pepfile.* disabled; PeFile64 class introduced

This commit is contained in:
László Molnár
2014-02-20 00:10:18 +01:00
parent e49b65723f
commit 18e55061e1
7 changed files with 263 additions and 924 deletions
+189 -22
View File
@@ -142,21 +142,6 @@ PeFile::PeFile(InputFile *f) : super(f)
}
PeFile::~PeFile()
{
delete [] isection;
delete [] orelocs;
delete [] oimport;
oimpdlls = NULL;
delete [] oexport;
delete [] otls;
delete [] oresources;
delete [] oxrelocs;
delete [] oloadconf;
//delete res;
}
bool PeFile::testUnpackVersion(int version) const
{
if (version != ph_version && ph_version != -1)
@@ -478,6 +463,107 @@ void PeFile32::processRelocs() // pass1
info("Relocations: original size: %u bytes, preprocessed size: %u bytes",(unsigned) IDSIZE(PEDIR_RELOC),sorelocs);
}
void PeFile64::processRelocs() // pass1
{
big_relocs = 0;
Reloc rel(ibuf + IDADDR(PEDIR_RELOC),IDSIZE(PEDIR_RELOC));
const unsigned *counts = rel.getcounts();
unsigned rnum = 0;
unsigned ic;
for (ic = 1; ic < 16; ic++)
rnum += counts[ic];
if ((opt->win32_pe.strip_relocs && !isdll) || rnum == 0)
{
if (IDSIZE(PEDIR_RELOC))
ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL);
orelocs = new upx_byte [1];
sorelocs = 0;
return;
}
for (ic = 15; ic; ic--)
if (ic != 10 && counts[ic])
infoWarning("skipping unsupported relocation type %d (%d)",ic,counts[ic]);
LE32 *fix[16];
for (ic = 15; ic; ic--)
fix[ic] = new LE32 [counts[ic]];
unsigned xcounts[16];
memset(xcounts, 0, sizeof(xcounts));
// prepare sorting
unsigned pos,type;
while (rel.next(pos,type))
{
// FIXME add check for relocations which try to modify the
// PE header or other relocation records
if (pos >= ih.imagesize)
continue; // skip out-of-bounds record
if (type < 16)
fix[type][xcounts[type]++] = pos - rvamin;
}
// remove duplicated records
for (ic = 1; ic <= 15; ic++)
{
qsort(fix[ic], xcounts[ic], 4, le32_compare);
unsigned prev = ~0;
unsigned jc = 0;
for (unsigned kc = 0; kc < xcounts[ic]; kc++)
if (fix[ic][kc] != prev)
prev = fix[ic][jc++] = fix[ic][kc];
//printf("xcounts[%u] %u->%u\n", ic, xcounts[ic], jc);
xcounts[ic] = jc;
}
// preprocess "type 10" relocation records
for (ic = 0; ic < xcounts[10]; ic++)
{
pos = fix[10][ic] + rvamin;
set_le64(ibuf + pos, get_le64(ibuf + pos) - ih.imagebase - rvamin);
}
ibuf.fill(IDADDR(PEDIR_RELOC), IDSIZE(PEDIR_RELOC), FILLVAL);
orelocs = new upx_byte [rnum * 4 + 1024]; // 1024 - safety
sorelocs = ptr_diff(optimizeReloc64((upx_byte*) fix[10], xcounts[10],
orelocs, ibuf + rvamin,1, &big_relocs),
orelocs);
for (ic = 15; ic; ic--)
delete [] fix[ic];
#if 0
// Malware that hides behind UPX often has PE header info that is
// deliberately corrupt. Sometimes it is even tuned to cause us trouble!
// Use an extra check to avoid AccessViolation (SIGSEGV) when appending
// the relocs into one array.
if ((rnum * 4 + 1024) < (sorelocs + 4*(2 + xcounts[2] + xcounts[1])))
throwCantUnpack("Invalid relocs");
// append relocs type "LOW" then "HIGH"
for (ic = 2; ic ; ic--)
{
memcpy(orelocs + sorelocs,fix[ic],4 * xcounts[ic]);
sorelocs += 4 * xcounts[ic];
delete [] fix[ic];
set_le32(orelocs + sorelocs,0);
if (xcounts[ic])
{
sorelocs += 4;
big_relocs |= 2 * ic;
}
}
#endif
info("Relocations: original size: %u bytes, preprocessed size: %u bytes",(unsigned) IDSIZE(PEDIR_RELOC),sorelocs);
}
/*************************************************************************
// import handling
**************************************************************************/
@@ -850,6 +936,7 @@ unsigned PeFile::processImports(ord_mask_t ord_mask) // pass 1
info("Processing imports: %d DLLs", dllnum);
ilinker = new ImportLinker(sizeof(LEXX));
// create the new import table
addKernelImports();
@@ -1152,6 +1239,23 @@ struct PeFile::tls_traits<LE32>
static const unsigned reloc_type = 3;
};
template <>
struct PeFile::tls_traits<LE64>
{
__packed_struct(tls)
LE64 datastart; // VA tls init data start
LE64 dataend; // VA tls init data end
LE64 tlsindex; // VA tls index
LE64 callbacks; // VA tls callbacks
char _[8]; // zero init, characteristics
__packed_struct_end()
static const unsigned sotls = 40;
static const unsigned cb_size = 8;
typedef upx_uint64_t cb_value_t;
static const unsigned reloc_type = 10;
};
template <typename LEXX>
void PeFile::processTls1(Interval *iv,
typename tls_traits<LEXX>::cb_value_t imagebase,
@@ -2101,8 +2205,8 @@ void PeFile::rebuildImports(upx_byte *& extrainfo,
}
else
{
OCHECK(Obuf + *newiat + 2, ilen + 1);
strcpy(Obuf + *newiat + 2, p);
OCHECK(Obuf + (*newiat + 2), ilen + 1);
strcpy(Obuf + (*newiat + 2), p);
}
p += ilen;
}
@@ -2307,6 +2411,26 @@ int PeFile::canUnpack0(unsigned max_sections, LE16 &ih_objects,
return false;
}
upx_uint64_t PeFile::ilinkerGetAddress(const char *d, const char *n) const
{
return ilinker->getAddress(d, n);
}
PeFile::~PeFile()
{
delete [] isection;
delete [] orelocs;
delete [] oimport;
oimpdlls = NULL;
delete [] oexport;
delete [] otls;
delete [] oresources;
delete [] oxrelocs;
delete [] oloadconf;
delete ilinker;
//delete res;
}
/*************************************************************************
// PeFile32
@@ -2319,14 +2443,10 @@ PeFile32::PeFile32(InputFile *f) : super(f)
iddirs = ih.ddirs;
oddirs = oh.ddirs;
ilinker = new ImportLinker(4);
}
PeFile32::~PeFile32()
{
delete ilinker;
}
{}
void PeFile32::readPeHeader()
{
@@ -2361,6 +2481,53 @@ void PeFile32::processTls(Reloc *r, const Interval *iv, unsigned a)
super::processTls2<LE32>(r, iv, a, ih.imagebase);
}
/*************************************************************************
// PeFile64
**************************************************************************/
PeFile64::PeFile64(InputFile *f) : super(f)
{
COMPILE_TIME_ASSERT(sizeof(pe_header_t) == 264)
COMPILE_TIME_ASSERT_ALIGNED1(pe_header_t)
iddirs = ih.ddirs;
oddirs = oh.ddirs;
}
PeFile64::~PeFile64()
{}
void PeFile64::readPeHeader()
{
fi->readx(&ih,sizeof(ih));
isdll = ((ih.flags & DLL_FLAG) != 0);
}
void PeFile64::unpack(OutputFile *fo)
{
super::unpack<pe_header_t, LE64>(fo, ih, oh, 1ULL << 63, false);
}
int PeFile64::canUnpack()
{
return canUnpack0(3, ih.objects, ih.entry, sizeof(ih));
}
unsigned PeFile64::processImports() // pass 1
{
return super::processImports<LE64>(1ULL << 63);
}
void PeFile64::processTls(Interval *iv)
{
super::processTls1<LE64>(iv, ih.imagebase, ih.imagesize);
}
void PeFile64::processTls(Reloc *r, const Interval *iv, unsigned a)
{
super::processTls2<LE64>(r, iv, a, ih.imagebase);
}
/*
extra info added to help uncompression: