Added new field PackHeader::overlap_overhead.

committer: mfx <mfx> 978190533 +0000
This commit is contained in:
Markus F.X.J. Oberhumer 2000-12-30 15:35:33 +00:00
parent 85bebf0b43
commit a8177201ef
21 changed files with 139 additions and 114 deletions

View File

@ -93,7 +93,7 @@ bool PackCom::canPack()
void PackCom::patchLoader(OutputFile *fo,
upx_byte *loader, int lsize,
unsigned calls, unsigned overlapoh)
unsigned calls)
{
const int filter_id = ph.filter;
const int e_len = getLoaderSectionStart("COMCUTPO");
@ -101,7 +101,7 @@ void PackCom::patchLoader(OutputFile *fo,
assert(e_len > 0 && e_len < 256);
assert(d_len > 0 && d_len < 256);
const unsigned upper_end = ph.u_len + overlapoh + d_len + 0x100;
const unsigned upper_end = ph.u_len + ph.overlap_overhead + d_len + 0x100;
if (upper_end + STACKSIZE > 0xfffe)
throwNotCompressible();
@ -195,9 +195,6 @@ void PackCom::pack(OutputFile *fo)
// prepare filter
Filter ft(opt->level);
ft.addvalue = getCallTrickOffset();
// prepare other settings
const unsigned overlap_range = ph.u_len < 0xFE00 - ft.addvalue ? 32 : 0;
unsigned overlapoh;
int strategy = -1; // try the first working filter
if (opt->filter >= 0 && isValidFilter(opt->filter))
@ -209,17 +206,18 @@ void PackCom::pack(OutputFile *fo)
else if (opt->level == 9)
// choose best from the first 4 filters
strategy = 4;
compressWithFilters(&ft, &overlapoh, overlap_range, strategy);
const unsigned overlap_range = ph.u_len < 0xFE00 - ft.addvalue ? 32 : 0;
compressWithFilters(&ft, overlap_range, strategy);
const int lsize = getLoaderSize();
MemBuffer loader(lsize);
memcpy(loader,getLoader(),lsize);
const unsigned calls = ft.id % 3 ? ft.lastcall - 2 * ft.calls : ft.calls;
patchLoader(fo, loader, lsize, calls, overlapoh);
patchLoader(fo, loader, lsize, calls);
// verify
verifyOverlappingDecompression(&obuf, overlapoh);
verifyOverlappingDecompression(&obuf, ph.overlap_overhead);
// finally check the compression ratio
if (!checkFinalCompressionRatio(fo))

View File

@ -56,7 +56,7 @@ protected:
protected:
virtual int buildLoader(const Filter *ft);
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned, unsigned);
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
virtual void addFilter16(int filter_id);
};

View File

@ -67,6 +67,16 @@ const int *PackDjgpp2::getFilters() const
}
unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
unsigned range,
unsigned upper_limit) const
{
unsigned o = super::findOverlapOverhead(buf, range, upper_limit);
o = (o + 0x3ff) &~ 0x1ff;
return o;
}
int PackDjgpp2::buildLoader(const Filter *ft)
{
// prepare loader
@ -158,7 +168,7 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo)
}
bool PackDjgpp2::readFileHeader()
int PackDjgpp2::readFileHeader()
{
unsigned char hdr[0x1c];
unsigned char magic[8];
@ -173,7 +183,7 @@ bool PackDjgpp2::readFileHeader()
fi->seek(512,SEEK_SET);
fi->readx(magic,8);
if (memcmp("go32stub",magic,8) != 0)
return false; // not V2 image
return 0; // not V2 image
fi->seek(coff_offset,SEEK_SET);
if (fi->read(&coff_hdr,sizeof(coff_hdr)) != sizeof(coff_hdr))
throwCantPack("skipping djgpp symlink");
@ -184,17 +194,17 @@ bool PackDjgpp2::readFileHeader()
fi->readx(&coff_hdr,0xa8);
}
if (coff_hdr.f_magic != 0x014c) // I386MAGIC
return false;
return 0;
if ((coff_hdr.f_flags & 2) == 0) // F_EXEC - COFF executable
return false;
return 0;
if (coff_hdr.a_magic != 0413) // ZMAGIC - demand load format
return false;
return 0;
// FIXME: check for Linux etc.
text = coff_hdr.sh;
data = text + 1;
bss = data + 1;
return true;
return UPX_F_DJGPP2_COFF;
}
@ -278,10 +288,9 @@ void PackDjgpp2::pack(OutputFile *fo)
ph.u_len = usize;
if (!compress(ibuf,obuf))
throwNotCompressible();
buildLoader(&ft);
unsigned overlapoh = findOverlapOverhead(obuf,ibuf,512);
overlapoh = (overlapoh + 0x3ff) & ~0x1ff;
ph.overlap_overhead = findOverlapOverhead(obuf,ibuf,512);
buildLoader(&ft);
// verify filter
ft.verifyUnfilter();
@ -295,9 +304,6 @@ void PackDjgpp2::pack(OutputFile *fo)
Filter ft(opt->level);
ft.buf_len = usize - data->size;
ft.addvalue = text->vaddr & ~0x1ff;
// prepare other settings
const unsigned overlap_range = 512;
unsigned overlapoh;
int strategy = -1; // try the first working filter
if (opt->filter >= 0 && isValidFilter(opt->filter))
@ -306,8 +312,7 @@ void PackDjgpp2::pack(OutputFile *fo)
else if (opt->all_filters)
// choose best from all available filters
strategy = 0;
compressWithFilters(&ft, &overlapoh, overlap_range, strategy);
overlapoh = (overlapoh + 0x3ff) & ~0x1ff;
compressWithFilters(&ft, 512, strategy);
#endif
// patch coff header #2
@ -315,12 +320,12 @@ void PackDjgpp2::pack(OutputFile *fo)
text->size = lsize; // new size of .text
data->size = ph.c_len; // new size of .data
if (bss->size < overlapoh) // give it a .bss
bss->size = overlapoh;
if (bss->size < ph.overlap_overhead) // give it a .bss
bss->size = ph.overlap_overhead;
text->scnptr = sizeof(coff_hdr);
data->scnptr = text->scnptr + text->size;
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + overlapoh - 0x200;
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
coff_hdr.f_nscns = 3;
// prepare loader
@ -331,7 +336,7 @@ void PackDjgpp2::pack(OutputFile *fo)
patchPackHeader(loader,lsize);
patch_le32(loader,lsize,"ENTR",coff_hdr.a_entry);
patchFilter32(loader, lsize, &ft);
patch_le32(loader,lsize,"BSSL",overlapoh/4);
patch_le32(loader,lsize,"BSSL",ph.overlap_overhead/4);
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
patch_le32(loader,lsize,"OUTP",text->vaddr &~ 0x1ff);
patch_le32(loader,lsize,"INPP",data->vaddr);
@ -339,8 +344,8 @@ void PackDjgpp2::pack(OutputFile *fo)
// patch coff header #3
text->vaddr = sizeof(coff_hdr);
coff_hdr.a_entry = sizeof(coff_hdr) + getLoaderSection("DJ2MAIN1");
bss->vaddr += overlapoh;
bss->size -= overlapoh;
bss->vaddr += ph.overlap_overhead;
bss->size -= ph.overlap_overhead;
// because of a feature (bug?) in stub.asm we need some padding
memcpy(obuf+data->size,"UPX",3);
@ -357,7 +362,7 @@ void PackDjgpp2::pack(OutputFile *fo)
#endif
// verify
verifyOverlappingDecompression(&obuf, overlapoh);
verifyOverlappingDecompression(&obuf, ph.overlap_overhead);
// handle overlay
// FIXME: only Allegro pakfiles are supported

View File

@ -53,9 +53,13 @@ public:
virtual int canUnpack();
protected:
virtual int buildLoader(const Filter *ft);
virtual void handleStub(OutputFile *fo);
virtual bool readFileHeader();
virtual int readFileHeader();
virtual unsigned findOverlapOverhead(const upx_bytep buf,
unsigned range = 0,
unsigned upper_limit = ~0u) const;
virtual int buildLoader(const Filter *ft);
long coff_offset;

View File

