diff --git a/src/p_armpe.cpp b/src/p_armpe.cpp index c5ee7625..88e75f96 100644 --- a/src/p_armpe.cpp +++ b/src/p_armpe.cpp @@ -39,13 +39,6 @@ static const static const #include "stub/arm.v4t-wince.pe.h" -#define IDSIZE(x) ih.ddirs[x].size -#define IDADDR(x) ih.ddirs[x].vaddr -#define ODSIZE(x) oh.ddirs[x].size -#define ODADDR(x) oh.ddirs[x].vaddr - -#define isdll ((ih.flags & DLL_FLAG) != 0) - #define FILLVAL 0 /************************************************************************* @@ -790,10 +783,9 @@ void PackArmPe::pack(OutputFile *fo) ODADDR(PEDIR_BOUNDIM) = 0; ODSIZE(PEDIR_BOUNDIM) = 0; - // tls is put into section 1 ic = s1addr + s1size - sotls; - super::processTls(&rel,&tlsiv,ic); +// super::processTls(&rel,&tlsiv,ic); ODADDR(PEDIR_TLS) = sotls ? ic : 0; ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0; ic += sotls; @@ -803,7 +795,7 @@ void PackArmPe::pack(OutputFile *fo) ic = ncsection; // wince wants relocation data at the beginning of a section - processRelocs(&rel); + PeFile::processRelocs(&rel); ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0; ODSIZE(PEDIR_RELOC) = soxrelocs; ic += soxrelocs; diff --git a/src/p_armpe.h b/src/p_armpe.h index 03e76ebf..542c14fb 100644 --- a/src/p_armpe.h +++ b/src/p_armpe.h @@ -34,9 +34,9 @@ // arm/pe **************************************************************************/ -class PackArmPe : public PeFile +class PackArmPe : public PeFile32 { - typedef PeFile super; + typedef PeFile32 super; public: PackArmPe(InputFile *f); diff --git a/src/p_w32pe.cpp b/src/p_w32pe.cpp index 601853d3..69a923a8 100644 --- a/src/p_w32pe.cpp +++ b/src/p_w32pe.cpp @@ -37,13 +37,6 @@ static const #include "stub/i386-win32.pe.h" -#define IDSIZE(x) ih.ddirs[x].size -#define IDADDR(x) ih.ddirs[x].vaddr -#define ODSIZE(x) oh.ddirs[x].size -#define ODADDR(x) oh.ddirs[x].vaddr - -#define isdll ((ih.flags & DLL_FLAG) != 0) - #define FILLVAL 0 @@ -1226,7 +1219,7 @@ void PackW32Pe::pack(OutputFile *fo) } ic += soexport; - processRelocs(&rel); + PeFile::processRelocs(&rel); ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0; ODSIZE(PEDIR_RELOC) = soxrelocs; ic += soxrelocs; diff --git a/src/p_w32pe.h b/src/p_w32pe.h index 3b4d7c19..196d6eff 100644 --- a/src/p_w32pe.h +++ b/src/p_w32pe.h @@ -34,9 +34,9 @@ // w32/pe **************************************************************************/ -class PackW32Pe : public PeFile +class PackW32Pe : public PeFile32 { - typedef PeFile super; + typedef PeFile32 super; public: PackW32Pe(InputFile *f); diff --git a/src/pefile.cpp b/src/pefile.cpp index 8218658e..b443c0f3 100644 --- a/src/pefile.cpp +++ b/src/pefile.cpp @@ -32,13 +32,6 @@ #include "packer.h" #include "pefile.h" -#define IDSIZE(x) ih.ddirs[x].size -#define IDADDR(x) ih.ddirs[x].vaddr -#define ODSIZE(x) oh.ddirs[x].size -#define ODADDR(x) oh.ddirs[x].vaddr - -#define isdll ((ih.flags & DLL_FLAG) != 0) - #define FILLVAL 0 /************************************************************************* @@ -103,13 +96,9 @@ static void xcheck(size_t poff, size_t plen, const void *b, size_t blen) PeFile::PeFile(InputFile *f) : super(f) { bele = &N_BELE_RTP::le_policy; - //printf("pe_header_t %d\n", (int) sizeof(pe_header_t)); - //printf("pe_section_t %d\n", (int) sizeof(pe_section_t)); - COMPILE_TIME_ASSERT(sizeof(pe_header_t) == 248) - COMPILE_TIME_ASSERT(sizeof(pe_header_t::ddirs_t) == 8) + COMPILE_TIME_ASSERT(sizeof(ddirs_t) == 8) COMPILE_TIME_ASSERT(sizeof(pe_section_t) == 40) - COMPILE_TIME_ASSERT_ALIGNED1(pe_header_t) - COMPILE_TIME_ASSERT_ALIGNED1(pe_header_t::ddirs_t) + COMPILE_TIME_ASSERT_ALIGNED1(ddirs_t) COMPILE_TIME_ASSERT_ALIGNED1(pe_section_t) COMPILE_TIME_ASSERT(RT_LAST == TABLESIZE(opt->win32_pe.compress_rt)) @@ -130,6 +119,7 @@ PeFile::PeFile(InputFile *f) : super(f) sorelocs = 0; soxrelocs = 0; sotls = 0; + isdll = false; } @@ -202,7 +192,7 @@ int PeFile::readFileHeader() if (ic == 20) return 0; fi->seek(pe_offset,SEEK_SET); - fi->readx(&ih,sizeof(ih)); + readPeHeader(); fi->seek(0x200,SEEK_SET); fi->readx(&h,6); return getFormat(); @@ -373,11 +363,11 @@ void PeFile::Reloc::finish(upx_byte *&p,unsigned &siz) void PeFile::processRelocs(Reloc *rel) // pass2 { rel->finish(oxrelocs,soxrelocs); - if (opt->win32_pe.strip_relocs && !isdll) + if (opt->win32_pe.strip_relocs && !isdll /*FIXME ASLR*/) soxrelocs = 0; } -void PeFile::processRelocs() // pass1 +void PeFile32::processRelocs() // pass1 { big_relocs = 0; @@ -468,7 +458,7 @@ void PeFile::processRelocs() // pass1 info("Relocations: original size: %u bytes, preprocessed size: %u bytes",(unsigned) IDSIZE(PEDIR_RELOC),sorelocs); } - +#if 0 /************************************************************************* // import handling **************************************************************************/ @@ -759,7 +749,7 @@ unsigned PeFile::processImports() // pass 1 info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport); return names.ivnum == 1 ? names.ivarr[0].start : 0; } - +#endif /************************************************************************* // export handling @@ -915,7 +905,7 @@ void PeFile::processExports(Export *xport,unsigned newoffs) // pass2 // the tls area is not relocated, because the relocation is done by // the virtual memory manager only for pages which are not yet loaded. // of course it was impossible to debug this ;-) - +#if 0 __packed_struct(tls) LE32 datastart; // VA tls init data start LE32 dataend; // VA tls init data end @@ -1003,7 +993,7 @@ void PeFile::processTls(Reloc *rel,const Interval *iv,unsigned newaddr) // pass tlsp->dataend = newaddr + sotls + ih.imagebase; tlsp->callbacks = 0; // note: TLS callbacks are not implemented in Windows 95/98/ME } - +#endif /************************************************************************* // resource handling @@ -1573,7 +1563,7 @@ unsigned PeFile::stripDebug(unsigned overlaystart) // unpack **************************************************************************/ -void PeFile::rebuildRelocs(upx_byte *& extrainfo) +void PeFile32::rebuildRelocs(upx_byte *& extrainfo) { if (!ODADDR(PEDIR_RELOC) || !ODSIZE(PEDIR_RELOC) || (oh.flags & RELOCS_STRIPPED)) return; @@ -1657,7 +1647,7 @@ void PeFile::rebuildTls() // this is an easy one : just do nothing ;-) } -void PeFile::rebuildResources(upx_byte *& extrainfo) +void PeFile::rebuildResources(upx_byte *& extrainfo, unsigned lastvaddr) { if (ODSIZE(PEDIR_RESOURCE) == 0 || IDSIZE(PEDIR_RESOURCE) == 0) return; @@ -1666,7 +1656,7 @@ void PeFile::rebuildResources(upx_byte *& extrainfo) extrainfo += 2; const unsigned vaddr = IDADDR(PEDIR_RESOURCE); - const upx_byte *r = ibuf - isection[ih.objects - 1].vaddr; + const upx_byte *r = ibuf - lastvaddr; Resource res(r + vaddr); while (res.next()) if (res.offs() > vaddr) @@ -1688,7 +1678,8 @@ void PeFile::rebuildResources(upx_byte *& extrainfo) delete [] p; } -void PeFile::unpack(OutputFile *fo) +template +void PeFile::unpack(OutputFile *fo, const ht &ih, ht &oh) { //infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), objs); @@ -1751,7 +1742,7 @@ void PeFile::unpack(OutputFile *fo) fi->readx(ibuf,isection[3].size); } - rebuildResources(extrainfo); + rebuildResources(extrainfo, isection[ih.objects - 1].vaddr); //FIXME: this does bad things if the relocation section got removed // during compression ... @@ -1806,6 +1797,26 @@ void PeFile::unpack(OutputFile *fo) ibuf.dealloc(); } +PeFile32::PeFile32(InputFile *f) : super(f) +{ + COMPILE_TIME_ASSERT(sizeof(pe_header_t) == 248) + COMPILE_TIME_ASSERT_ALIGNED1(pe_header_t) + + iddirs = ih.ddirs; + oddirs = oh.ddirs; +} + +void PeFile32::readPeHeader() +{ + fi->readx(&ih,sizeof(ih)); + isdll = ((ih.flags & DLL_FLAG) != 0); +} + +void PeFile32::unpack(OutputFile *fo) +{ + super::unpack(fo, ih, oh); +} + /* extra info added to help uncompression: diff --git a/src/pefile.h b/src/pefile.h index a1c966ce..bae41348 100644 --- a/src/pefile.h +++ b/src/pefile.h @@ -47,7 +47,8 @@ protected: virtual ~PeFile(); virtual int getVersion() const { return 13; } - virtual void unpack(OutputFile *fo); + template + void unpack(OutputFile *fo, const ht &ih, ht &oh); // unpacker capabilities virtual bool canUnpackVersion(int version) const @@ -56,6 +57,7 @@ protected: protected: virtual int readFileHeader(); virtual bool testUnpackVersion(int version) const; + virtual void readPeHeader() = 0; unsigned pe_offset; @@ -67,9 +69,9 @@ protected: upx_byte *oimpdlls; unsigned soimpdlls; - void processRelocs(); + virtual void processRelocs() = 0; void processRelocs(Reloc *); - void rebuildRelocs(upx_byte *&); + virtual void rebuildRelocs(upx_byte *&) = 0; upx_byte *orelocs; unsigned sorelocs; upx_byte *oxrelocs; @@ -83,12 +85,12 @@ protected: void processResources(Resource *); void processResources(Resource *, unsigned); - void rebuildResources(upx_byte *&); + void rebuildResources(upx_byte *&, unsigned); upx_byte *oresources; unsigned soresources; - virtual void processTls(Interval *); - void processTls(Reloc *, const Interval *, unsigned); +// virtual void processTls(Interval *); +// void processTls(Reloc *, const Interval *, unsigned); void rebuildTls(); upx_byte *otls; unsigned sotls; @@ -106,49 +108,17 @@ protected: unsigned crelocs; // rva of preprocessed fixups int big_relocs; - __packed_struct(pe_header_t) - // 0x0 - char _[4]; // pemagic - LE16 cpu; - LE16 objects; - char __[12]; // timestamp + reserved - LE16 opthdrsize; - LE16 flags; - // optional header - LE16 coffmagic; // NEW: Stefan Widmann - char ___[2]; // linkerversion - LE32 codesize; - // 0x20 - LE32 datasize; - LE32 bsssize; - LE32 entry; - LE32 codebase; - // 0x30 - LE32 database; - // nt specific fields - LE32 imagebase; - LE32 objectalign; - LE32 filealign; // should set to 0x200 ? - // 0x40 - char ____[16]; // versions - // 0x50 - LE32 imagesize; - LE32 headersize; - LE32 chksum; // should set to 0 - LE16 subsystem; - LE16 dllflags; - // 0x60 - char _____[20]; // stack + heap sizes - // 0x74 - LE32 ddirsentries; // usually 16 - - __packed_struct(ddirs_t) - LE32 vaddr; - LE32 size; - __packed_struct_end() - - ddirs_t ddirs[16]; + __packed_struct(ddirs_t) + LE32 vaddr; + LE32 size; __packed_struct_end() + ddirs_t *iddirs; + ddirs_t *oddirs; + + LE32 &IDSIZE(unsigned x) { return iddirs[x].size; } + LE32 &IDADDR(unsigned x) { return iddirs[x].vaddr; } + LE32 &ODSIZE(unsigned x) { return oddirs[x].size; } + LE32 &ODADDR(unsigned x) { return oddirs[x].vaddr; } __packed_struct(pe_section_t) char name[8]; @@ -160,8 +130,8 @@ protected: LE32 flags; __packed_struct_end() - pe_header_t ih, oh; pe_section_t *isection; + bool isdll; static unsigned virta2objnum (unsigned, pe_section_t *, unsigned); unsigned tryremove (unsigned, unsigned); @@ -372,6 +342,61 @@ protected: }; +class PeFile32 : public PeFile +{ + typedef PeFile super; +protected: + PeFile32(InputFile *f); + //virtual ~PeFile32(); + virtual void unpack(OutputFile *fo); + + virtual void readPeHeader(); + + virtual void processRelocs(); + virtual void rebuildRelocs(upx_byte *&); + + __packed_struct(pe_header_t) + // 0x0 + char _[4]; // pemagic + LE16 cpu; + LE16 objects; + char __[12]; // timestamp + reserved + LE16 opthdrsize; + LE16 flags; + // optional header + LE16 coffmagic; // NEW: Stefan Widmann + char ___[2]; // linkerversion + LE32 codesize; + // 0x20 + LE32 datasize; + LE32 bsssize; + LE32 entry; + LE32 codebase; + // 0x30 + LE32 database; + // nt specific fields + LE32 imagebase; + LE32 objectalign; + LE32 filealign; // should set to 0x200 ? + // 0x40 + char ____[16]; // versions + // 0x50 + LE32 imagesize; + LE32 headersize; + LE32 chksum; // should set to 0 + LE16 subsystem; + LE16 dllflags; + // 0x60 + char _____[20]; // stack + heap sizes + // 0x74 + LE32 ddirsentries; // usually 16 + + ddirs_t ddirs[16]; + __packed_struct_end() + + pe_header_t ih, oh; +}; + #endif /* already included */