pe: refactoring started

This commit is contained in:
László Molnár 2013-10-06 22:57:20 +02:00
parent aa2ac1bbb8
commit 8ab229cca9
6 changed files with 117 additions and 96 deletions

View File

@ -39,13 +39,6 @@ static const
static const static const
#include "stub/arm.v4t-wince.pe.h" #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 #define FILLVAL 0
/************************************************************************* /*************************************************************************
@ -790,10 +783,9 @@ void PackArmPe::pack(OutputFile *fo)
ODADDR(PEDIR_BOUNDIM) = 0; ODADDR(PEDIR_BOUNDIM) = 0;
ODSIZE(PEDIR_BOUNDIM) = 0; ODSIZE(PEDIR_BOUNDIM) = 0;
// tls is put into section 1 // tls is put into section 1
ic = s1addr + s1size - sotls; ic = s1addr + s1size - sotls;
super::processTls(&rel,&tlsiv,ic); // super::processTls(&rel,&tlsiv,ic);
ODADDR(PEDIR_TLS) = sotls ? ic : 0; ODADDR(PEDIR_TLS) = sotls ? ic : 0;
ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0; ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0;
ic += sotls; ic += sotls;
@ -803,7 +795,7 @@ void PackArmPe::pack(OutputFile *fo)
ic = ncsection; ic = ncsection;
// wince wants relocation data at the beginning of a section // wince wants relocation data at the beginning of a section
processRelocs(&rel); PeFile::processRelocs(&rel);
ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0; ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0;
ODSIZE(PEDIR_RELOC) = soxrelocs; ODSIZE(PEDIR_RELOC) = soxrelocs;
ic += soxrelocs; ic += soxrelocs;

View File

@ -34,9 +34,9 @@
// arm/pe // arm/pe
**************************************************************************/ **************************************************************************/
class PackArmPe : public PeFile class PackArmPe : public PeFile32
{ {
typedef PeFile super; typedef PeFile32 super;
public: public:
PackArmPe(InputFile *f); PackArmPe(InputFile *f);

View File

@ -37,13 +37,6 @@
static const static const
#include "stub/i386-win32.pe.h" #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 #define FILLVAL 0
@ -1226,7 +1219,7 @@ void PackW32Pe::pack(OutputFile *fo)
} }
ic += soexport; ic += soexport;
processRelocs(&rel); PeFile::processRelocs(&rel);
ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0; ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0;
ODSIZE(PEDIR_RELOC) = soxrelocs; ODSIZE(PEDIR_RELOC) = soxrelocs;
ic += soxrelocs; ic += soxrelocs;

View File