@ -116,9 +116,6 @@ void PackElks8086::pack(OutputFile *fo)
Filter ft(opt->level);
ft.buf_len = ph.u_len;
ft.addvalue = kernel_entry;
// prepare other settings
const unsigned overlap_range = 1 << 20;
unsigned overlapoh;
int strategy = -1; // try the first working filter
if (opt->filter >= 0 && isValidFilter(opt->filter))
@ -127,7 +124,7 @@ void PackElks8086::pack(OutputFile *fo)
else if (opt->all_filters)
// choose best from all available filters
strategy = 0;
compressWithFilters(&ft, &overlapoh, overlap_range, strategy);
compressWithFilters(&ft, overlap_range, strategy);
const unsigned lsize = getLoaderSize();
MemBuffer loader(lsize);

View File

@ -65,7 +65,7 @@ bool PackSys::canPack()
void PackSys::patchLoader(OutputFile *fo,
upx_byte *loader, int lsize,
unsigned calls, unsigned overlapoh)
unsigned calls)
{
const int filter_id = ph.filter;
const int e_len = getLoaderSectionStart("SYSCUTPO");
@ -73,13 +73,13 @@ void PackSys::patchLoader(OutputFile *fo,
assert(e_len > 0 && e_len < 256);
assert(d_len > 0 && d_len < 256);
if (ph.u_len + d_len + overlapoh > 0xfffe)
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
throwNotCompressible();
memcpy(loader,ibuf,6); // copy from orig. header
memcpy(loader+8,ibuf+8,2); // opendos wants this word too
unsigned copy_to = ph.u_len + d_len + overlapoh;
unsigned copy_to = ph.u_len + d_len + ph.overlap_overhead;
patch_le16(loader,lsize,"JO",get_le16(ibuf+6)-copy_to-1);
if (filter_id)
@ -90,7 +90,7 @@ void PackSys::patchLoader(OutputFile *fo,
patchPackHeader(loader,e_len);
const unsigned jmp_pos = find_le16(loader,e_len,get_le16("JM"));
patch_le16(loader,e_len,"JM",ph.u_len+overlapoh+2-jmp_pos-2);
patch_le16(loader,e_len,"JM",ph.u_len+ph.overlap_overhead+2-jmp_pos-2);
loader[getLoaderSection("SYSSUBSI") - 1] = (upx_byte) -e_len;
patch_le16(loader,e_len,"DI",copy_to);
patch_le16(loader,e_len,"SI",ph.c_len+e_len+d_len-1);

View File

@ -50,7 +50,7 @@ protected:
protected:
virtual int buildLoader(const Filter *ft);
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned, unsigned);
virtual void patchLoader(OutputFile *fo, upx_byte *, int, unsigned);
};

View File

@ -65,6 +65,17 @@ const int *PackTmt::getFilters() const
}
unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
unsigned range,
unsigned upper_limit) const
{
// make sure the decompressor will be paragraph aligned
unsigned o = super::findOverlapOverhead(buf, range, upper_limit);
o = ((o + 0x20) &~ 0xf) - (ph.u_len & 0xf);
return o;
}
int PackTmt::buildLoader(const Filter *ft)
{
// prepare loader
@ -95,7 +106,7 @@ int PackTmt::buildLoader(const Filter *ft)
// util
**************************************************************************/
bool PackTmt::readFileHeader()
int PackTmt::readFileHeader()
{
#define H(x) get_le16(h,2*(x))
#define H4(x) get_le32(h,x)
@ -143,14 +154,16 @@ bool PackTmt::readFileHeader()
else if (memcmp(h,"Adam",4) == 0)
break;
else
return false;
return 0;
}
if (ic == 20)
return false;
return 0;
fi->seek(adam_offset,SEEK_SET);
fi->readx(&ih,sizeof(ih));
// FIXME: should add some checks for the values in `ih'
return true;
return UPX_F_TMT_ADAM;
#undef H4
#undef H
}
@ -218,9 +231,9 @@ void PackTmt::pack(OutputFile *fo)
ph.u_len = usize + relocsize;
if (!compress(ibuf,obuf))
throwNotCompressible();
buildLoader(&ft);
unsigned overlapoh = findOverlapOverhead(obuf,512);
ph.overlap_overhead = findOverlapOverhead(obuf,512);
buildLoader(&ft);
// verify filter
ft.verifyUnfilter();
@ -233,9 +246,6 @@ void PackTmt::pack(OutputFile *fo)
// prepare filter
Filter ft(opt->level);
ft.buf_len = usize;
// prepare other settings
const unsigned overlap_range = 512;
unsigned overlapoh;
int strategy = -1; // try the first working filter
if (opt->filter >= 0 && isValidFilter(opt->filter))
@ -244,12 +254,9 @@ void PackTmt::pack(OutputFile *fo)
else if (opt->all_filters)
// choose best from all available filters
strategy = 0;
compressWithFilters(&ft, &overlapoh, overlap_range, strategy);
compressWithFilters(&ft, 512, strategy);
#endif
// make sure the decompressor will be paragraph aligned
overlapoh = ((overlapoh + 0x20) &~ 0xf) - (ph.u_len & 0xf);
const unsigned lsize = getLoaderSize();
MemBuffer loader(lsize);
memcpy(loader,getLoader(),lsize);
@ -260,18 +267,18 @@ void PackTmt::pack(OutputFile *fo)
assert(e_len > 0 && s_point > 0);
// patch loader
patch_le32(loader,lsize,"JMPO",ih.entry-(ph.u_len+overlapoh+d_len));
patch_le32(loader,lsize,"JMPO",ih.entry-(ph.u_len+ph.overlap_overhead+d_len));
patchFilter32(loader, lsize, &ft);
patchPackHeader(loader,e_len);
const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD"));
patch_le32(loader,e_len,"JMPD",ph.u_len+overlapoh-jmp_pos-4);
patch_le32(loader,e_len,"JMPD",ph.u_len+ph.overlap_overhead-jmp_pos-4);
patch_le32(loader,e_len,"ECX0",ph.c_len+d_len);
patch_le32(loader,e_len,"EDI0",ph.u_len+overlapoh+d_len-1);
patch_le32(loader,e_len,"EDI0",ph.u_len+ph.overlap_overhead+d_len-1);
patch_le32(loader,e_len,"ESI0",ph.c_len+e_len+d_len-1);
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x clen=%x \n\n",
// e_len,d_len,copy_len,copy_to,overlapoh,jmp_pos,ph.u_len,ph.c_len);
// e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len);
memcpy(&oh,&ih,sizeof(oh));
oh.imagesize = ph.c_len+e_len+d_len; // new size
@ -288,7 +295,7 @@ void PackTmt::pack(OutputFile *fo)
fo->write(rel_entry,sizeof (rel_entry));
// verify
verifyOverlappingDecompression(&obuf, overlapoh);
verifyOverlappingDecompression(&obuf, ph.overlap_overhead);
// copy the overlay
copyOverlay(fo, overlay, &obuf);

