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:
parent
8e52894763
commit
e49b65723f
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -50,7 +50,6 @@ public:
|
|||
virtual void pack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual void buildLoader(const Filter *ft);
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ public:
|
|||
virtual void pack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual int readFileHeader();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user