pe32: refactoring of import handling and unpacking continues
This commit is contained in:
parent
96708d7592
commit
9cb639b505
398
src/p_armpe.cpp
398
src/p_armpe.cpp
@ -67,6 +67,7 @@ static const
|
||||
#define OPTR_C(type, var, v) type* const var = (v)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void xcheck(const void *p, size_t plen, const void *b, size_t blen)
|
||||
{
|
||||
const char *pp = (const char *) p;
|
||||
@ -74,7 +75,7 @@ static void xcheck(const void *p, size_t plen, const void *b, size_t blen)
|
||||
if (pp < bb || pp > bb + blen || pp + plen > bb + blen)
|
||||
throwCantUnpack("pointer out of range; take care!");
|
||||
}
|
||||
#if 0
|
||||
|
||||
static void xcheck(size_t poff, size_t plen, const void *b, size_t blen)
|
||||
{
|
||||
ACC_UNUSED(b);
|
||||
@ -141,6 +142,10 @@ Linker* PackArmPe::newLinker() const
|
||||
// import handling
|
||||
**************************************************************************/
|
||||
|
||||
void PackArmPe::processImports(unsigned myimport, unsigned iat_off) // pass 2
|
||||
{
|
||||
PeFile::processImports(myimport, iat_off);
|
||||
|
||||
__packed_struct(import_desc)
|
||||
LE32 oft; // orig first thunk
|
||||
char _[8];
|
||||
@ -148,293 +153,23 @@ __packed_struct(import_desc)
|
||||
LE32 iat; // import address table
|
||||
__packed_struct_end()
|
||||
|
||||
void PackArmPe::processImports(unsigned myimport, unsigned iat_off) // pass 2
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(import_desc) == 20);
|
||||
|
||||
// adjust import data
|
||||
for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++)
|
||||
{
|
||||
if (im->dllname < myimport)
|
||||
im->dllname += myimport;
|
||||
LE32 *p = (LE32*) (oimpdlls + im->iat);
|
||||
im->iat += myimport;
|
||||
im->oft = im->iat;
|
||||
|
||||
while (*p)
|
||||
if ((*p++ & 0x80000000) == 0) // import by name?
|
||||
p[-1] += myimport;
|
||||
|
||||
im->iat = im == (import_desc*) oimpdlls ? iat_off : iat_off + 12;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned PackArmPe::processImports() // pass 1
|
||||
void PackArmPe::addKernelImports()
|
||||
{
|
||||
static const unsigned char kernel32dll[] = "COREDLL.dll";
|
||||
static const char llgpa[] = "\x0\x0""LoadLibraryW\x0\x0"
|
||||
"GetProcAddressA\x0\x0\x0"
|
||||
"CacheSync";
|
||||
//static const char exitp[] = "ExitProcess\x0\x0\x0";
|
||||
|
||||
unsigned dllnum = 0;
|
||||
import_desc *im = (import_desc*) (ibuf + IDADDR(PEDIR_IMPORT));
|
||||
import_desc * const im_save = im;
|
||||
if (IDADDR(PEDIR_IMPORT))
|
||||
{
|
||||
while (im->dllname)
|
||||
dllnum++, im++;
|
||||
im = im_save;
|
||||
}
|
||||
|
||||
struct udll
|
||||
{
|
||||
const upx_byte *name;
|
||||
const upx_byte *shname;
|
||||
unsigned ordinal;
|
||||
unsigned iat;
|
||||
LE32 *lookupt;
|
||||
unsigned npos;
|
||||
unsigned original_position;
|
||||
bool isk32;
|
||||
|
||||
static int __acc_cdecl_qsort compare(const void *p1, const void *p2)
|
||||
{
|
||||
const udll *u1 = * (const udll * const *) p1;
|
||||
const udll *u2 = * (const udll * const *) p2;
|
||||
if (u1->isk32) return -1;
|
||||
if (u2->isk32) return 1;
|
||||
if (!*u1->lookupt) return 1;
|
||||
if (!*u2->lookupt) return -1;
|
||||
int rc = strcasecmp(u1->name,u2->name);
|
||||
if (rc) return rc;
|
||||
if (u1->ordinal) return -1;
|
||||
if (u2->ordinal) return 1;
|
||||
if (!u1->shname) return 1;
|
||||
if (!u2->shname) return -1;
|
||||
return strlen(u1->shname) - strlen(u2->shname);
|
||||
}
|
||||
};
|
||||
|
||||
// +1 for dllnum=0
|
||||
Array(struct udll, dlls, dllnum+1);
|
||||
Array(struct udll *, idlls, dllnum+1);
|
||||
|
||||
soimport = 1024; // safety
|
||||
|
||||
unsigned ic,k32o;
|
||||
for (ic = k32o = 0; dllnum && im->dllname; ic++, im++)
|
||||
{
|
||||
idlls[ic] = dlls + ic;
|
||||
dlls[ic].name = ibuf + im->dllname;
|
||||
dlls[ic].shname = NULL;
|
||||
dlls[ic].ordinal = 0;
|
||||
dlls[ic].iat = im->iat;
|
||||
dlls[ic].lookupt = (LE32*) (ibuf + (im->oft ? im->oft : im->iat));
|
||||
dlls[ic].npos = 0;
|
||||
dlls[ic].original_position = ic;
|
||||
dlls[ic].isk32 = strcasecmp(kernel32dll,dlls[ic].name) == 0;
|
||||
|
||||
soimport += strlen(dlls[ic].name) + 1 + 4;
|
||||
|
||||
for (IPTR_I(LE32, tarr, dlls[ic].lookupt); *tarr; tarr += 1)
|
||||
{
|
||||
if (*tarr & 0x80000000)
|
||||
{
|
||||
importbyordinal = true;
|
||||
soimport += 2; // ordinal num: 2 bytes
|
||||
dlls[ic].ordinal = *tarr & 0xffff;
|
||||
//if (dlls[ic].isk32)
|
||||
// kernel32ordinal = true,k32o++;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPTR_I(const upx_byte, n, ibuf + *tarr + 2);
|
||||
unsigned len = strlen(n);
|
||||
soimport += len + 1;
|
||||
if (dlls[ic].shname == NULL || len < strlen (dlls[ic].shname))
|
||||
dlls[ic].shname = n;
|
||||
}
|
||||
soimport++; // separator
|
||||
}
|
||||
}
|
||||
oimport = new upx_byte[soimport];
|
||||
memset(oimport,0,soimport);
|
||||
oimpdlls = new upx_byte[soimport];
|
||||
memset(oimpdlls,0,soimport);
|
||||
|
||||
qsort(idlls,dllnum,sizeof (udll*),udll::compare);
|
||||
|
||||
unsigned dllnamelen = sizeof (kernel32dll);
|
||||
unsigned dllnum2 = 1;
|
||||
for (ic = 0; ic < dllnum; ic++)
|
||||
if (!idlls[ic]->isk32 && (ic == 0 || strcasecmp(idlls[ic - 1]->name,idlls[ic]->name)))
|
||||
{
|
||||
dllnum2++;
|
||||
dllnamelen += strlen(idlls[ic]->name) + 1;
|
||||
}
|
||||
//fprintf(stderr,"dllnum=%d dllnum2=%d soimport=%d\n",dllnum,dllnum2,soimport); //
|
||||
|
||||
info("Processing imports: %d DLLs", dllnum);
|
||||
|
||||
// create the new import table
|
||||
im = (import_desc*) oimpdlls;
|
||||
|
||||
LE32 *ordinals = (LE32*) (oimpdlls + (dllnum2 + 1) * sizeof(import_desc));
|
||||
LE32 *lookuptable = ordinals + 4;// + k32o + (isdll ? 0 : 1);
|
||||
upx_byte *dllnames = ((upx_byte*) lookuptable) + (dllnum2 - 1) * 8;
|
||||
upx_byte *importednames = dllnames + (dllnamelen &~ 1);
|
||||
|
||||
unsigned k32namepos = ptr_diff(dllnames,oimpdlls);
|
||||
|
||||
memcpy(importednames, llgpa, ALIGN_UP((unsigned) sizeof(llgpa), 2u));
|
||||
strcpy(dllnames,kernel32dll);
|
||||
im->dllname = k32namepos;
|
||||
im->iat = ptr_diff(ordinals,oimpdlls);
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls); // LoadLibraryW
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls) + 14; // GetProcAddressA
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls) + 14 + 18; // CacheSync
|
||||
dllnames += sizeof(kernel32dll);
|
||||
importednames += sizeof(llgpa);
|
||||
|
||||
im++;
|
||||
for (ic = 0; ic < dllnum; ic++)
|
||||
if (idlls[ic]->isk32)
|
||||
{
|
||||
idlls[ic]->npos = k32namepos;
|
||||
/*
|
||||
if (idlls[ic]->ordinal)
|
||||
for (LE32 *tarr = idlls[ic]->lookupt; *tarr; tarr++)
|
||||
if (*tarr & 0x80000000)
|
||||
*ordinals++ = *tarr;
|
||||
*/
|
||||
}
|
||||
else if (ic && strcasecmp(idlls[ic-1]->name,idlls[ic]->name) == 0)
|
||||
idlls[ic]->npos = idlls[ic-1]->npos;
|
||||
else
|
||||
{
|
||||
im->dllname = idlls[ic]->npos = ptr_diff(dllnames,oimpdlls);
|
||||
im->iat = ptr_diff(lookuptable,oimpdlls);
|
||||
|
||||
strcpy(dllnames,idlls[ic]->name);
|
||||
dllnames += strlen(idlls[ic]->name)+1;
|
||||
if (idlls[ic]->ordinal)
|
||||
*lookuptable = idlls[ic]->ordinal + 0x80000000;
|
||||
else if (idlls[ic]->shname)
|
||||
{
|
||||
if (ptr_diff(importednames,oimpdlls) & 1)
|
||||
importednames--;
|
||||
*lookuptable = ptr_diff(importednames,oimpdlls);
|
||||
importednames += 2;
|
||||
strcpy(importednames,idlls[ic]->shname);
|
||||
importednames += strlen(idlls[ic]->shname) + 1;
|
||||
}
|
||||
lookuptable += 2;
|
||||
im++;
|
||||
}
|
||||
soimpdlls = ALIGN_UP(ptr_diff(importednames,oimpdlls),4);
|
||||
|
||||
Interval names(ibuf),iats(ibuf),lookups(ibuf);
|
||||
// create the preprocessed data
|
||||
//ordinals -= k32o;
|
||||
upx_byte *ppi = oimport; // preprocessed imports
|
||||
for (ic = 0; ic < dllnum; ic++)
|
||||
{
|
||||
LE32 *tarr = idlls[ic]->lookupt;
|
||||
#if 0 && ENABLE_THIS_AND_UNCOMPRESSION_WILL_BREAK
|
||||
if (!*tarr) // no imports from this dll
|
||||
continue;
|
||||
#endif
|
||||
set_le32(ppi,idlls[ic]->npos);
|
||||
set_le32(ppi+4,idlls[ic]->iat - rvamin);
|
||||
ppi += 8;
|
||||
for (; *tarr; tarr++)
|
||||
if (*tarr & 0x80000000)
|
||||
{
|
||||
/*if (idlls[ic]->isk32)
|
||||
{
|
||||
*ppi++ = 0xfe; // signed + odd parity
|
||||
set_le32(ppi,ptr_diff(ordinals,oimpdlls));
|
||||
ordinals++;
|
||||
ppi += 4;
|
||||
}
|
||||
else*/
|
||||
{
|
||||
*ppi++ = 0xff;
|
||||
set_le16(ppi,*tarr & 0xffff);
|
||||
ppi += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppi++ = 1;
|
||||
unsigned len = strlen(ibuf + *tarr + 2) + 1;
|
||||
memcpy(ppi,ibuf + *tarr + 2,len);
|
||||
ppi += len;
|
||||
names.add(*tarr,len + 2 + 1);
|
||||
}
|
||||
ppi++;
|
||||
|
||||
unsigned esize = ptr_diff((char *)tarr, (char *)idlls[ic]->lookupt);
|
||||
lookups.add(idlls[ic]->lookupt,esize);
|
||||
if (ptr_diff(ibuf + idlls[ic]->iat, (char *)idlls[ic]->lookupt))
|
||||
{
|
||||
memcpy(ibuf + idlls[ic]->iat, idlls[ic]->lookupt, esize);
|
||||
iats.add(idlls[ic]->iat,esize);
|
||||
}
|
||||
names.add(idlls[ic]->name,strlen(idlls[ic]->name) + 1 + 1);
|
||||
}
|
||||
ppi += 4;
|
||||
assert(ppi < oimport+soimport);
|
||||
soimport = ptr_diff(ppi,oimport);
|
||||
|
||||
if (soimport == 4)
|
||||
soimport = 0;
|
||||
|
||||
//OutputFile::dump("x0.imp", oimport, soimport);
|
||||
//OutputFile::dump("x1.imp", oimpdlls, soimpdlls);
|
||||
|
||||
unsigned ilen = 0;
|
||||
names.flatten();
|
||||
if (names.ivnum > 1)
|
||||
{
|
||||
// The area occupied by the dll and imported names is not continuous
|
||||
// so to still support uncompression, I can't zero the iat area.
|
||||
// This decreases compression ratio, so FIXME somehow.
|
||||
infoWarning("can't remove unneeded imports");
|
||||
ilen += sizeof(import_desc) * dllnum;
|
||||
#if defined(DEBUG)
|
||||
if (opt->verbose > 3)
|
||||
names.dump();
|
||||
#endif
|
||||
// do some work for the unpacker
|
||||
im = im_save;
|
||||
for (ic = 0; ic < dllnum; ic++, im++)
|
||||
{
|
||||
memset(im,FILLVAL,sizeof(*im));
|
||||
im->dllname = ptr_diff(dlls[idlls[ic]->original_position].name,ibuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iats.add(im_save,sizeof(import_desc) * dllnum);
|
||||
// zero unneeded data
|
||||
iats.clear();
|
||||
lookups.clear();
|
||||
}
|
||||
names.clear();
|
||||
|
||||
iats.add(&names);
|
||||
iats.add(&lookups);
|
||||
iats.flatten();
|
||||
for (ic = 0; ic < iats.ivnum; ic++)
|
||||
ilen += iats.ivarr[ic].len;
|
||||
|
||||
info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport);
|
||||
return names.ivnum == 1 ? names.ivarr[0].start : 0;
|
||||
addKernelImport("COREDLL.DLL", "LoadLibraryW");
|
||||
addKernelImport("COREDLL.DLL", "GetProcAddressA");
|
||||
addKernelImport("COREDLL.DLL", "CacheSync");
|
||||
}
|
||||
|
||||
|
||||
void PackArmPe::processTls(Interval *) // pass 1
|
||||
{
|
||||
if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4u)) == 0)
|
||||
@ -628,7 +363,7 @@ void PackArmPe::pack(OutputFile *fo)
|
||||
Interval tlsiv(ibuf);
|
||||
Export xport((char*)(unsigned char*)ibuf);
|
||||
|
||||
const unsigned dllstrings = processImports();
|
||||
const unsigned dllstrings = PeFile32::processImports();
|
||||
processTls(&tlsiv); // call before processRelocs!!
|
||||
processResources(&res);
|
||||
processExports(&xport);
|
||||
@ -1029,117 +764,6 @@ int PackArmPe::canUnpack()
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PackArmPe::rebuildImports(upx_byte *& extrainfo)
|
||||
{
|
||||
if (ODADDR(PEDIR_IMPORT) == 0
|
||||
|| ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))
|
||||
return;
|
||||
|
||||
// const upx_byte * const idata = obuf + get_le32(extrainfo);
|
||||
OPTR_C(const upx_byte, idata, obuf + get_le32(extrainfo));
|
||||
const unsigned inamespos = get_le32(extrainfo + 4);
|
||||
extrainfo += 8;
|
||||
|
||||
unsigned sdllnames = 0;
|
||||
|
||||
// const upx_byte *import = ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr;
|
||||
// const upx_byte *p;
|
||||
IPTR_I(const upx_byte, import, ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr);
|
||||
OPTR(const upx_byte, p);
|
||||
|
||||
for (p = idata; get_le32(p) != 0; ++p)
|
||||
{
|
||||
const upx_byte *dname = get_le32(p) + import;
|
||||
ICHECK(dname, 1);
|
||||
const unsigned dlen = strlen(dname);
|
||||
ICHECK(dname, dlen + 1);
|
||||
|
||||
sdllnames += dlen + 1;
|
||||
for (p += 8; *p;)
|
||||
if (*p == 1)
|
||||
p += strlen(++p) + 1;
|
||||
else if (*p == 0xff)
|
||||
p += 3; // ordinal
|
||||
else
|
||||
p += 5;
|
||||
}
|
||||
sdllnames = ALIGN_UP(sdllnames,2u);
|
||||
|
||||
upx_byte * const Obuf = obuf - rvamin;
|
||||
import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));
|
||||
import_desc *im = im0;
|
||||
upx_byte *dllnames = Obuf + inamespos;
|
||||
upx_byte *importednames = dllnames + sdllnames;
|
||||
upx_byte * const importednames_start = importednames;
|
||||
|
||||
for (p = idata; get_le32(p) != 0; ++p)
|
||||
{
|
||||
// restore the name of the dll
|
||||
const upx_byte *dname = get_le32(p) + import;
|
||||
ICHECK(dname, 1);
|
||||
const unsigned dlen = strlen(dname);
|
||||
ICHECK(dname, dlen + 1);
|
||||
|
||||
const unsigned iatoffs = get_le32(p + 4) + rvamin;
|
||||
if (inamespos)
|
||||
{
|
||||
// now I rebuild the dll names
|
||||
OCHECK(dllnames, dlen + 1);
|
||||
strcpy(dllnames, dname);
|
||||
im->dllname = ptr_diff(dllnames,Obuf);
|
||||
//;;;printf("\ndll: %s:",dllnames);
|
||||
dllnames += dlen + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
OCHECK(Obuf + im->dllname, dlen + 1);
|
||||
strcpy(Obuf + im->dllname, dname);
|
||||
}
|
||||
im->oft = im->iat = iatoffs;
|
||||
|
||||
// LE32 *newiat = (LE32 *) (Obuf + iatoffs);
|
||||
OPTR_I(LE32, newiat, (LE32 *) (Obuf + iatoffs));
|
||||
|
||||
// restore the imported names+ordinals
|
||||
for (p += 8; *p; ++newiat)
|
||||
if (*p == 1)
|
||||
{
|
||||
const unsigned ilen = strlen(++p) + 1;
|
||||
if (inamespos)
|
||||
{
|
||||
if (ptr_diff(importednames, importednames_start) & 1)
|
||||
importednames -= 1;
|
||||
omemcpy(importednames + 2, p, ilen);
|
||||
//;;;printf(" %s",importednames+2);
|
||||
*newiat = ptr_diff(importednames, Obuf);
|
||||
importednames += 2 + ilen;
|
||||
}
|
||||
else
|
||||
{
|
||||
OCHECK(Obuf + *newiat + 2, ilen + 1);
|
||||
strcpy(Obuf + *newiat + 2, p);
|
||||
}
|
||||
p += ilen;
|
||||
}
|
||||
else if (*p == 0xff)
|
||||
{
|
||||
*newiat = get_le16(p + 1) + 0x80000000;
|
||||
//;;;printf(" %x",(unsigned)*newiat);
|
||||
p += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*newiat = get_le32(get_le32(p + 1) + import);
|
||||
assert(*newiat & 0x80000000);
|
||||
p += 5;
|
||||
}
|
||||
*newiat = 0;
|
||||
im++;
|
||||
}
|
||||
//memset(idata,0,p - idata);
|
||||
}
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
@ -56,9 +56,8 @@ protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
virtual unsigned processImports();
|
||||
virtual void processImports(unsigned, unsigned);
|
||||
virtual void rebuildImports(upx_byte *&);
|
||||
virtual void addKernelImports();
|
||||
|
||||
virtual void processTls(Interval *);
|
||||
|
||||
|
||||
418
src/p_w32pe.cpp
418
src/p_w32pe.cpp
@ -49,7 +49,7 @@ static const
|
||||
# define strcpy(a,b) strcpy((char *)(a),(const char *)(b))
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
//static
|
||||
unsigned my_strlen(const char *s)
|
||||
{
|
||||
@ -81,6 +81,7 @@ static unsigned my_strlen(const unsigned char *s)
|
||||
#define OPTR_C(type, var, v) type* const var = (v)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void xcheck(const void *p, size_t plen, const void *b, size_t blen)
|
||||
{
|
||||
const char *pp = (const char *) p;
|
||||
@ -88,7 +89,6 @@ static void xcheck(const void *p, size_t plen, const void *b, size_t blen)
|
||||
if (pp < bb || pp > bb + blen || pp + plen > bb + blen)
|
||||
throwCantUnpack("pointer out of range; take care!");
|
||||
}
|
||||
#if 0
|
||||
static void xcheck(size_t poff, size_t plen, const void *b, size_t blen)
|
||||
{
|
||||
ACC_UNUSED(b);
|
||||
@ -299,307 +299,6 @@ void PackW32Pe::processTls(Reloc *rel,const Interval *iv,unsigned newaddr) // pa
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
// import handling
|
||||
**************************************************************************/
|
||||
|
||||
__packed_struct(import_desc)
|
||||
LE32 oft; // orig first thunk
|
||||
char _[8];
|
||||
LE32 dllname;
|
||||
LE32 iat; // import address table
|
||||
__packed_struct_end()
|
||||
|
||||
void PackW32Pe::processImports(unsigned myimport, unsigned) // pass 2
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(import_desc) == 20);
|
||||
|
||||
// adjust import data
|
||||
for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++)
|
||||
{
|
||||
if (im->dllname < myimport)
|
||||
im->dllname += myimport;
|
||||
LE32 *p = (LE32*) (oimpdlls + im->iat);
|
||||
im->iat += myimport;
|
||||
|
||||
while (*p)
|
||||
if ((*p++ & 0x80000000) == 0) // import by name?
|
||||
p[-1] += myimport;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned PackW32Pe::processImports() // pass 1
|
||||
{
|
||||
static const unsigned char kernel32dll[] = "KERNEL32.DLL";
|
||||
static const char llgpa[] = "\x0\x0""LoadLibraryA\x0\x0"
|
||||
"GetProcAddress\x0\x0"
|
||||
"VirtualProtect\x0\x0"
|
||||
"VirtualAlloc\x0\x0"
|
||||
"VirtualFree\x0\x0\x0";
|
||||
static const char exitp[] = "ExitProcess\x0\x0\x0";
|
||||
|
||||
unsigned dllnum = 0;
|
||||
import_desc *im = (import_desc*) (ibuf + IDADDR(PEDIR_IMPORT));
|
||||
import_desc * const im_save = im;
|
||||
if (IDADDR(PEDIR_IMPORT))
|
||||
{
|
||||
while (im->dllname)
|
||||
dllnum++, im++;
|
||||
im = im_save;
|
||||
}
|
||||
|
||||
struct udll
|
||||
{
|
||||
const upx_byte *name;
|
||||
const upx_byte *shname;
|
||||
unsigned ordinal;
|
||||
unsigned iat;
|
||||
LE32 *lookupt;
|
||||
unsigned npos;
|
||||
unsigned original_position;
|
||||
bool isk32;
|
||||
|
||||
static int __acc_cdecl_qsort compare(const void *p1, const void *p2)
|
||||
{
|
||||
const udll *u1 = * (const udll * const *) p1;
|
||||
const udll *u2 = * (const udll * const *) p2;
|
||||
if (u1->isk32) return -1;
|
||||
if (u2->isk32) return 1;
|
||||
if (!*u1->lookupt) return 1;
|
||||
if (!*u2->lookupt) return -1;
|
||||
int rc = strcasecmp(u1->name,u2->name);
|
||||
if (rc) return rc;
|
||||
if (u1->ordinal) return -1;
|
||||
if (u2->ordinal) return 1;
|
||||
if (!u1->shname) return 1;
|
||||
if (!u2->shname) return -1;
|
||||
return strlen(u1->shname) - strlen(u2->shname);
|
||||
}
|
||||
};
|
||||
|
||||
// +1 for dllnum=0
|
||||
Array(struct udll, dlls, dllnum+1);
|
||||
Array(struct udll *, idlls, dllnum+1);
|
||||
|
||||
soimport = 1024; // safety
|
||||
|
||||
unsigned ic,k32o;
|
||||
for (ic = k32o = 0; dllnum && im->dllname; ic++, im++)
|
||||
{
|
||||
idlls[ic] = dlls + ic;
|
||||
dlls[ic].name = ibuf + im->dllname;
|
||||
dlls[ic].shname = NULL;
|
||||
dlls[ic].ordinal = 0;
|
||||
dlls[ic].iat = im->iat;
|
||||
dlls[ic].lookupt = (LE32*) (ibuf + (im->oft ? im->oft : im->iat));
|
||||
dlls[ic].npos = 0;
|
||||
dlls[ic].original_position = ic;
|
||||
dlls[ic].isk32 = strcasecmp(kernel32dll,dlls[ic].name) == 0;
|
||||
|
||||
soimport += strlen(dlls[ic].name) + 1 + 4;
|
||||
|
||||
for (IPTR_I(LE32, tarr, dlls[ic].lookupt); *tarr; tarr += 1)
|
||||
{
|
||||
if (*tarr & 0x80000000)
|
||||
{
|
||||
importbyordinal = true;
|
||||
soimport += 2; // ordinal num: 2 bytes
|
||||
dlls[ic].ordinal = *tarr & 0xffff;
|
||||
if (dlls[ic].isk32)
|
||||
kernel32ordinal = true,k32o++;
|
||||
}
|
||||
else
|
||||
{
|
||||
IPTR_I(const upx_byte, n, ibuf + *tarr + 2);
|
||||
unsigned len = strlen(n);
|
||||
soimport += len + 1;
|
||||
if (dlls[ic].shname == NULL || len < strlen (dlls[ic].shname))
|
||||
dlls[ic].shname = n;
|
||||
}
|
||||
soimport++; // separator
|
||||
}
|
||||
}
|
||||
oimport = new upx_byte[soimport];
|
||||
memset(oimport,0,soimport);
|
||||
oimpdlls = new upx_byte[soimport];
|
||||
memset(oimpdlls,0,soimport);
|
||||
|
||||
qsort(idlls,dllnum,sizeof (udll*),udll::compare);
|
||||
|
||||
unsigned dllnamelen = sizeof (kernel32dll);
|
||||
unsigned dllnum2 = 1;
|
||||
for (ic = 0; ic < dllnum; ic++)
|
||||
if (!idlls[ic]->isk32 && (ic == 0 || strcasecmp(idlls[ic - 1]->name,idlls[ic]->name)))
|
||||
{
|
||||
dllnum2++;
|
||||
dllnamelen += strlen(idlls[ic]->name) + 1;
|
||||
}
|
||||
//fprintf(stderr,"dllnum=%d dllnum2=%d soimport=%d\n",dllnum,dllnum2,soimport); //
|
||||
|
||||
info("Processing imports: %d DLLs", dllnum);
|
||||
|
||||
// create the new import table
|
||||
im = (import_desc*) oimpdlls;
|
||||
|
||||
LE32 *ordinals = (LE32*) (oimpdlls + (dllnum2 + 1) * sizeof(import_desc));
|
||||
LE32 *lookuptable = ordinals + 6 + k32o + (isdll ? 0 : 1);
|
||||
upx_byte *dllnames = ((upx_byte*) lookuptable) + (dllnum2 - 1) * 8;
|
||||
upx_byte *importednames = dllnames + (dllnamelen &~ 1);
|
||||
|
||||
unsigned k32namepos = ptr_diff(dllnames,oimpdlls);
|
||||
|
||||
memcpy(importednames, llgpa, sizeof(llgpa));
|
||||
if (!isdll)
|
||||
memcpy(importednames + sizeof(llgpa) - 1, exitp, sizeof(exitp));
|
||||
strcpy(dllnames,kernel32dll);
|
||||
im->dllname = k32namepos;
|
||||
im->iat = ptr_diff(ordinals,oimpdlls);
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls); // LoadLibraryA
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls) + 14; // GetProcAddress
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls) + 14 + 16; // VirtualProtect
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls) + 14 + 16 + 16; // VirtualAlloc
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls) + 14 + 16 + 16 + 14; // VirtualFree
|
||||
if (!isdll)
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls) + sizeof(llgpa) - 3; // ExitProcess
|
||||
dllnames += sizeof(kernel32dll);
|
||||
importednames += sizeof(llgpa) - 2 + (isdll ? 0 : sizeof(exitp) - 1);
|
||||
|
||||
im++;
|
||||
for (ic = 0; ic < dllnum; ic++)
|
||||
if (idlls[ic]->isk32)
|
||||
{
|
||||
idlls[ic]->npos = k32namepos;
|
||||
if (idlls[ic]->ordinal)
|
||||
for (LE32 *tarr = idlls[ic]->lookupt; *tarr; tarr++)
|
||||
if (*tarr & 0x80000000)
|
||||
*ordinals++ = *tarr;
|
||||
}
|
||||
else if (ic && strcasecmp(idlls[ic-1]->name,idlls[ic]->name) == 0)
|
||||
idlls[ic]->npos = idlls[ic-1]->npos;
|
||||
else
|
||||
{
|
||||
im->dllname = idlls[ic]->npos = ptr_diff(dllnames,oimpdlls);
|
||||
im->iat = ptr_diff(lookuptable,oimpdlls);
|
||||
|
||||
strcpy(dllnames,idlls[ic]->name);
|
||||
dllnames += strlen(idlls[ic]->name)+1;
|
||||
if (idlls[ic]->ordinal)
|
||||
*lookuptable = idlls[ic]->ordinal + 0x80000000;
|
||||
else if (idlls[ic]->shname)
|
||||
{
|
||||
if (ptr_diff(importednames,oimpdlls) & 1)
|
||||
importednames--;
|
||||
*lookuptable = ptr_diff(importednames,oimpdlls);
|
||||
importednames += 2;
|
||||
strcpy(importednames,idlls[ic]->shname);
|
||||
importednames += strlen(idlls[ic]->shname) + 1;
|
||||
}
|
||||
lookuptable += 2;
|
||||
im++;
|
||||
}
|
||||
soimpdlls = ALIGN_UP(ptr_diff(importednames,oimpdlls),4);
|
||||
|
||||
Interval names(ibuf),iats(ibuf),lookups(ibuf);
|
||||
// create the preprocessed data
|
||||
ordinals -= k32o;
|
||||
upx_byte *ppi = oimport; // preprocessed imports
|
||||
for (ic = 0; ic < dllnum; ic++)
|
||||
{
|
||||
LE32 *tarr = idlls[ic]->lookupt;
|
||||
#if 0 && ENABLE_THIS_AND_UNCOMPRESSION_WILL_BREAK
|
||||
if (!*tarr) // no imports from this dll
|
||||
continue;
|
||||
#endif
|
||||
set_le32(ppi,idlls[ic]->npos);
|
||||
set_le32(ppi+4,idlls[ic]->iat - rvamin);
|
||||
ppi += 8;
|
||||
for (; *tarr; tarr++)
|
||||
if (*tarr & 0x80000000)
|
||||
{
|
||||
if (idlls[ic]->isk32)
|
||||
{
|
||||
*ppi++ = 0xfe; // signed + odd parity
|
||||
set_le32(ppi,ptr_diff(ordinals,oimpdlls));
|
||||
ordinals++;
|
||||
ppi += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppi++ = 0xff;
|
||||
set_le16(ppi,*tarr & 0xffff);
|
||||
ppi += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppi++ = 1;
|
||||
unsigned len = strlen(ibuf + *tarr + 2) + 1;
|
||||
memcpy(ppi,ibuf + *tarr + 2,len);
|
||||
ppi += len;
|
||||
names.add(*tarr,len + 2 + 1);
|
||||
}
|
||||
ppi++;
|
||||
|
||||
unsigned esize = ptr_diff((char *)tarr, (char *)idlls[ic]->lookupt);
|
||||
lookups.add(idlls[ic]->lookupt,esize);
|
||||
if (ptr_diff(ibuf + idlls[ic]->iat, (char *)idlls[ic]->lookupt))
|
||||
{
|
||||
memcpy(ibuf + idlls[ic]->iat, idlls[ic]->lookupt, esize);
|
||||
iats.add(idlls[ic]->iat,esize);
|
||||
}
|
||||
names.add(idlls[ic]->name,strlen(idlls[ic]->name) + 1 + 1);
|
||||
}
|
||||
ppi += 4;
|
||||
assert(ppi < oimport+soimport);
|
||||
soimport = ptr_diff(ppi,oimport);
|
||||
|
||||
if (soimport == 4)
|
||||
soimport = 0;
|
||||
|
||||
//OutputFile::dump("x0.imp", oimport, soimport);
|
||||
//OutputFile::dump("x1.imp", oimpdlls, soimpdlls);
|
||||
|
||||
unsigned ilen = 0;
|
||||
names.flatten();
|
||||
if (names.ivnum > 1)
|
||||
{
|
||||
// The area occupied by the dll and imported names is not continuous
|
||||
// so to still support uncompression, I can't zero the iat area.
|
||||
// This decreases compression ratio, so FIXME somehow.
|
||||
infoWarning("can't remove unneeded imports");
|
||||
ilen += sizeof(import_desc) * dllnum;
|
||||
#if defined(DEBUG)
|
||||
if (opt->verbose > 3)
|
||||
names.dump();
|
||||
#endif
|
||||
// do some work for the unpacker
|
||||
im = im_save;
|
||||
for (ic = 0; ic < dllnum; ic++, im++)
|
||||
{
|
||||
memset(im,FILLVAL,sizeof(*im));
|
||||
im->dllname = ptr_diff(dlls[idlls[ic]->original_position].name,ibuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
iats.add(im_save,sizeof(import_desc) * dllnum);
|
||||
// zero unneeded data
|
||||
iats.clear();
|
||||
lookups.clear();
|
||||
}
|
||||
names.clear();
|
||||
|
||||
iats.add(&names);
|
||||
iats.add(&lookups);
|
||||
iats.flatten();
|
||||
for (ic = 0; ic < iats.ivnum; ic++)
|
||||
ilen += iats.ivarr[ic].len;
|
||||
|
||||
info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport);
|
||||
return names.ivnum == 1 ? names.ivarr[0].start : 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// Load Configuration handling
|
||||
**************************************************************************/
|
||||
@ -1204,7 +903,7 @@ void PackW32Pe::pack(OutputFile *fo)
|
||||
ODSIZE(PEDIR_RESOURCE) = soresources;
|
||||
ic += soresources;
|
||||
|
||||
processImports(ic, 0);
|
||||
PeFile::processImports(ic, 0);
|
||||
ODADDR(PEDIR_IMPORT) = ic;
|
||||
ODSIZE(PEDIR_IMPORT) = soimpdlls;
|
||||
ic += soimpdlls;
|
||||
@ -1411,117 +1110,6 @@ int PackW32Pe::canUnpack()
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PackW32Pe::rebuildImports(upx_byte *& extrainfo)
|
||||
{
|
||||
if (ODADDR(PEDIR_IMPORT) == 0
|
||||
|| ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))
|
||||
return;
|
||||
|
||||
// const upx_byte * const idata = obuf + get_le32(extrainfo);
|
||||
OPTR_C(const upx_byte, idata, obuf + get_le32(extrainfo));
|
||||
const unsigned inamespos = get_le32(extrainfo + 4);
|
||||
extrainfo += 8;
|
||||
|
||||
unsigned sdllnames = 0;
|
||||
|
||||
// const upx_byte *import = ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr;
|
||||
// const upx_byte *p;
|
||||
IPTR_I(const upx_byte, import, ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr);
|
||||
OPTR(const upx_byte, p);
|
||||
|
||||
for (p = idata; get_le32(p) != 0; ++p)
|
||||
{
|
||||
const upx_byte *dname = get_le32(p) + import;
|
||||
ICHECK(dname, 1);
|
||||
const unsigned dlen = strlen(dname);
|
||||
ICHECK(dname, dlen + 1);
|
||||
|
||||
sdllnames += dlen + 1;
|
||||
for (p += 8; *p;)
|
||||
if (*p == 1)
|
||||
p += strlen(++p) + 1;
|
||||
else if (*p == 0xff)
|
||||
p += 3; // ordinal
|
||||
else
|
||||
p += 5;
|
||||
}
|
||||
sdllnames = ALIGN_UP(sdllnames, 2u);
|
||||
|
||||
upx_byte * const Obuf = obuf - rvamin;
|
||||
import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));
|
||||
import_desc *im = im0;
|
||||
upx_byte *dllnames = Obuf + inamespos;
|
||||
upx_byte *importednames = dllnames + sdllnames;
|
||||
upx_byte * const importednames_start = importednames;
|
||||
|
||||
for (p = idata; get_le32(p) != 0; ++p)
|
||||
{
|
||||
// restore the name of the dll
|
||||
const upx_byte *dname = get_le32(p) + import;
|
||||
ICHECK(dname, 1);
|
||||
const unsigned dlen = strlen(dname);
|
||||
ICHECK(dname, dlen + 1);
|
||||
|
||||
const unsigned iatoffs = get_le32(p + 4) + rvamin;
|
||||
if (inamespos)
|
||||
{
|
||||
// now I rebuild the dll names
|
||||
OCHECK(dllnames, dlen + 1);
|
||||
strcpy(dllnames, dname);
|
||||
im->dllname = ptr_diff(dllnames,Obuf);
|
||||
//;;;printf("\ndll: %s:",dllnames);
|
||||
dllnames += dlen + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
OCHECK(Obuf + im->dllname, dlen + 1);
|
||||
strcpy(Obuf + im->dllname, dname);
|
||||
}
|
||||
im->iat = iatoffs;
|
||||
|
||||
// LE32 *newiat = (LE32 *) (Obuf + iatoffs);
|
||||
OPTR_I(LE32, newiat, (LE32 *) (Obuf + iatoffs));
|
||||
|
||||
// restore the imported names+ordinals
|
||||
for (p += 8; *p; ++newiat)
|
||||
if (*p == 1)
|
||||
{
|
||||
const unsigned ilen = strlen(++p) + 1;
|
||||
if (inamespos)
|
||||
{
|
||||
if (ptr_diff(importednames, importednames_start) & 1)
|
||||
importednames -= 1;
|
||||
omemcpy(importednames + 2, p, ilen);
|
||||
//;;;printf(" %s",importednames+2);
|
||||
*newiat = ptr_diff(importednames, Obuf);
|
||||
importednames += 2 + ilen;
|
||||
}
|
||||
else
|
||||
{
|
||||
OCHECK(Obuf + *newiat + 2, ilen + 1);
|
||||
strcpy(Obuf + *newiat + 2, p);
|
||||
}
|
||||
p += ilen;
|
||||
}
|
||||
else if (*p == 0xff)
|
||||
{
|
||||
*newiat = get_le16(p + 1) + 0x80000000;
|
||||
//;;;printf(" %x",(unsigned)*newiat);
|
||||
p += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*newiat = get_le32(get_le32(p + 1) + import);
|
||||
assert(*newiat & 0x80000000);
|
||||
p += 5;
|
||||
}
|
||||
*newiat = 0;
|
||||
im++;
|
||||
}
|
||||
//memset(idata,0,p - idata);
|
||||
}
|
||||
|
||||
/*
|
||||
extra info added to help uncompression:
|
||||
|
||||
|
||||
@ -58,10 +58,6 @@ protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
virtual unsigned processImports();
|
||||
virtual void processImports(unsigned, unsigned);
|
||||
virtual void rebuildImports(upx_byte *&);
|
||||
|
||||
virtual void processTls(Interval *); //NEW: TLS callback handling - Stefan Widmann
|
||||
void processTls(Reloc *, const Interval *, unsigned); //NEW: TLS callback handling - Stefan Widmann
|
||||
|
||||
|
||||
372
src/pefile.cpp
372
src/pefile.cpp
@ -44,6 +44,20 @@
|
||||
# define strcpy(a,b) strcpy((char *)(a),(const char *)(b))
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
//static
|
||||
unsigned my_strlen(const char *s)
|
||||
{
|
||||
size_t l = strlen((const char*)s); assert((unsigned) l == l); return (unsigned) l;
|
||||
}
|
||||
static unsigned my_strlen(const unsigned char *s)
|
||||
{
|
||||
size_t l = strlen((const char*)s); assert((unsigned) l == l); return (unsigned) l;
|
||||
}
|
||||
#undef strlen
|
||||
#define strlen my_strlen
|
||||
#endif
|
||||
|
||||
#if (__ACC_CXX_HAVE_PLACEMENT_DELETE) || defined(__DJGPP__)
|
||||
#include "bptr.h"
|
||||
#define IPTR(type, var) BoundedPtr<type> var(ibuf, ibuf.getSize())
|
||||
@ -531,12 +545,12 @@ class PeFile::ImportLinker : public ElfLinkerAMD64
|
||||
unsigned len = 1 + 2 * strlen(dll) + 1 + 2 * strlen(proc) + 1 + 1;
|
||||
tstr dlln(name_for_dll(dll, first_char));
|
||||
char *procn = new char[len];
|
||||
snprintf(procn, len - 1, "%s%c", (const char*) dlln, separator);
|
||||
upx_snprintf(procn, len - 1, "%s%c", (const char*) dlln, separator);
|
||||
encode_name(proc, procn + strlen(procn));
|
||||
return procn;
|
||||
}
|
||||
|
||||
static char zeros[sizeof(import_desc)];
|
||||
static const char zeros[sizeof(import_desc)];
|
||||
|
||||
enum {
|
||||
// the order of identifiers is very important below!!
|
||||
@ -635,15 +649,18 @@ public:
|
||||
template <typename C>
|
||||
void add(const C *dll, unsigned ordinal)
|
||||
{
|
||||
ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char"
|
||||
assert(ordinal > 0 && ordinal < 0x10000);
|
||||
char ord[20];
|
||||
snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal);
|
||||
char ord[1+5+1];
|
||||
upx_snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal);
|
||||
add((const char*) dll, ord, ordinal);
|
||||
}
|
||||
|
||||
template <typename C1, typename C2>
|
||||
void add(const C1 *dll, const C2 *proc)
|
||||
{
|
||||
ACC_COMPILE_TIME_ASSERT(sizeof(C1) == 1) // "char" or "unsigned char"
|
||||
ACC_COMPILE_TIME_ASSERT(sizeof(C2) == 1) // "char" or "unsigned char"
|
||||
assert(proc);
|
||||
add((const char*) dll, (const char*) proc, 0);
|
||||
}
|
||||
@ -680,6 +697,8 @@ public:
|
||||
template <typename C1, typename C2>
|
||||
upx_uint64_t getAddress(const C1 *dll, const C2 *proc) const
|
||||
{
|
||||
ACC_COMPILE_TIME_ASSERT(sizeof(C1) == 1) // "char" or "unsigned char"
|
||||
ACC_COMPILE_TIME_ASSERT(sizeof(C2) == 1) // "char" or "unsigned char"
|
||||
const Section *s = getThunk((const char*) dll, (const char*) proc,
|
||||
thunk_separator_first);
|
||||
if (s == NULL && (s = getThunk((const char*) dll,(const char*) proc,
|
||||
@ -688,12 +707,13 @@ public:
|
||||
return s->offset;
|
||||
}
|
||||
|
||||
template <typename C1>
|
||||
upx_uint64_t getAddress(const C1 *dll, unsigned ordinal) const
|
||||
template <typename C>
|
||||
upx_uint64_t getAddress(const C *dll, unsigned ordinal) const
|
||||
{
|
||||
ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char"
|
||||
assert(ordinal > 0 && ordinal < 0x10000);
|
||||
char ord[20];
|
||||
snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal);
|
||||
char ord[1+5+1];
|
||||
upx_snprintf(ord, sizeof(ord), "%c%05u", ordinal_id, ordinal);
|
||||
|
||||
const Section *s = getThunk((const char*) dll, ord, thunk_separator_first);
|
||||
if (s == NULL
|
||||
@ -702,56 +722,45 @@ public:
|
||||
return s->offset;
|
||||
}
|
||||
|
||||
template <typename C1>
|
||||
upx_uint64_t getAddress(const C1 *dll) const
|
||||
template <typename C>
|
||||
upx_uint64_t getAddress(const C *dll) const
|
||||
{
|
||||
ACC_COMPILE_TIME_ASSERT(sizeof(C) == 1) // "char" or "unsigned char"
|
||||
tstr sdll(name_for_dll((const char*) dll, dll_name_id));
|
||||
return findSection(sdll, true)->offset;
|
||||
}
|
||||
};
|
||||
char PeFile::ImportLinker::zeros[sizeof(import_desc)];
|
||||
const char PeFile::ImportLinker::zeros[sizeof(import_desc)] = { 0 };
|
||||
|
||||
#if 0
|
||||
/*************************************************************************
|
||||
// import handling
|
||||
**************************************************************************/
|
||||
|
||||
__packed_struct(import_desc)
|
||||
LE32 oft; // orig first thunk
|
||||
char _[8];
|
||||
LE32 dllname;
|
||||
LE32 iat; // import address table
|
||||
__packed_struct_end()
|
||||
|
||||
void PeFile::processImports(unsigned myimport, unsigned iat_off) // pass 2
|
||||
void PeFile::addKernelImport(const char *dll, const char *name)
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(import_desc) == 20)
|
||||
COMPILE_TIME_ASSERT_ALIGNED1(import_desc)
|
||||
|
||||
// adjust import data
|
||||
for (import_desc *im = (import_desc*) oimpdlls; im->dllname; im++)
|
||||
{
|
||||
if (im->dllname < myimport)
|
||||
im->dllname += myimport;
|
||||
LE32 *p = (LE32*) (oimpdlls + im->iat);
|
||||
im->iat += myimport;
|
||||
im->oft = im->iat;
|
||||
|
||||
while (*p)
|
||||
if ((*p++ & 0x80000000) == 0) // import by name?
|
||||
p[-1] += myimport;
|
||||
|
||||
im->iat = im == (import_desc*) oimpdlls ? iat_off : iat_off + 12;
|
||||
}
|
||||
ilinker->add(dll, name);
|
||||
}
|
||||
|
||||
unsigned PeFile::processImports() // pass 1
|
||||
void PeFile::addKernelImports()
|
||||
{
|
||||
static const unsigned char kernel32dll[] = "COREDLL.dll";
|
||||
static const char llgpa[] = "\x0\x0""LoadLibraryW\x0\x0"
|
||||
"GetProcAddressA\x0\x0\x0"
|
||||
"CacheSync";
|
||||
//static const char exitp[] = "ExitProcess\x0\x0\x0";
|
||||
addKernelImport("KERNEL32.DLL", "LoadLibraryA");
|
||||
addKernelImport("KERNEL32.DLL", "GetProcAddress");
|
||||
if (!isdll)
|
||||
addKernelImport("KERNEL32.DLL", "ExitProcess");
|
||||
addKernelImport("KERNEL32.DLL", "VirtualProtect");
|
||||
}
|
||||
|
||||
void PeFile::processImports(unsigned myimport, unsigned) // pass 2
|
||||
{
|
||||
COMPILE_TIME_ASSERT(sizeof(import_desc) == 20);
|
||||
|
||||
ilinker->relocate(myimport);
|
||||
int len;
|
||||
oimpdlls = ilinker->getLoader(&len);
|
||||
assert(len == (int) soimpdlls);
|
||||
//OutputFile::dump("x1.imp", oimpdlls, soimpdlls);
|
||||
}
|
||||
|
||||
template <typename LEXX, typename ord_mask_t>
|
||||
unsigned PeFile::processImports(ord_mask_t ord_mask) // pass 1
|
||||
{
|
||||
static const unsigned char kernel32dll[] = "KERNEL32.DLL";
|
||||
|
||||
unsigned dllnum = 0;
|
||||
import_desc *im = (import_desc*) (ibuf + IDADDR(PEDIR_IMPORT));
|
||||
@ -769,8 +778,8 @@ unsigned PeFile::processImports() // pass 1
|
||||
const upx_byte *shname;
|
||||
unsigned ordinal;
|
||||
unsigned iat;
|
||||
LE32 *lookupt;
|
||||
unsigned npos;
|
||||
LEXX *lookupt;
|
||||
unsigned original_position;
|
||||
bool isk32;
|
||||
|
||||
static int __acc_cdecl_qsort compare(const void *p1, const void *p2)
|
||||
@ -779,6 +788,8 @@ unsigned PeFile::processImports() // pass 1
|
||||
const udll *u2 = * (const udll * const *) p2;
|
||||
if (u1->isk32) return -1;
|
||||
if (u2->isk32) return 1;
|
||||
if (!*u1->lookupt) return 1;
|
||||
if (!*u2->lookupt) return -1;
|
||||
int rc = strcasecmp(u1->name,u2->name);
|
||||
if (rc) return rc;
|
||||
if (u1->ordinal) return -1;
|
||||
@ -795,33 +806,32 @@ unsigned PeFile::processImports() // pass 1
|
||||
|
||||
soimport = 1024; // safety
|
||||
|
||||
unsigned ic,k32o;
|
||||
for (ic = k32o = 0; dllnum && im->dllname; ic++, im++)
|
||||
unsigned ic;
|
||||
for (ic = 0; dllnum && im->dllname; ic++, im++)
|
||||
{
|
||||
idlls[ic] = dlls + ic;
|
||||
dlls[ic].name = ibuf + im->dllname;
|
||||
dlls[ic].shname = NULL;
|
||||
dlls[ic].ordinal = 0;
|
||||
dlls[ic].iat = im->iat;
|
||||
dlls[ic].lookupt = (LE32*) (ibuf + (im->oft ? im->oft : im->iat));
|
||||
dlls[ic].npos = 0;
|
||||
dlls[ic].lookupt = (LEXX*) (ibuf + (im->oft ? im->oft : im->iat));
|
||||
dlls[ic].original_position = ic;
|
||||
dlls[ic].isk32 = strcasecmp(kernel32dll,dlls[ic].name) == 0;
|
||||
|
||||
soimport += strlen(dlls[ic].name) + 1 + 4;
|
||||
|
||||
for (LE32 *tarr = dlls[ic].lookupt; *tarr; tarr++)
|
||||
for (IPTR_I(LEXX, tarr, dlls[ic].lookupt); *tarr; tarr += 1)
|
||||
{
|
||||
if (*tarr & 0x80000000)
|
||||
if (*tarr & ord_mask)
|
||||
{
|
||||
importbyordinal = true;
|
||||
soimport += 2; // ordinal num: 2 bytes
|
||||
dlls[ic].ordinal = *tarr & 0xffff;
|
||||
//if (dlls[ic].isk32)
|
||||
// kernel32ordinal = true,k32o++;
|
||||
}
|
||||
else
|
||||
else //it's an import by name
|
||||
{
|
||||
unsigned len = strlen(ibuf + *tarr + 2);
|
||||
IPTR_I(const upx_byte, n, ibuf + *tarr + 2);
|
||||
unsigned len = strlen(n);
|
||||
soimport += len + 1;
|
||||
if (dlls[ic].shname == NULL || len < strlen (dlls[ic].shname))
|
||||
dlls[ic].shname = ibuf + *tarr + 2;
|
||||
@ -831,106 +841,70 @@ unsigned PeFile::processImports() // pass 1
|
||||
}
|
||||
oimport = new upx_byte[soimport];
|
||||
memset(oimport,0,soimport);
|
||||
oimpdlls = new upx_byte[soimport];
|
||||
memset(oimpdlls,0,soimport);
|
||||
|
||||
qsort(idlls,dllnum,sizeof (udll*),udll::compare);
|
||||
|
||||
unsigned dllnamelen = sizeof (kernel32dll);
|
||||
unsigned dllnum2 = 1;
|
||||
for (ic = 0; ic < dllnum; ic++)
|
||||
if (!idlls[ic]->isk32 && (ic == 0 || strcasecmp(idlls[ic - 1]->name,idlls[ic]->name)))
|
||||
{
|
||||
dllnum2++;
|
||||
dllnamelen += strlen(idlls[ic]->name) + 1;
|
||||
}
|
||||
//fprintf(stderr,"dllnum=%d dllnum2=%d soimport=%d\n",dllnum,dllnum2,soimport); //
|
||||
|
||||
info("Processing imports: %d DLLs", dllnum);
|
||||
|
||||
// create the new import table
|
||||
im = (import_desc*) oimpdlls;
|
||||
addKernelImports();
|
||||
|
||||
LE32 *ordinals = (LE32*) (oimpdlls + (dllnum2 + 1) * sizeof(import_desc));
|
||||
LE32 *lookuptable = ordinals + 4;// + k32o + (isdll ? 0 : 1);
|
||||
upx_byte *dllnames = ((upx_byte*) lookuptable) + (dllnum2 - 1) * 8;
|
||||
upx_byte *importednames = dllnames + (dllnamelen &~ 1);
|
||||
|
||||
unsigned k32namepos = ptr_diff(dllnames,oimpdlls);
|
||||
|
||||
memcpy(importednames, llgpa, ALIGN_UP((unsigned) sizeof(llgpa), 2u));
|
||||
strcpy(dllnames,kernel32dll);
|
||||
im->dllname = k32namepos;
|
||||
im->iat = ptr_diff(ordinals,oimpdlls);
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls); // LoadLibraryW
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls) + 14; // GetProcAddressA
|
||||
*ordinals++ = ptr_diff(importednames,oimpdlls) + 14 + 18; // CacheSync
|
||||
dllnames += sizeof(kernel32dll);
|
||||
importednames += sizeof(llgpa);
|
||||
|
||||
im++;
|
||||
for (ic = 0; ic < dllnum; ic++)
|
||||
{
|
||||
if (idlls[ic]->isk32)
|
||||
{
|
||||
idlls[ic]->npos = k32namepos;
|
||||
/*
|
||||
// for kernel32.dll we need to put all the imported
|
||||
// ordinals into the output import table, as on
|
||||
// some versions of windows GetProcAddress does not resolve them
|
||||
if (idlls[ic]->ordinal)
|
||||
for (LE32 *tarr = idlls[ic]->lookupt; *tarr; tarr++)
|
||||
if (*tarr & 0x80000000)
|
||||
*ordinals++ = *tarr;
|
||||
*/
|
||||
for (LEXX *tarr = idlls[ic]->lookupt; *tarr; tarr++)
|
||||
if (*tarr & ord_mask)
|
||||
{
|
||||
ilinker->add(kernel32dll, *tarr & 0xffff);
|
||||
kernel32ordinal = true;
|
||||
}
|
||||
}
|
||||
else if (ic && strcasecmp(idlls[ic-1]->name,idlls[ic]->name) == 0)
|
||||
idlls[ic]->npos = idlls[ic-1]->npos;
|
||||
else
|
||||
{
|
||||
im->dllname = idlls[ic]->npos = ptr_diff(dllnames,oimpdlls);
|
||||
im->iat = ptr_diff(lookuptable,oimpdlls);
|
||||
|
||||
strcpy(dllnames,idlls[ic]->name);
|
||||
dllnames += strlen(idlls[ic]->name)+1;
|
||||
if (idlls[ic]->ordinal)
|
||||
*lookuptable = idlls[ic]->ordinal + 0x80000000;
|
||||
ilinker->add(idlls[ic]->name, idlls[ic]->ordinal);
|
||||
else if (idlls[ic]->shname)
|
||||
{
|
||||
if (ptr_diff(importednames,oimpdlls) & 1)
|
||||
importednames--;
|
||||
*lookuptable = ptr_diff(importednames,oimpdlls);
|
||||
importednames += 2;
|
||||
strcpy(importednames,idlls[ic]->shname);
|
||||
importednames += strlen(idlls[ic]->shname) + 1;
|
||||
}
|
||||
lookuptable += 2;
|
||||
im++;
|
||||
ilinker->add(idlls[ic]->name, idlls[ic]->shname);
|
||||
else
|
||||
throwInternalError("should not happen");
|
||||
}
|
||||
soimpdlls = ALIGN_UP(ptr_diff(importednames,oimpdlls),4);
|
||||
}
|
||||
|
||||
soimpdlls = ilinker->build();
|
||||
|
||||
Interval names(ibuf),iats(ibuf),lookups(ibuf);
|
||||
|
||||
// create the preprocessed data
|
||||
//ordinals -= k32o;
|
||||
upx_byte *ppi = oimport; // preprocessed imports
|
||||
for (ic = 0; ic < dllnum; ic++)
|
||||
{
|
||||
LE32 *tarr = idlls[ic]->lookupt;
|
||||
LEXX *tarr = idlls[ic]->lookupt;
|
||||
#if 0 && ENABLE_THIS_AND_UNCOMPRESSION_WILL_BREAK // FIXME
|
||||
if (!*tarr) // no imports from this dll
|
||||
continue;
|
||||
set_le32(ppi,idlls[ic]->npos);
|
||||
#endif
|
||||
set_le32(ppi, ilinker->getAddress(idlls[ic]->name));
|
||||
set_le32(ppi+4,idlls[ic]->iat - rvamin);
|
||||
ppi += 8;
|
||||
for (; *tarr; tarr++)
|
||||
if (*tarr & 0x80000000)
|
||||
if (*tarr & ord_mask)
|
||||
{
|
||||
/*if (idlls[ic]->isk32)
|
||||
unsigned ord = *tarr & 0xffff;
|
||||
if (idlls[ic]->isk32)
|
||||
{
|
||||
*ppi++ = 0xfe; // signed + odd parity
|
||||
set_le32(ppi,ptr_diff(ordinals,oimpdlls));
|
||||
ordinals++;
|
||||
set_le32(ppi, ilinker->getAddress(idlls[ic]->name, ord));
|
||||
ppi += 4;
|
||||
}
|
||||
else*/
|
||||
else
|
||||
{
|
||||
*ppi++ = 0xff;
|
||||
set_le16(ppi,*tarr & 0xffff);
|
||||
set_le16(ppi, ord);
|
||||
ppi += 2;
|
||||
}
|
||||
}
|
||||
@ -961,7 +935,6 @@ unsigned PeFile::processImports() // pass 1
|
||||
soimport = 0;
|
||||
|
||||
//OutputFile::dump("x0.imp", oimport, soimport);
|
||||
//OutputFile::dump("x1.imp", oimpdlls, soimpdlls);
|
||||
|
||||
unsigned ilen = 0;
|
||||
names.flatten();
|
||||
@ -981,7 +954,7 @@ unsigned PeFile::processImports() // pass 1
|
||||
for (ic = 0; ic < dllnum; ic++, im++)
|
||||
{
|
||||
memset(im,FILLVAL,sizeof(*im));
|
||||
im->dllname = ptr_diff(idlls[ic]->name,ibuf); // I only need this info
|
||||
im->dllname = ptr_diff(dlls[idlls[ic]->original_position].name,ibuf);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1002,7 +975,6 @@ 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
|
||||
@ -1816,9 +1788,10 @@ unsigned PeFile::stripDebug(unsigned overlaystart)
|
||||
// unpack
|
||||
**************************************************************************/
|
||||
|
||||
void PeFile32::rebuildRelocs(upx_byte *& extrainfo)
|
||||
void PeFile::rebuildRelocs(upx_byte *& extrainfo, unsigned bits,
|
||||
unsigned flags, upx_uint64_t imagebase)
|
||||
{
|
||||
if (!ODADDR(PEDIR_RELOC) || !ODSIZE(PEDIR_RELOC) || (oh.flags & RELOCS_STRIPPED))
|
||||
if (!ODADDR(PEDIR_RELOC) || !ODSIZE(PEDIR_RELOC) || (flags & RELOCS_STRIPPED))
|
||||
return;
|
||||
|
||||
if (ODSIZE(PEDIR_RELOC) == 8) // some tricky dlls use this
|
||||
@ -1834,7 +1807,7 @@ void PeFile32::rebuildRelocs(upx_byte *& extrainfo)
|
||||
// upx_byte *p = rdata;
|
||||
OPTR_I(upx_byte, p, rdata);
|
||||
MemBuffer wrkmem;
|
||||
unsigned relocn = unoptimizeReloc32(&rdata,obuf,&wrkmem,1);
|
||||
unsigned relocn = unoptimizeReloc(&rdata,obuf,&wrkmem,1,bits);
|
||||
unsigned r16 = 0;
|
||||
if (big & 6) // 16 bit relocations
|
||||
{
|
||||
@ -1863,8 +1836,11 @@ void PeFile32::rebuildRelocs(upx_byte *& extrainfo)
|
||||
for (unsigned ic = 0; ic < relocn; ic++)
|
||||
{
|
||||
p = obuf + get_le32(wrkmem + 4 * ic);
|
||||
set_le32(p, get_le32((unsigned char *)p) + oh.imagebase + rvamin);
|
||||
rel.add(rvamin + get_le32(wrkmem + 4 * ic),3);
|
||||
if (bits == 32)
|
||||
set_le32(p, get_le32((unsigned char *)p) + imagebase + rvamin);
|
||||
else
|
||||
set_le64(p, get_le64((unsigned char *)p) + imagebase + rvamin);
|
||||
rel.add(rvamin + get_le32(wrkmem + 4 * ic), bits == 32 ? 3 : 10);
|
||||
}
|
||||
rel.finish (oxrelocs,soxrelocs);
|
||||
|
||||
@ -1931,8 +1907,122 @@ void PeFile::rebuildResources(upx_byte *& extrainfo, unsigned lastvaddr)
|
||||
delete [] p;
|
||||
}
|
||||
|
||||
template <typename ht>
|
||||
void PeFile::unpack(OutputFile *fo, const ht &ih, ht &oh)
|
||||
template <typename LEXX, typename ord_mask_t>
|
||||
void PeFile::rebuildImports(upx_byte *& extrainfo,
|
||||
ord_mask_t ord_mask, bool set_oft)
|
||||
{
|
||||
if (ODADDR(PEDIR_IMPORT) == 0
|
||||
|| ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))
|
||||
return;
|
||||
|
||||
// const upx_byte * const idata = obuf + get_le32(extrainfo);
|
||||
OPTR_C(const upx_byte, idata, obuf + get_le32(extrainfo));
|
||||
const unsigned inamespos = get_le32(extrainfo + 4);
|
||||
extrainfo += 8;
|
||||
|
||||
unsigned sdllnames = 0;
|
||||
|
||||
// const upx_byte *import = ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr;
|
||||
// const upx_byte *p;
|
||||
IPTR_I(const upx_byte, import, ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr);
|
||||
OPTR(const upx_byte, p);
|
||||
|
||||
for (p = idata; get_le32(p) != 0; ++p)
|
||||
{
|
||||
const upx_byte *dname = get_le32(p) + import;
|
||||
ICHECK(dname, 1);
|
||||
const unsigned dlen = strlen(dname);
|
||||
ICHECK(dname, dlen + 1);
|
||||
|
||||
sdllnames += dlen + 1;
|
||||
for (p += 8; *p;)
|
||||
if (*p == 1)
|
||||
p += strlen(++p) + 1;
|
||||
else if (*p == 0xff)
|
||||
p += 3; // ordinal
|
||||
else
|
||||
p += 5;
|
||||
}
|
||||
sdllnames = ALIGN_UP(sdllnames, 2u);
|
||||
|
||||
upx_byte * const Obuf = obuf - rvamin;
|
||||
import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));
|
||||
import_desc *im = im0;
|
||||
upx_byte *dllnames = Obuf + inamespos;
|
||||
upx_byte *importednames = dllnames + sdllnames;
|
||||
upx_byte * const importednames_start = importednames;
|
||||
|
||||
for (p = idata; get_le32(p) != 0; ++p)
|
||||
{
|
||||
// restore the name of the dll
|
||||
const upx_byte *dname = get_le32(p) + import;
|
||||
ICHECK(dname, 1);
|
||||
const unsigned dlen = strlen(dname);
|
||||
ICHECK(dname, dlen + 1);
|
||||
|
||||
const unsigned iatoffs = get_le32(p + 4) + rvamin;
|
||||
if (inamespos)
|
||||
{
|
||||
// now I rebuild the dll names
|
||||
OCHECK(dllnames, dlen + 1);
|
||||
strcpy(dllnames, dname);
|
||||
im->dllname = ptr_diff(dllnames,Obuf);
|
||||
//;;;printf("\ndll: %s:",dllnames);
|
||||
dllnames += dlen + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
OCHECK(Obuf + im->dllname, dlen + 1);
|
||||
strcpy(Obuf + im->dllname, dname);
|
||||
}
|
||||
im->iat = iatoffs;
|
||||
if (set_oft)
|
||||
im->oft = iatoffs;
|
||||
|
||||
OPTR_I(LEXX, newiat, (LEXX *) (Obuf + iatoffs));
|
||||
|
||||
// restore the imported names+ordinals
|
||||
for (p += 8; *p; ++newiat)
|
||||
if (*p == 1)
|
||||
{
|
||||
const unsigned ilen = strlen(++p) + 1;
|
||||
if (inamespos)
|
||||
{
|
||||
if (ptr_diff(importednames, importednames_start) & 1)
|
||||
importednames -= 1;
|
||||
omemcpy(importednames + 2, p, ilen);
|
||||
//;;;printf(" %s",importednames+2);
|
||||
*newiat = ptr_diff(importednames, Obuf);
|
||||
importednames += 2 + ilen;
|
||||
}
|
||||
else
|
||||
{
|
||||
OCHECK(Obuf + *newiat + 2, ilen + 1);
|
||||
strcpy(Obuf + *newiat + 2, p);
|
||||
}
|
||||
p += ilen;
|
||||
}
|
||||
else if (*p == 0xff)
|
||||
{
|
||||
*newiat = get_le16(p + 1) + ord_mask;
|
||||
//;;;printf(" %x",(unsigned)*newiat);
|
||||
p += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*newiat = *(const LEXX*)(get_le32(p + 1) + import);
|
||||
assert(*newiat & ord_mask);
|
||||
p += 5;
|
||||
}
|
||||
*newiat = 0;
|
||||
im++;
|
||||
}
|
||||
//memset(idata,0,p - idata);
|
||||
}
|
||||
|
||||
template <typename ht, typename LEXX, typename ord_mask_t>
|
||||
void PeFile::unpack(OutputFile *fo, const ht &ih, ht &oh,
|
||||
ord_mask_t ord_mask, bool set_oft)
|
||||
{
|
||||
//infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), objs);
|
||||
|
||||
@ -1981,8 +2071,8 @@ void PeFile::unpack(OutputFile *fo, const ht &ih, ht &oh)
|
||||
ft.unfilter(obuf + oh.codebase - rvamin, oh.codesize);
|
||||
}
|
||||
|
||||
rebuildImports(extrainfo);
|
||||
rebuildRelocs(extrainfo);
|
||||
rebuildImports<LEXX>(extrainfo, ord_mask, set_oft);
|
||||
rebuildRelocs(extrainfo, sizeof(ih.imagebase) * 8, oh.flags, oh.imagebase);
|
||||
rebuildTls();
|
||||
rebuildExports();
|
||||
|
||||
@ -2074,7 +2164,13 @@ void PeFile32::readPeHeader()
|
||||
|
||||
void PeFile32::unpack(OutputFile *fo)
|
||||
{
|
||||
super::unpack(fo, ih, oh);
|
||||
bool set_oft = getFormat() == UPX_F_WINCE_ARM_PE;
|
||||
super::unpack<pe_header_t, LE32>(fo, ih, oh, 1U << 31, set_oft);
|
||||
}
|
||||
|
||||
unsigned PeFile32::processImports() // pass 1
|
||||
{
|
||||
return super::processImports<LE32>(1u << 31);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
22
src/pefile.h
22
src/pefile.h
@ -48,8 +48,9 @@ protected:
|
||||
virtual ~PeFile();
|
||||
virtual int getVersion() const { return 13; }
|
||||
|
||||
template <typename ht>
|
||||
void unpack(OutputFile *fo, const ht &ih, ht &oh);
|
||||
template <typename ht, typename LEXX, typename ord_mask_t>
|
||||
void unpack(OutputFile *fo, const ht &ih, ht &oh,
|
||||
ord_mask_t ord_mask, bool set_oft);
|
||||
|
||||
// unpacker capabilities
|
||||
virtual bool canUnpackVersion(int version) const
|
||||
@ -62,18 +63,25 @@ protected:
|
||||
|
||||
unsigned pe_offset;
|
||||
|
||||
virtual unsigned processImports() = 0;
|
||||
virtual void processImports(unsigned, unsigned) = 0;
|
||||
virtual void rebuildImports(upx_byte *&) = 0;
|
||||
template <typename LEXX, typename ord_mask_t>
|
||||
unsigned processImports(ord_mask_t ord_mask);
|
||||
|
||||
template <typename LEXX, typename ord_mask_t>
|
||||
void rebuildImports(upx_byte *& extrainfo,
|
||||
ord_mask_t ord_mask, bool set_oft);
|
||||
virtual void processImports(unsigned, unsigned);
|
||||
upx_byte *oimport;
|
||||
unsigned soimport;
|
||||
upx_byte *oimpdlls;
|
||||
unsigned soimpdlls;
|
||||
ImportLinker *ilinker;
|
||||
void addKernelImport(const char *, const char *);
|
||||
virtual void addKernelImports();
|
||||
|
||||
virtual void processRelocs() = 0;
|
||||
void processRelocs(Reloc *);
|
||||
virtual void rebuildRelocs(upx_byte *&) = 0;
|
||||
void rebuildRelocs(upx_byte *&, unsigned bits,
|
||||
unsigned flags, upx_uint64_t imagebase);
|
||||
upx_byte *orelocs;
|
||||
unsigned sorelocs;
|
||||
upx_byte *oxrelocs;
|
||||
@ -354,8 +362,8 @@ protected:
|
||||
|
||||
virtual void readPeHeader();
|
||||
|
||||
virtual unsigned processImports();
|
||||
virtual void processRelocs();
|
||||
virtual void rebuildRelocs(upx_byte *&);
|
||||
|
||||
__packed_struct(pe_header_t)
|
||||
// 0x0
|
||||
|
||||
Loading…
Reference in New Issue
Block a user