1
0
mirror of https://github.com/upx/upx synced 2025-09-28 19:06:07 +08:00

djgpp2/coff updates

committer: ml1050 <ml1050> 1043312061 +0000
This commit is contained in:
László Molnár 2003-01-23 08:54:21 +00:00
parent 32e76e88cf
commit 1282ed333a
3 changed files with 86 additions and 63 deletions

View File

@ -269,28 +269,25 @@ void PackDjgpp2::pack(OutputFile *fo)
// read file // read file
const unsigned size = text->size + data->size; const unsigned size = text->size + data->size;
const unsigned tpos = text->scnptr; const unsigned tpos = text->scnptr;
const unsigned usize = size + (tpos & 0x1ff); const unsigned hdrsize = 20 + 28 + sizeof(external_scnhdr_t) * coff_hdr.f_nscns;
const unsigned hdrsize = 20 + 28 + (40 * coff_hdr.f_nscns); const unsigned usize = size + hdrsize;
if (hdrsize < sizeof(coff_hdr) || hdrsize > tpos) if (hdrsize < sizeof(coff_hdr) || hdrsize > tpos)
throwCantPack("coff header error"); throwCantPack("coff header error");
if (hdrsize > (tpos & 0x1ff))
throwCantPack("unsupported coff header");
ibuf.alloc(usize); ibuf.alloc(usize);
obuf.allocForCompression(usize); obuf.allocForCompression(usize);
fi->seek(coff_offset, SEEK_SET); fi->seek(coff_offset, SEEK_SET);
fi->readx(ibuf, hdrsize); // orig. coff header fi->readx(ibuf, hdrsize); // orig. coff header
memset(ibuf + hdrsize, 0, tpos - hdrsize);
fi->seek(coff_offset + tpos, SEEK_SET); fi->seek(coff_offset + tpos, SEEK_SET);
fi->readx(ibuf + (tpos & 0x1ff),size); fi->readx(ibuf + hdrsize, size);
// prepare packheader // prepare packheader
ph.u_len = usize; ph.u_len = usize;
// prepare filter // prepare filter
Filter ft(ph.level); Filter ft(ph.level);
ft.buf_len = usize - data->size; ft.buf_len = usize - data->size;
ft.addvalue = text->vaddr & ~0x1ff; ft.addvalue = text->vaddr - hdrsize;
// compress // compress
compressWithFilters(&ft, 512); compressWithFilters(&ft, 512);
@ -317,9 +314,14 @@ void PackDjgpp2::pack(OutputFile *fo)
patchFilter32(loader, lsize, &ft); patchFilter32(loader, lsize, &ft);
patch_le32(loader, lsize, "BSSL", ph.overlap_overhead / 4); patch_le32(loader, lsize, "BSSL", ph.overlap_overhead / 4);
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff)); assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
patch_le32(loader,lsize,"OUTP",text->vaddr &~ 0x1ff); patch_le32(loader, lsize, "OUTP", text->vaddr - hdrsize);
patch_le32(loader, lsize, "INPP", data->vaddr); patch_le32(loader, lsize, "INPP", data->vaddr);
// we should not overwrite our decompressor during unpacking
// the original coff header (which is put just before the
// beginning of the original .text section)
assert(text->vaddr > hdrsize + lsize + sizeof(coff_hdr));
// patch coff header #3 // patch coff header #3
text->vaddr = sizeof(coff_hdr); text->vaddr = sizeof(coff_hdr);
coff_hdr.a_entry = sizeof(coff_hdr) + getLoaderSection("DJ2MAIN1"); coff_hdr.a_entry = sizeof(coff_hdr) + getLoaderSection("DJ2MAIN1");
@ -385,13 +387,22 @@ void PackDjgpp2::unpack(OutputFile *fo)
// decompress // decompress
decompress(ibuf, obuf); decompress(ibuf, obuf);
coff_header_t *chdr = (coff_header_t*) (unsigned char *) obuf;
text = chdr->sh;
data = text + 1;
const unsigned hdrsize = 20 + 28
+ sizeof(external_scnhdr_t) * chdr->f_nscns;
unsigned addvalue = text->vaddr &~ 0x1ff; // for old versions
if (ph.version >= 14)
addvalue = text->vaddr - hdrsize;
// unfilter // unfilter
if (ph.filter) if (ph.filter)
{ {
memcpy(&coff_hdr,obuf,sizeof(coff_hdr));
Filter ft(ph.level); Filter ft(ph.level);
ft.init(ph.filter, text->vaddr &~ 0x1ff); ft.init(ph.filter, addvalue);
ft.cto = (unsigned char) ph.filter_cto; ft.cto = (unsigned char) ph.filter_cto;
if (ph.version < 11) if (ph.version < 11)
{ {
@ -402,18 +413,31 @@ void PackDjgpp2::unpack(OutputFile *fo)
ft.unfilter(obuf, ph.u_len - data->size); ft.unfilter(obuf, ph.u_len - data->size);
} }
if (ph.version < 14)
{
// fixup for the aligning bug in strip 2.8+ // fixup for the aligning bug in strip 2.8+
text = ((coff_header_t*) (unsigned char *) obuf)->sh;
data = text + 1;
text->scnptr &= 0x1ff; text->scnptr &= 0x1ff;
data->scnptr = text->scnptr + text->size; data->scnptr = text->scnptr + text->size;
// write decompressed file // write decompressed file
if (fo) if (fo)
{
fo->write(obuf, ph.u_len); fo->write(obuf, ph.u_len);
handle_allegropak(fi,fo);
} }
else if (fo)
{
// write the header
// some padding might be required between the end
// of the header and the start of the .text section
const unsigned padding = text->scnptr - hdrsize;
memset(ibuf, 0, padding);
fo->write(obuf, hdrsize);
fo->write(ibuf, padding);
fo->write(obuf + hdrsize, ph.u_len - hdrsize);
}
if (fo)
handle_allegropak(fi, fo);
} }

View File

@ -40,7 +40,7 @@ class PackDjgpp2 : public Packer
public: public:
PackDjgpp2(InputFile *f); PackDjgpp2(InputFile *f);
virtual int getVersion() const { return 13; } virtual int getVersion() const { return 14; }
virtual int getFormat() const { return UPX_F_DJGPP2_COFF; } virtual int getFormat() const { return UPX_F_DJGPP2_COFF; }
virtual const char *getName() const { return "djgpp2/coff"; } virtual const char *getName() const { return "djgpp2/coff"; }
virtual const int *getCompressionMethods(int method, int level) const; virtual const int *getCompressionMethods(int method, int level) const;

View File

@ -251,8 +251,7 @@ static void assertPacker(const Packer *p)
assert(p->getFormat() > 0); assert(p->getFormat() > 0);
assert(p->getFormat() <= 255); assert(p->getFormat() <= 255);
assert(p->getVersion() >= 11); assert(p->getVersion() >= 11);
assert(p->getVersion() < 255); assert(p->getVersion() <= 14);
assert(p->getVersion() == 13);
assert(strlen(p->getName()) <= 13); assert(strlen(p->getName()) <= 13);
} }