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

pe: canUnpack moved to PeFile

This commit is contained in:
László Molnár 2014-02-19 23:27:41 +01:00
parent 8e52894763
commit e49b65723f
7 changed files with 81 additions and 142 deletions

View File

@ -697,73 +697,6 @@ void PackArmPe::pack(OutputFile *fo)
throwNotCompressible();
}
/*************************************************************************
// unpack
**************************************************************************/
int PackArmPe::canUnpack()
{
if (!readFileHeader() || (ih.cpu != 0x1c0 && ih.cpu != 0x1c2))
return false;
unsigned objs = ih.objects;
isection = new pe_section_t[objs];
fi->seek(pe_offset+sizeof(ih),SEEK_SET);
fi->readx(isection,sizeof(pe_section_t)*objs);
if (ih.objects < 3)
return -1;
bool is_packed = ((ih.objects == 3 || ih.objects == 4) &&
(IDSIZE(15) || ih.entry > isection[1].vaddr));
bool found_ph = false;
if (memcmp(isection[0].name,"UPX",3) == 0)
{
// current version
fi->seek(isection[1].rawdataptr - 64, SEEK_SET);
found_ph = readPackHeader(1024);
if (!found_ph)
{
// old versions
fi->seek(isection[2].rawdataptr, SEEK_SET);
found_ph = readPackHeader(1024);
}
}
if (is_packed && found_ph)
return true;
if (!is_packed && !found_ph)
return -1;
if (is_packed && ih.entry < isection[2].vaddr)
{
unsigned char buf[256];
bool x = false;
memset(buf, 0, sizeof(buf));
try {
fi->seek(ih.entry - isection[1].vaddr + isection[1].rawdataptr, SEEK_SET);
fi->read(buf, sizeof(buf));
// FIXME this is for x86
static const unsigned char magic[] = "\x8b\x1e\x83\xee\xfc\x11\xdb";
// mov ebx, [esi]; sub esi, -4; adc ebx,ebx
int offset = find(buf, sizeof(buf), magic, 7);
if (offset >= 0 && find(buf + offset + 1, sizeof(buf) - offset - 1, magic, 7) >= 0)
x = true;
} catch (...) {
//x = true;
}
if (x)
throwCantUnpack("file is modified/hacked/protected; take care!!!");
else
throwCantUnpack("file is possibly modified/hacked/protected; take care!");
return false; // not reached
}
// FIXME: what should we say here ?
//throwCantUnpack("file is possibly modified/hacked/protected; take care!");
return false;
}
/*
vi:ts=4:et
*/

View File

@ -50,7 +50,6 @@ public:
virtual void pack(OutputFile *fo);
virtual bool canPack();
virtual int canUnpack();
protected:
virtual void buildLoader(const Filter *ft);

View File