View File

@ -52,8 +52,12 @@ public:
virtual int canUnpack();
protected:
virtual int readFileHeader();
virtual unsigned findOverlapOverhead(const upx_bytep buf,
unsigned range = 0,
unsigned upper_limit = ~0u) const;
virtual int buildLoader(const Filter *ft);
virtual bool readFileHeader();
unsigned adam_offset;
int big_relocs;

View File

@ -132,15 +132,15 @@ int PackTos::getLoaderSize() const
// util
**************************************************************************/
bool PackTos::readFileHeader()
int PackTos::readFileHeader()
{
fi->seek(0,SEEK_SET);
fi->readx(&ih, FH_SIZE);
if (ih.fh_magic != 0x601a)
return false;
return 0;
if (FH_SIZE + ih.fh_text + ih.fh_data + ih.fh_sym > (unsigned) file_size)
return false;
return true;
return 0;
return UPX_F_ATARI_TOS;
}
@ -412,8 +412,8 @@ void PackTos::pack(OutputFile *fo)
throwNotCompressible();
// The decompressed data will now get placed at this offset:
const unsigned overlapoh = findOverlapOverhead(obuf, 512);
unsigned offset = (ph.u_len + overlapoh) - ph.c_len;
ph.overlap_overhead = findOverlapOverhead(obuf, 512);
unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len;
// compute addresses
unsigned o_text, o_data, o_bss;
@ -538,7 +538,7 @@ void PackTos::pack(OutputFile *fo)
fo->write("\x00\x00\x00\x00",4);
// verify
verifyOverlappingDecompression(&obuf, overlapoh);
verifyOverlappingDecompression(&obuf, ph.overlap_overhead);
// copy the overlay
copyOverlay(fo, overlay, &obuf);

