diff --git a/src/p_com.cpp b/src/p_com.cpp index 6bd46db9..ce294c02 100644 --- a/src/p_com.cpp +++ b/src/p_com.cpp @@ -221,6 +221,10 @@ void PackCom::pack(OutputFile *fo) // verify verifyOverlappingDecompression(&obuf, overlapoh); + + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) + throwNotCompressible(); } diff --git a/src/p_djgpp2.cpp b/src/p_djgpp2.cpp index 14435d67..deb08316 100644 --- a/src/p_djgpp2.cpp +++ b/src/p_djgpp2.cpp @@ -368,6 +368,10 @@ void PackDjgpp2::pack(OutputFile *fo) // handle overlay // FIXME: only Allegro pakfiles are supported handle_allegropak(fi,fo); + + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) + throwNotCompressible(); } diff --git a/src/p_exe.cpp b/src/p_exe.cpp index f5c62732..10c785c3 100644 --- a/src/p_exe.cpp +++ b/src/p_exe.cpp @@ -516,6 +516,10 @@ void PackExe::pack(OutputFile *fo) // copy the overlay copyOverlay(fo, overlay, &obuf); //fprintf (stderr,"%x %x\n",relocsize,ph.u_len); + + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) + throwNotCompressible(); } diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index dfac13ca..88685443 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -360,8 +360,8 @@ void PackLinuxI386elf::pack(OutputFile *fo) updateLoader(fo); - // finally check compression ratio - if (!super::checkCompressionRatio(ph.u_len, fo->getBytesWritten())) + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); } diff --git a/src/p_tmt.cpp b/src/p_tmt.cpp index 6601106d..b3de260f 100644 --- a/src/p_tmt.cpp +++ b/src/p_tmt.cpp @@ -263,6 +263,10 @@ void PackTmt::pack(OutputFile *fo) // copy the overlay copyOverlay(fo, overlay, &obuf); + + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) + throwNotCompressible(); } diff --git a/src/p_tos.cpp b/src/p_tos.cpp index 8445d752..be15fd2a 100644 --- a/src/p_tos.cpp +++ b/src/p_tos.cpp @@ -542,6 +542,10 @@ void PackTos::pack(OutputFile *fo) // copy the overlay copyOverlay(fo, overlay, &obuf); + + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) + throwNotCompressible(); } diff --git a/src/p_unix.cpp b/src/p_unix.cpp index 5d800f97..afe02a53 100644 --- a/src/p_unix.cpp +++ b/src/p_unix.cpp @@ -196,8 +196,8 @@ void PackUnix::pack(OutputFile *fo) updateLoader(fo); - // finally check compression ratio - if (!Packer::checkCompressionRatio(ph.u_len, fo->getBytesWritten())) + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); } diff --git a/src/p_vmlinz.cpp b/src/p_vmlinz.cpp index f9a75d6a..fa84e020 100644 --- a/src/p_vmlinz.cpp +++ b/src/p_vmlinz.cpp @@ -71,11 +71,17 @@ const int *PackVmlinuzI386::getFilters() const } +bool PackVmlinuzI386::canPack() +{ + return readFileHeader() == getFormat(); +} + + /************************************************************************* -// common routines +// common util routines **************************************************************************/ -int PackVmlinuzI386::readHeader() +int PackVmlinuzI386::readFileHeader() { boot_sect_t h; @@ -95,7 +101,7 @@ int PackVmlinuzI386::readHeader() } -// read kernel into obuf, gzip-uncompress into ibuf, +// read full kernel into obuf, gzip-uncompress into ibuf, // return uncompressed size int PackVmlinuzI386::uncompressKernel() { @@ -147,8 +153,9 @@ void PackVmlinuzI386::readKernel() if (klen <= 0) throwCantPack("kernel decompression failed"); - // OutputFile::dump("kernel.img", ibuf, ulen); + //OutputFile::dump("kernel.img", ibuf, klen); + // copy the setup boot code setup_buf.alloc(setup_size); memcpy(setup_buf, obuf, setup_size); @@ -163,12 +170,6 @@ void PackVmlinuzI386::readKernel() // vmlinuz specific **************************************************************************/ -bool PackVmlinuzI386::canPack() -{ - return readHeader() == UPX_F_VMLINUZ_i386; -} - - void PackVmlinuzI386::pack(OutputFile *fo) { readKernel(); @@ -203,9 +204,15 @@ void PackVmlinuzI386::pack(OutputFile *fo) fo->write(setup_buf, setup_buf.getSize()); fo->write(loader, lsize); fo->write(obuf, clen); +#if 0 + printf("%-13s: setup : %8ld bytes\n", getName(), (long) setup_buf.getSize()); + printf("%-13s: loader : %8ld bytes\n", getName(), (long) lsize); + printf("%-13s: compressed : %8ld bytes\n", getName(), (long) clen); +#endif - //if (!checkCompressionRatio(file_size, fo->getBytesWritten())) - // throwNotCompressible(); + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) + throwNotCompressible(); } @@ -213,12 +220,6 @@ void PackVmlinuzI386::pack(OutputFile *fo) // bvmlinuz specific **************************************************************************/ -bool PackBvmlinuzI386::canPack() -{ - return readHeader() == UPX_F_BVMLINUZ_i386; -} - - void PackBvmlinuzI386::pack(OutputFile *fo) { readKernel(); @@ -277,12 +278,19 @@ void PackBvmlinuzI386::pack(OutputFile *fo) fo->write(loader, e_len); fo->write(obuf, clen); fo->write(loader + e_len, lsize - e_len); +#if 0 + printf("%-13s: setup : %8ld bytes\n", getName(), (long) setup_buf.getSize()); + printf("%-13s: entry : %8ld bytes\n", getName(), (long) e_len); + printf("%-13s: compressed : %8ld bytes\n", getName(), (long) clen); + printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) (lsize - e_len)); +#endif // verify verifyOverlappingDecompression(&obuf, overlapoh); - //if (!checkCompressionRatio(file_size, fo->getBytesWritten())) - // throwNotCompressible(); + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) + throwNotCompressible(); } @@ -295,6 +303,7 @@ int PackVmlinuzI386::canUnpack() return false; } + void PackVmlinuzI386::unpack(OutputFile *) { // no uncompression support for this format, so that diff --git a/src/p_vmlinz.h b/src/p_vmlinz.h index 303c0664..49082ae7 100644 --- a/src/p_vmlinz.h +++ b/src/p_vmlinz.h @@ -52,7 +52,7 @@ public: virtual int canUnpack(); protected: - virtual int readHeader(); + virtual int readFileHeader(); virtual int uncompressKernel(); virtual void readKernel(); @@ -98,8 +98,6 @@ public: virtual const char *getName() const { return "bvmlinuz/386"; } virtual void pack(OutputFile *fo); - - virtual bool canPack(); }; diff --git a/src/p_w32pe.cpp b/src/p_w32pe.cpp index d0d03e43..876ca776 100644 --- a/src/p_w32pe.cpp +++ b/src/p_w32pe.cpp @@ -1902,8 +1902,8 @@ void PackW32Pe::pack(OutputFile *fo) // copy the overlay copyOverlay(fo, overlay, &obuf); - // finally check compresion ratio - if (!checkCompressionRatio(file_size, fo->getBytesWritten())) + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); } diff --git a/src/p_wcle.cpp b/src/p_wcle.cpp index 4ca9ab4d..a7ec8949 100644 --- a/src/p_wcle.cpp +++ b/src/p_wcle.cpp @@ -544,6 +544,10 @@ void PackWcle::pack(OutputFile *fo) const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length; checkOverlay(overlay); copyOverlay(fo, overlay, &oimage); + + // finally check the compression ratio + if (!checkFinalCompressionRatio(fo)) + throwNotCompressible(); } diff --git a/src/packer.cpp b/src/packer.cpp index 293a3860..12f2ab78 100644 --- a/src/packer.cpp +++ b/src/packer.cpp @@ -260,9 +260,9 @@ bool Packer::checkCompressionRatio(unsigned u_len, unsigned c_len) const //assert((off_t)u_len < file_size); #if 1 - if (c_len >= u_len - u_len / 8) // min. 12.5% gain + if (c_len + 512 >= u_len) // min. 512 bytes gain return false; - if (c_len + 512 >= u_len) // min. 512 bytes gain + if (c_len >= u_len - u_len / 8) // min. 12.5% gain return false; #else if (c_len >= u_len) @@ -272,6 +272,21 @@ bool Packer::checkCompressionRatio(unsigned u_len, unsigned c_len) const } +bool Packer::checkFinalCompressionRatio(const OutputFile *fo) const +{ + unsigned u_len = file_size; + unsigned c_len = fo->getBytesWritten(); + + assert((int)u_len > 0); + assert((int)c_len > 0); + + if (c_len + 4096 <= u_len) // ok if we have 4096 bytes gain + return true; + + return checkCompressionRatio(u_len, c_len); +} + + /************************************************************************* // **************************************************************************/ @@ -350,7 +365,7 @@ void Packer::verifyOverlappingDecompression(MemBuffer *buf, // buf was allocated with MemBuffer.allocForCompression(), and // its contents are no longer needed, i.e. the compressed data // must have been already written. - // We now could performa a real overlapping decompression and + // We now could perform a real overlapping decompression and // verify the checksum. // // Note: diff --git a/src/packer.h b/src/packer.h index 0a03e600..69f116e0 100644 --- a/src/packer.h +++ b/src/packer.h @@ -156,6 +156,7 @@ protected: virtual void decompress(const upx_bytep in, upx_bytep out, bool verify_checksum=true); virtual bool checkCompressionRatio(unsigned u_len, unsigned c_len) const; + virtual bool checkFinalCompressionRatio(const OutputFile *fo) const; // high-level compression drivers void compressWithFilters(Filter *ft, unsigned *overlapoh,