@ -858,72 +858,6 @@ void PackW32Pe::pack(OutputFile *fo)
throwNotCompressible();
}
/*************************************************************************
// unpack
**************************************************************************/
int PackW32Pe::canUnpack()
{
if (!readFileHeader() || ih.cpu < 0x14c || ih.cpu > 0x150)
return false;
unsigned objs = ih.objects;
isection = new pe_section_t[objs];
fi->seek(pe_offset+sizeof(ih),SEEK_SET);
fi->readx(isection,sizeof(pe_section_t)*objs);
if (ih.objects < 3)
return -1;
bool is_packed = (ih.objects == 3 &&
(IDSIZE(15) || ih.entry > isection[1].vaddr));
bool found_ph = false;
if (memcmp(isection[0].name,"UPX",3) == 0)
{
// current version
fi->seek(isection[1].rawdataptr - 64, SEEK_SET);
found_ph = readPackHeader(1024);
if (!found_ph)
{
// old versions
fi->seek(isection[2].rawdataptr, SEEK_SET);
found_ph = readPackHeader(1024);
}
}
if (is_packed && found_ph)
return true;
if (!is_packed && !found_ph)
return -1;
if (is_packed && ih.entry < isection[2].vaddr)
{
unsigned char buf[256];
bool x = false;
memset(buf, 0, sizeof(buf));
try {
fi->seek(ih.entry - isection[1].vaddr + isection[1].rawdataptr, SEEK_SET);
fi->read(buf, sizeof(buf));
static const unsigned char magic[] = "\x8b\x1e\x83\xee\xfc\x11\xdb";
// mov ebx, [esi]; sub esi, -4; adc ebx,ebx
int offset = find(buf, sizeof(buf), magic, 7);
if (offset >= 0 && find(buf + offset + 1, sizeof(buf) - offset - 1, magic, 7) >= 0)
x = true;
} catch (...) {
//x = true;
}
if (x)
throwCantUnpack("file is modified/hacked/protected; take care!!!");
else
throwCantUnpack("file is possibly modified/hacked/protected; take care!");
return false; // not reached
}
// FIXME: what should we say here ?
//throwCantUnpack("file is possibly modified/hacked/protected; take care!");
return false;
}
/*
extra info added to help uncompression:

View File

@ -50,7 +50,6 @@ public:
virtual void pack(OutputFile *fo);
virtual bool canPack();
virtual int canUnpack();
protected:
virtual int readFileHeader();

View File

@ -123,8 +123,6 @@ static void xcheck(size_t poff, size_t plen, const void *b, size_t blen)
PackW64Pep::PackW64Pep(InputFile *f) : super(f)
{
oloadconf = NULL;
soloadconf = 0;
isrtm = false;
use_dep_hack = true;
use_clear_dirty_stack = true;
@ -133,10 +131,7 @@ PackW64Pep::PackW64Pep(InputFile *f) : super(f)
PackW64Pep::~PackW64Pep()
{
oimpdlls = NULL; // this is now a pointer to ImportLinker output
delete [] oloadconf;
}
{}
const int *PackW64Pep::getCompressionMethods(int method, int level) const

View File

@ -147,11 +147,12 @@ PeFile::~PeFile()
delete [] isection;
delete [] orelocs;
delete [] oimport;
delete [] oimpdlls;
oimpdlls = NULL;
delete [] oexport;
delete [] otls;
delete [] oresources;
delete [] oxrelocs;
delete [] oloadconf;
//delete res;
}
@ -2243,6 +2244,74 @@ void PeFile::unpack(OutputFile *fo, const ht &ih, ht &oh,
ibuf.dealloc();
}
int PeFile::canUnpack0(unsigned max_sections, LE16 &ih_objects,
LE32 &ih_entry, unsigned ihsize)
{
if (!canPack())
return false;
unsigned objs = ih_objects;
isection = new pe_section_t[objs];
fi->seek(pe_offset + ihsize, SEEK_SET);
fi->readx(isection,sizeof(pe_section_t)*objs);
if (ih_objects < 3)
return -1;
bool is_packed = ((ih_objects == 3 || ih_objects == max_sections) &&
(IDSIZE(15) || ih_entry > isection[1].vaddr));
bool found_ph = false;
if (memcmp(isection[0].name,"UPX",3) == 0)
{
// current version
fi->seek(isection[1].rawdataptr - 64, SEEK_SET);
found_ph = readPackHeader(1024);
if (!found_ph)
{
// old versions
fi->seek(isection[2].rawdataptr, SEEK_SET);
found_ph = readPackHeader(1024);
}
}
if (is_packed && found_ph)
return true;
if (!is_packed && !found_ph)
return -1;
if (is_packed && ih_entry < isection[2].vaddr)
{
unsigned char buf[256];
bool x = false;
memset(buf, 0, sizeof(buf));
try {
fi->seek(ih_entry - isection[1].vaddr + isection[1].rawdataptr, SEEK_SET);
fi->read(buf, sizeof(buf));
// FIXME this is for x86
static const unsigned char magic[] = "\x8b\x1e\x83\xee\xfc\x11\xdb";
// mov ebx, [esi]; sub esi, -4; adc ebx,ebx
int offset = find(buf, sizeof(buf), magic, 7);
if (offset >= 0 && find(buf + offset + 1, sizeof(buf) - offset - 1, magic, 7) >= 0)
x = true;
} catch (...) {
//x = true;
}
if (x)
throwCantUnpack("file is modified/hacked/protected; take care!!!");
else
throwCantUnpack("file is possibly modified/hacked/protected; take care!");
return false; // not reached
}
// FIXME: what should we say here ?
//throwCantUnpack("file is possibly modified/hacked/protected; take care!");
return false;
}
/*************************************************************************
// PeFile32
**************************************************************************/
PeFile32::PeFile32(InputFile *f) : super(f)
{
COMPILE_TIME_ASSERT(sizeof(pe_header_t) == 248)
@ -2271,6 +2340,12 @@ void PeFile32::unpack(OutputFile *fo)
super::unpack<pe_header_t, LE32>(fo, ih, oh, 1U << 31, set_oft);
}
int PeFile32::canUnpack()
{
return canUnpack0(getFormat() == UPX_F_WINCE_ARM_PE ? 4 : 3,
ih.objects, ih.entry, sizeof(ih));
}
unsigned PeFile32::processImports() // pass 1
{
return super::processImports<LE32>(1u << 31);

View File

@ -56,6 +56,9 @@ protected:
virtual bool canUnpackVersion(int version) const
{ return (version >= 12 && version <= 13); }
int canUnpack0(unsigned max_sections, LE16 &ih_objects,
LE32 &ih_entry, unsigned ihsize);
protected:
virtual int readFileHeader();
virtual bool testUnpackVersion(int version) const;
@ -374,6 +377,7 @@ protected:
PeFile32(InputFile *f);
virtual ~PeFile32();
virtual void unpack(OutputFile *fo);
virtual int canUnpack();
virtual void readPeHeader();