View File

@ -57,7 +57,7 @@ protected:
virtual const upx_byte *getLoader() const;
virtual int getLoaderSize() const;
virtual bool readFileHeader();
virtual int readFileHeader();
virtual bool checkFileHeader();
struct tos_header_t

View File

@ -220,9 +220,6 @@ void PackVmlinuzI386::pack(OutputFile *fo)
Filter ft(opt->level);
ft.buf_len = ph.u_len;
ft.addvalue = kernel_entry;
// prepare other settings
const unsigned overlap_range = 1 << 20;
unsigned overlapoh;
int strategy = -1; // try the first working filter
if (opt->filter >= 0 && isValidFilter(opt->filter))
@ -231,7 +228,7 @@ void PackVmlinuzI386::pack(OutputFile *fo)
else if (opt->all_filters)
// choose best from all available filters
strategy = 0;
compressWithFilters(&ft, &overlapoh, overlap_range, strategy);
compressWithFilters(&ft, 1 << 20, strategy);
const unsigned lsize = getLoaderSize();
MemBuffer loader(lsize);
@ -297,9 +294,6 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
Filter ft(opt->level);
ft.buf_len = ph.u_len;
ft.addvalue = kernel_entry;
// prepare other settings
const unsigned overlap_range = 512;
unsigned overlapoh;
int strategy = -1; // try the first working filter
if (opt->filter >= 0 && isValidFilter(opt->filter))
@ -308,7 +302,7 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
else if (opt->all_filters)
// choose best from all available filters
strategy = 0;
compressWithFilters(&ft, &overlapoh, overlap_range, strategy);
compressWithFilters(&ft, 512, strategy);
// align everything to dword boundary - it is easier to handle
unsigned clen = ph.c_len;
@ -326,7 +320,7 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
assert(e_len > 0);
const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4);
const unsigned decompr_pos = ALIGN_UP(ph.u_len + overlapoh, 16);
const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16);
const unsigned copy_size = clen + d_len4;
const unsigned edi = decompr_pos + d_len4 - 4; // copy to
const unsigned esi = ALIGN_UP(clen + lsize, 4) - 4; // copy from
@ -357,7 +351,7 @@ void PackBvmlinuzI386::pack(OutputFile *fo)
#endif
// verify
verifyOverlappingDecompression(&obuf, overlapoh);
verifyOverlappingDecompression(&obuf, ph.overlap_overhead);
// finally check the compression ratio
if (!checkFinalCompressionRatio(fo))

View File

@ -78,11 +78,12 @@ int PackW16Ne::buildLoader(const Filter *ft)
//
**************************************************************************/
bool PackW16Ne::readFileHeader()
int PackW16Ne::readFileHeader()
{
// FIXME: identify a win16/ne executable, so that the call
// for contribution below will get thrown
return false;
return 0;
//return UPX_F_WIN16_NE;
}

View File

@ -52,7 +52,8 @@ public:
virtual int canUnpack();
protected:
virtual bool readFileHeader(void);
virtual int readFileHeader(void);
virtual int buildLoader(const Filter *ft);
};

View File