@ -34,9 +34,9 @@
// w32/pe // w32/pe
**************************************************************************/ **************************************************************************/
class PackW32Pe : public PeFile class PackW32Pe : public PeFile32
{ {
typedef PeFile super; typedef PeFile32 super;
public: public:
PackW32Pe(InputFile *f); PackW32Pe(InputFile *f);

View File

@ -32,13 +32,6 @@
#include "packer.h" #include "packer.h"
#include "pefile.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 #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) PeFile::PeFile(InputFile *f) : super(f)
{ {
bele = &N_BELE_RTP::le_policy; bele = &N_BELE_RTP::le_policy;
//printf("pe_header_t %d\n", (int) sizeof(pe_header_t)); COMPILE_TIME_ASSERT(sizeof(ddirs_t) == 8)
//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(pe_section_t) == 40) COMPILE_TIME_ASSERT(sizeof(pe_section_t) == 40)
COMPILE_TIME_ASSERT_ALIGNED1(pe_header_t) COMPILE_TIME_ASSERT_ALIGNED1(ddirs_t)
COMPILE_TIME_ASSERT_ALIGNED1(pe_header_t::ddirs_t)
COMPILE_TIME_ASSERT_ALIGNED1(pe_section_t) COMPILE_TIME_ASSERT_ALIGNED1(pe_section_t)
COMPILE_TIME_ASSERT(RT_LAST == TABLESIZE(opt->win32_pe.compress_rt)) COMPILE_TIME_ASSERT(RT_LAST == TABLESIZE(opt->win32_pe.compress_rt))
@ -130,6 +119,7 @@ PeFile::PeFile(InputFile *f) : super(f)
sorelocs = 0; sorelocs = 0;
soxrelocs = 0; soxrelocs = 0;
sotls = 0; sotls = 0;
isdll = false;
} }
@ -202,7 +192,7 @@ int PeFile::readFileHeader()
if (ic == 20) if (ic == 20)
return 0; return 0;
fi->seek(pe_offset,SEEK_SET); fi->seek(pe_offset,SEEK_SET);
fi->readx(&ih,sizeof(ih)); readPeHeader();
fi->seek(0x200,SEEK_SET); fi->seek(0x200,SEEK_SET);
fi->readx(&h,6); fi->readx(&h,6);
return getFormat(); return getFormat();
@ -373,11 +363,11 @@ void PeFile::Reloc::finish(upx_byte *&p,unsigned &siz)
void PeFile::processRelocs(Reloc *rel) // pass2 void PeFile::processRelocs(Reloc *rel) // pass2
{ {
rel->finish(oxrelocs,soxrelocs); rel->finish(oxrelocs,soxrelocs);
if (opt->win32_pe.strip_relocs && !isdll) if (opt->win32_pe.strip_relocs && !isdll /*FIXME ASLR*/)
soxrelocs = 0; soxrelocs = 0;
} }
void PeFile::processRelocs() // pass1 void PeFile32::processRelocs() // pass1
{ {
big_relocs = 0; 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); info("Relocations: original size: %u bytes, preprocessed size: %u bytes",(unsigned) IDSIZE(PEDIR_RELOC),sorelocs);
} }
#if 0
/************************************************************************* /*************************************************************************
// import handling // import handling
**************************************************************************/ **************************************************************************/
@ -759,7 +749,7 @@ unsigned PeFile::processImports() // pass 1
info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport); info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport);
return names.ivnum == 1 ? names.ivarr[0].start : 0; return names.ivnum == 1 ? names.ivarr[0].start : 0;
} }
#endif
/************************************************************************* /*************************************************************************
// export handling // 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 tls area is not relocated, because the relocation is done by
// the virtual memory manager only for pages which are not yet loaded. // the virtual memory manager only for pages which are not yet loaded.
// of course it was impossible to debug this ;-) // of course it was impossible to debug this ;-)
#if 0
__packed_struct(tls) __packed_struct(tls)
LE32 datastart; // VA tls init data start LE32 datastart; // VA tls init data start
LE32 dataend; // VA tls init data end 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->dataend = newaddr + sotls + ih.imagebase;
tlsp->callbacks = 0; // note: TLS callbacks are not implemented in Windows 95/98/ME tlsp->callbacks = 0; // note: TLS callbacks are not implemented in Windows 95/98/ME
} }
#endif
/************************************************************************* /*************************************************************************
// resource handling // resource handling
@ -1573,7 +1563,7 @@ unsigned PeFile::stripDebug(unsigned overlaystart)
// unpack // unpack
**************************************************************************/ **************************************************************************/
void PeFile::rebuildRelocs(upx_byte *& extrainfo) void PeFile32::rebuildRelocs(upx_byte *& extrainfo)
{ {
if (!ODADDR(PEDIR_RELOC) || !ODSIZE(PEDIR_RELOC) || (oh.flags & RELOCS_STRIPPED)) if (!ODADDR(PEDIR_RELOC) || !ODSIZE(PEDIR_RELOC) || (oh.flags & RELOCS_STRIPPED))
return; return;
@ -1657,7 +1647,7 @@ void PeFile::rebuildTls()
// this is an easy one : just do nothing ;-) // 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) if (ODSIZE(PEDIR_RESOURCE) == 0 || IDSIZE(PEDIR_RESOURCE) == 0)
return; return;
@ -1666,7 +1656,7 @@ void PeFile::rebuildResources(upx_byte *& extrainfo)
extrainfo += 2; extrainfo += 2;
const unsigned vaddr = IDADDR(PEDIR_RESOURCE); 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); Resource res(r + vaddr);
while (res.next()) while (res.next())
if (res.offs() > vaddr) if (res.offs() > vaddr)
@ -1688,7 +1678,8 @@ void PeFile::rebuildResources(upx_byte *& extrainfo)
delete [] p; delete [] p;
} }
void PeFile::unpack(OutputFile *fo) template <typename ht>
void PeFile::unpack(OutputFile *fo, const ht &ih, ht &oh)
{ {
//infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), objs); //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); 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 //FIXME: this does bad things if the relocation section got removed
// during compression ... // during compression ...
@ -1806,6 +1797,26 @@ void PeFile::unpack(OutputFile *fo)
ibuf.dealloc(); 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: extra info added to help uncompression:

View File

@ -47,7 +47,8 @@ protected:
virtual ~PeFile(); virtual ~PeFile();
virtual int getVersion() const { return 13; } virtual int getVersion() const { return 13; }
virtual void unpack(OutputFile *fo); template <typename ht>
void unpack(OutputFile *fo, const ht &ih, ht &oh);
// unpacker capabilities // unpacker capabilities
virtual bool canUnpackVersion(int version) const virtual bool canUnpackVersion(int version) const
@ -56,6 +57,7 @@ protected:
protected: protected:
virtual int readFileHeader(); virtual int readFileHeader();
virtual bool testUnpackVersion(int version) const; virtual bool testUnpackVersion(int version) const;
virtual void readPeHeader() = 0;
unsigned pe_offset; unsigned pe_offset;
@ -67,9 +69,9 @@ protected:
upx_byte *oimpdlls; upx_byte *oimpdlls;
unsigned soimpdlls; unsigned soimpdlls;
void processRelocs(); virtual void processRelocs() = 0;
void processRelocs(Reloc *); void processRelocs(Reloc *);
void rebuildRelocs(upx_byte *&); virtual void rebuildRelocs(upx_byte *&) = 0;
upx_byte *orelocs; upx_byte *orelocs;
unsigned sorelocs; unsigned sorelocs;
upx_byte *oxrelocs; upx_byte *oxrelocs;
@ -83,12 +85,12 @@ protected:
void processResources(Resource *); void processResources(Resource *);
void processResources(Resource *, unsigned); void processResources(Resource *, unsigned);
void rebuildResources(upx_byte *&); void rebuildResources(upx_byte *&, unsigned);
upx_byte *oresources; upx_byte *oresources;
unsigned soresources; unsigned soresources;
virtual void processTls(Interval *); // virtual void processTls(Interval *);
void processTls(Reloc *, const Interval *, unsigned); // void processTls(Reloc *, const Interval *, unsigned);
void rebuildTls(); void rebuildTls();
upx_byte *otls; upx_byte *otls;
unsigned sotls; unsigned sotls;
@ -106,49 +108,17 @@ protected:
unsigned crelocs; // rva of preprocessed fixups unsigned crelocs; // rva of preprocessed fixups
int big_relocs; int big_relocs;
__packed_struct(pe_header_t) __packed_struct(ddirs_t)
// 0x0 LE32 vaddr;
char _[4]; // pemagic LE32 size;
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_end() __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) __packed_struct(pe_section_t)
char name[8]; char name[8];
@ -160,8 +130,8 @@ protected:
LE32 flags; LE32 flags;
__packed_struct_end() __packed_struct_end()
pe_header_t ih, oh;
pe_section_t *isection; pe_section_t *isection;
bool isdll;
static unsigned virta2objnum (unsigned, pe_section_t *, unsigned); static unsigned virta2objnum (unsigned, pe_section_t *, unsigned);
unsigned tryremove (unsigned, 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 */ #endif /* already included */