@ -130,7 +130,7 @@ bool PackW32Pe::testUnpackVersion(int version) const
// util
**************************************************************************/
bool PackW32Pe::readFileHeader()
int PackW32Pe::readFileHeader()
{
struct h_t
{
@ -161,16 +161,16 @@ bool PackW32Pe::readFileHeader()
else if (get_le32(&h) == 'P' + 'E'*256)
break;
else
return false;
return 0;
}
if (ic == 20)
return false;
return 0;
fi->seek(pe_offset,SEEK_SET);
fi->readx(&ih,sizeof(ih));
fi->seek(0x200,SEEK_SET);
fi->readx(&h,6);
isrtm = memcmp(&h,"32STUB",6) == 0;
return true;
return UPX_F_WIN32_PE;
}
@ -1625,9 +1625,9 @@ void PackW32Pe::pack(OutputFile *fo)
ph.filter_cto = ft.cto;
if (!compress(ibuf + rvamin,obuf))
throwNotCompressible();
buildLoader(&ft);
const unsigned overlapoh = findOverlapOverhead(obuf, 2048);
ph.overlap_overhead = findOverlapOverhead(obuf, 2048);
buildLoader(&ft);
// verify filter
ft.verifyUnfilter();
@ -1640,9 +1640,6 @@ void PackW32Pe::pack(OutputFile *fo)
Filter ft(opt->level);
ft.buf_len = ih.codesize;
ft.addvalue = 0;
// prepare other settings
const unsigned overlap_range = 2048;
unsigned overlapoh;
int strategy = -1; // try the first working filter
if (!allow_filter)
@ -1654,11 +1651,11 @@ void PackW32Pe::pack(OutputFile *fo)
else if (opt->all_filters)
// choose best from all available filters
strategy = 0;
compressWithFilters(&ft, &overlapoh, overlap_range, strategy,
compressWithFilters(&ft, 2048, strategy,
NULL, 0, 0, ih.codebase, rvamin);
#endif
newvsize = (ph.u_len + rvamin + overlapoh + oam1) &~ oam1;
newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;
if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)
tlsindex = 0;

View File

@ -64,8 +64,9 @@ public:
{ return (version == 12); }
protected:
virtual bool readFileHeader();
virtual int readFileHeader();
virtual bool testUnpackVersion(int version) const;
virtual int buildLoader(const Filter *ft);
unsigned pe_offset;

View File

@ -208,7 +208,7 @@ void PackWcle::encodeObjectTable()
if (ic < jc)
ic = jc;
unsigned csection = (ic + overlapoh + mps-1) &~ (mps-1);
unsigned csection = (ic + ph.overlap_overhead + mps-1) &~ (mps-1);
OOT(0,virtual_size) = csection + mps;
OOT(0,flags) = LEOF_READ|LEOF_EXEC|LEOF_HUGE32|LEOF_PRELOAD;
@ -421,9 +421,9 @@ void PackWcle::encodeImage(const Filter *ft)
// reserve RESERVED bytes for the decompressor
if (!compress(ibuf,oimage+RESERVED))
throwNotCompressible();
ph.overlap_overhead = findOverlapOverhead(oimage+RESERVED, 512);
buildLoader(ft);
overlapoh = findOverlapOverhead(oimage+RESERVED, 512);
ibuf.free();
soimage = (ph.c_len + 3) &~ 3;
}
@ -516,7 +516,7 @@ void PackWcle::pack(OutputFile *fo)
// patch loader
ic = (OOT(0,virtual_size) - d_len) &~ 15;
assert(ic > ((ph.u_len + overlapoh + 31) &~ 15));
assert(ic > ((ph.u_len + ph.overlap_overhead + 31) &~ 15));
upx_byte * const p = oimage + soimage - d_len;
patch_le32(p,d_len,"JMPO",ih.init_eip_offset+text_vaddr-(ic+d_len));

View File

@ -52,9 +52,10 @@ public:
virtual int canUnpack();
protected:
virtual int buildLoader(const Filter *ft);
virtual void handleStub(OutputFile *fo);
virtual int buildLoader(const Filter *ft);
virtual void readObjectTable();
virtual void encodeObjectTable();
virtual void decodeObjectTable();
@ -81,7 +82,6 @@ protected:
int big_relocs;
bool has_extra_code;
unsigned overlapoh;
unsigned neweip;
};

View File

@ -1088,7 +1088,7 @@ void Packer::addFilter32(int filter_id)
// It will replace the tryFilters() / compress() call sequence.
**************************************************************************/
void Packer::compressWithFilters(Filter *parm_ft, unsigned *parm_overlapoh,
void Packer::compressWithFilters(Filter *parm_ft,
const unsigned overlap_range,
int strategy, const int *parm_filters,
unsigned max_offset, unsigned max_match,
@ -1106,8 +1106,8 @@ void Packer::compressWithFilters(Filter *parm_ft, unsigned *parm_overlapoh,
const unsigned filter_len = orig_ft.buf_len ? orig_ft.buf_len : compress_buf_len;
//
best_ph.c_len = orig_ph.u_len;
best_ph.overlap_overhead = 0;
unsigned best_ph_lsize = 0;
unsigned best_overlapoh = 0;
// preconditions
assert(orig_ph.filter == 0);
@ -1209,14 +1209,27 @@ void Packer::compressWithFilters(Filter *parm_ft, unsigned *parm_overlapoh,
// compress
if (compress(ibuf + compress_buf_off, otemp, max_offset, max_match))
{
// get results
const unsigned lsize = buildLoader(&ft);
unsigned lsize = 0;
if (ph.c_len + lsize < best_ph.c_len + best_ph_lsize)
{
// get results
ph.overlap_overhead = findOverlapOverhead(otemp, overlap_range);
lsize = buildLoader(&ft);
}
#if 0
printf("\n%02x: %d + %d = %d (best: %d + %d = %d)\n", ft.id,
ph.c_len, getLoaderSize(), ph.c_len + getLoaderSize(),
best_ph.c_len, best_ph_lsize, best_ph.c_len + best_ph_lsize);
#endif
bool update = false;
if (ph.c_len + lsize < best_ph.c_len + best_ph_lsize)
update = true;
else if (ph.c_len + lsize == best_ph.c_len + best_ph_lsize)
{
if (ph.overlap_overhead < best_ph.overlap_overhead)
update = true;
}
if (update)
{
// update obuf[] with best version
if (otemp != obuf)
@ -1225,7 +1238,6 @@ void Packer::compressWithFilters(Filter *parm_ft, unsigned *parm_overlapoh,
best_ph = ph;
best_ph_lsize = lsize;
best_ft = ft;
best_overlapoh = findOverlapOverhead(obuf, overlap_range);
}
}
// restore ibuf[] - unfilter with verify
@ -1240,11 +1252,11 @@ void Packer::compressWithFilters(Filter *parm_ft, unsigned *parm_overlapoh,
assert(best_ph.u_len == orig_ph.u_len);
assert(best_ph.filter == best_ft.id);
assert(best_ph.filter_cto == best_ft.cto);
assert(best_ph.overlap_overhead > 0);
// copy back results
this->ph = best_ph;
*parm_ft = best_ft;
*parm_overlapoh = best_overlapoh;
// finally check compression ratio
if (best_ph.c_len + best_ph_lsize >= best_ph.u_len)

View File

@ -87,6 +87,9 @@ public:
unsigned max_run_found;
unsigned first_offset_found;
//unsigned same_match_offsets_found;
// info fields set by Packer::compressWithFilters()
unsigned overlap_overhead;
};
@ -158,24 +161,25 @@ protected:
virtual bool checkFinalCompressionRatio(const OutputFile *fo) const;
// high-level compression drivers
void compressWithFilters(Filter *ft, unsigned *overlapoh,
void compressWithFilters(Filter *ft,
const unsigned overlap_range,
int strategy = -1, const int *filters = NULL,
int strategy,
const int *filters = NULL,
unsigned max_offset = 0, unsigned max_match = 0,
unsigned filter_buf_off = 0,
unsigned compress_buf_off = 0);
// util for verifying overlapping decompresion
// non-destructive test
bool testOverlappingDecompression(const upx_bytep buf,
unsigned overlap_overhead) const;
virtual bool testOverlappingDecompression(const upx_bytep buf,
unsigned overlap_overhead) const;
// non-destructive find
unsigned findOverlapOverhead(const upx_bytep buf,
unsigned range = 0,
unsigned upper_limit = ~0u) const;
virtual unsigned findOverlapOverhead(const upx_bytep buf,
unsigned range = 0,
unsigned upper_limit = ~0u) const;
// destructive decompress + verify
void verifyOverlappingDecompression(MemBuffer *buf,
unsigned overlap_overhead);
virtual void verifyOverlappingDecompression(MemBuffer *buf,
unsigned overlap_overhead);
// packheader handling

View File

@ -38,7 +38,7 @@
**************************************************************************/
PackHeader::PackHeader() :
version(-1), format(-1)
version(-1), format(-1), filter(0), filter_cto(0), overlap_overhead(0)
{
}