mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
Packer::canUnpack() now can return -1.
committer: mfx <mfx> 962126554 +0000
This commit is contained in:
parent
87a1b66847
commit
51c6566092
|
@ -63,6 +63,13 @@ void throwAlreadyPacked(const char *msg)
|
||||||
throw AlreadyPackedException(msg);
|
throw AlreadyPackedException(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void throwAlreadyPackedByUPX(const char *msg)
|
||||||
|
{
|
||||||
|
if (msg == NULL)
|
||||||
|
msg = "already packed by UPX";
|
||||||
|
throwAlreadyPacked(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// decompression
|
// decompression
|
||||||
|
@ -109,7 +116,15 @@ void throwBadLoader()
|
||||||
|
|
||||||
void throwIOException(const char *msg, int e)
|
void throwIOException(const char *msg, int e)
|
||||||
{
|
{
|
||||||
throw IOException(msg,e);
|
throw IOException(msg, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void throwEOFException(const char *msg, int e)
|
||||||
|
{
|
||||||
|
if (msg == NULL && e == 0)
|
||||||
|
msg = "premature end of file";
|
||||||
|
throw EOFException(msg, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,9 +134,9 @@ void throwIOException(const char *msg, int e)
|
||||||
|
|
||||||
const char *prettyName(const char *n)
|
const char *prettyName(const char *n)
|
||||||
{
|
{
|
||||||
while (*n >= '0' && *n <= '9') // gcc / egcs
|
while (*n >= '0' && *n <= '9') // gcc / egcs
|
||||||
n++;
|
n++;
|
||||||
if (strlen(n) > 6 && memcmp(n, "class ", 6) == 0) // Visual C++
|
if (strncmp(n, "class ", 6) == 0) // Visual C++
|
||||||
n += 6;
|
n += 6;
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,8 +192,9 @@ public:
|
||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#undef NORET
|
||||||
#if 0 && defined(__GNUC__)
|
#if 0 && defined(__GNUC__)
|
||||||
// (noreturn) is probably not the correct semantics
|
// (noreturn) is probably not the correct semantics for throwing exceptions
|
||||||
#define NORET __attribute__((noreturn))
|
#define NORET __attribute__((noreturn))
|
||||||
#else
|
#else
|
||||||
#define NORET
|
#define NORET
|
||||||
|
@ -203,6 +204,7 @@ void throwCantPack(const char *msg) NORET;
|
||||||
void throwUnknownExecutableFormat(const char *msg = 0, bool warn = false) NORET;
|
void throwUnknownExecutableFormat(const char *msg = 0, bool warn = false) NORET;
|
||||||
void throwNotCompressible(const char *msg = 0) NORET;
|
void throwNotCompressible(const char *msg = 0) NORET;
|
||||||
void throwAlreadyPacked(const char *msg = 0) NORET;
|
void throwAlreadyPacked(const char *msg = 0) NORET;
|
||||||
|
void throwAlreadyPackedByUPX(const char *msg = 0) NORET;
|
||||||
void throwCantUnpack(const char *msg) NORET;
|
void throwCantUnpack(const char *msg) NORET;
|
||||||
void throwNotPacked(const char *msg = 0) NORET;
|
void throwNotPacked(const char *msg = 0) NORET;
|
||||||
void throwFilterException() NORET;
|
void throwFilterException() NORET;
|
||||||
|
@ -211,6 +213,7 @@ void throwChecksumError() NORET;
|
||||||
void throwCompressedDataViolation() NORET;
|
void throwCompressedDataViolation() NORET;
|
||||||
void throwInternalError(const char *msg) NORET;
|
void throwInternalError(const char *msg) NORET;
|
||||||
void throwIOException(const char *msg = 0, int e = 0) NORET;
|
void throwIOException(const char *msg = 0, int e = 0) NORET;
|
||||||
|
void throwEOFException(const char *msg = 0, int e = 0) NORET;
|
||||||
|
|
||||||
#undef NORET
|
#undef NORET
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ int FileBase::readx(void *buf, int len)
|
||||||
{
|
{
|
||||||
int l = this->read(buf,len);
|
int l = this->read(buf,len);
|
||||||
if (l != len)
|
if (l != len)
|
||||||
throw EOFException();
|
throwEOFException();
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ void PackCom::pack(OutputFile *fo)
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackCom::canUnpack()
|
int PackCom::canUnpack()
|
||||||
{
|
{
|
||||||
if (!readPackHeader(128, 0))
|
if (!readPackHeader(128, 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual bool canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual const unsigned getCallTrickOffset() const { return 0x100; }
|
virtual const unsigned getCallTrickOffset() const { return 0x100; }
|
||||||
|
|
|
@ -368,13 +368,13 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackDjgpp2::canUnpack()
|
int PackDjgpp2::canUnpack()
|
||||||
{
|
{
|
||||||
if (!readFileHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
if (is_dlm(fi,coff_offset))
|
if (is_dlm(fi,coff_offset))
|
||||||
throwCantUnpack("can't handle DLM");
|
throwCantUnpack("can't handle DLM");
|
||||||
return readPackHeader(1024, coff_offset);
|
return readPackHeader(1024, coff_offset) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ public:
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual bool canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int buildLoader(const Filter *ft);
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
|
|
@ -71,7 +71,7 @@ const int *PackExe::getFilters() const
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackExe::readExeHeader()
|
bool PackExe::readFileHeader()
|
||||||
{
|
{
|
||||||
ih_exesize = ih_imagesize = ih_overlay = 0;
|
ih_exesize = ih_imagesize = ih_overlay = 0;
|
||||||
fi->readx(&ih,sizeof(ih));
|
fi->readx(&ih,sizeof(ih));
|
||||||
|
@ -95,7 +95,7 @@ bool PackExe::canPack()
|
||||||
{
|
{
|
||||||
if (fn_has_ext(fi->getName(),"sys"))
|
if (fn_has_ext(fi->getName(),"sys"))
|
||||||
return false;
|
return false;
|
||||||
if (!readExeHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
if (file_size < 1024)
|
if (file_size < 1024)
|
||||||
throwCantPack("file is too small");
|
throwCantPack("file is too small");
|
||||||
|
@ -519,9 +519,9 @@ void PackExe::pack(OutputFile *fo)
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackExe::canUnpack()
|
int PackExe::canUnpack()
|
||||||
{
|
{
|
||||||
if (!readExeHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
const off_t off = ih.headsize16*16;
|
const off_t off = ih.headsize16*16;
|
||||||
bool b = readPackHeader(128, off);
|
bool b = readPackHeader(128, off);
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual bool canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
// unpacker capabilities
|
// unpacker capabilities
|
||||||
virtual bool canUnpackVersion(int version) const
|
virtual bool canUnpackVersion(int version) const
|
||||||
|
@ -62,7 +62,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool readExeHeader(void);
|
virtual bool readFileHeader(void);
|
||||||
|
|
||||||
struct exe_header_t
|
struct exe_header_t
|
||||||
{
|
{
|
||||||
|
|
|
@ -343,7 +343,7 @@ void PackLinuxI386elf::pack(OutputFile *fo)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((off_t)total_in != file_size)
|
if ((off_t)total_in != file_size)
|
||||||
throw EOFException();
|
throwEOFException();
|
||||||
|
|
||||||
// write block end marker (uncompressed size 0)
|
// write block end marker (uncompressed size 0)
|
||||||
fo->write("\x00\x00\x00\x00", 4);
|
fo->write("\x00\x00\x00\x00", 4);
|
||||||
|
@ -492,7 +492,7 @@ void PackLinuxI386elf::unpack(OutputFile *fo)
|
||||||
|
|
||||||
// all bytes must be written
|
// all bytes must be written
|
||||||
if (total_out != orig_file_size)
|
if (total_out != orig_file_size)
|
||||||
throw EOFException();
|
throwEOFException();
|
||||||
|
|
||||||
// finally test the checksums
|
// finally test the checksums
|
||||||
if (ph.c_adler != c_adler || ph.u_adler != u_adler)
|
if (ph.c_adler != c_adler || ph.u_adler != u_adler)
|
||||||
|
|
|
@ -46,11 +46,11 @@ public:
|
||||||
virtual const char *getName() const { return "linux/elf386"; }
|
virtual const char *getName() const { return "linux/elf386"; }
|
||||||
virtual const int *getFilters() const { return NULL; }
|
virtual const int *getFilters() const { return NULL; }
|
||||||
|
|
||||||
virtual bool canPack();
|
|
||||||
virtual bool canUnpackFormat(int format) const;
|
|
||||||
virtual void pack(OutputFile *fo);
|
virtual void pack(OutputFile *fo);
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
|
virtual bool canPack();
|
||||||
|
virtual bool canUnpackFormat(int format) const;
|
||||||
virtual bool canUnpackVersion(int version) const
|
virtual bool canUnpackVersion(int version) const
|
||||||
{ return (version >= 11); }
|
{ return (version >= 11); }
|
||||||
|
|
||||||
|
|
|
@ -264,11 +264,11 @@ void PackTmt::pack(OutputFile *fo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PackTmt::canUnpack()
|
int PackTmt::canUnpack()
|
||||||
{
|
{
|
||||||
if (!PackTmt::readFileHeader())
|
if (!PackTmt::readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
return readPackHeader(512,adam_offset);
|
return readPackHeader(512,adam_offset) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual bool canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool readFileHeader();
|
bool readFileHeader();
|
||||||
|
|
|
@ -126,7 +126,7 @@ int PackTos::getLoaderSize() const
|
||||||
// util
|
// util
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackTos::readExeHeader()
|
bool PackTos::readFileHeader()
|
||||||
{
|
{
|
||||||
fi->seek(0,SEEK_SET);
|
fi->seek(0,SEEK_SET);
|
||||||
fi->readx(&ih, FH_SIZE);
|
fi->readx(&ih, FH_SIZE);
|
||||||
|
@ -138,7 +138,7 @@ bool PackTos::readExeHeader()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PackTos::checkExeHeader()
|
bool PackTos::checkFileHeader()
|
||||||
{
|
{
|
||||||
const unsigned f = ih.fh_flag;
|
const unsigned f = ih.fh_flag;
|
||||||
//printf("flags: 0x%x, text: %d, data: %d, bss: %d, sym: %d\n", f, (int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_bss, (int)ih.fh_sym);
|
//printf("flags: 0x%x, text: %d, data: %d, bss: %d, sym: %d\n", f, (int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_bss, (int)ih.fh_sym);
|
||||||
|
@ -235,7 +235,7 @@ static int check_relocs(const upx_byte *relocs, unsigned rsize, unsigned isize,
|
||||||
|
|
||||||
bool PackTos::canPack()
|
bool PackTos::canPack()
|
||||||
{
|
{
|
||||||
if (!readExeHeader())
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned char buf[512];
|
unsigned char buf[512];
|
||||||
|
@ -243,7 +243,7 @@ bool PackTos::canPack()
|
||||||
if (find_le32(buf,sizeof(buf),UPX_MAGIC_LE32))
|
if (find_le32(buf,sizeof(buf),UPX_MAGIC_LE32))
|
||||||
throwAlreadyPacked();
|
throwAlreadyPacked();
|
||||||
|
|
||||||
if (!checkExeHeader())
|
if (!checkFileHeader())
|
||||||
throwCantPack("unsupported header flags");
|
throwCantPack("unsupported header flags");
|
||||||
if (file_size < 256)
|
if (file_size < 256)
|
||||||
throwCantPack("program too small");
|
throwCantPack("program too small");
|
||||||
|
@ -253,7 +253,7 @@ bool PackTos::canPack()
|
||||||
|
|
||||||
void PackTos::fileInfo()
|
void PackTos::fileInfo()
|
||||||
{
|
{
|
||||||
if (!readExeHeader())
|
if (!readFileHeader())
|
||||||
return;
|
return;
|
||||||
con_fprintf(stdout, " text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
con_fprintf(stdout, " text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n",
|
||||||
(int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_sym, (int)ih.fh_bss, (int)ih.fh_flag);
|
(int)ih.fh_text, (int)ih.fh_data, (int)ih.fh_sym, (int)ih.fh_bss, (int)ih.fh_flag);
|
||||||
|
@ -490,17 +490,17 @@ void PackTos::pack(OutputFile *fo)
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackTos::canUnpack()
|
int PackTos::canUnpack()
|
||||||
{
|
{
|
||||||
if (!readPackHeader(512, 0))
|
if (!readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
if (!readExeHeader())
|
if (!readPackHeader(512, 0))
|
||||||
return false;
|
return false;
|
||||||
// check header as set by packer
|
// check header as set by packer
|
||||||
if ((ih.fh_text & 3) != 0 || (ih.fh_data & 3) != 0 || (ih.fh_bss & 3) != 0
|
if ((ih.fh_text & 3) != 0 || (ih.fh_data & 3) != 0 || (ih.fh_bss & 3) != 0
|
||||||
|| ih.fh_sym != 0 || ih.fh_reserved != 0 || ih.fh_reloc > 1)
|
|| ih.fh_sym != 0 || ih.fh_reserved != 0 || ih.fh_reloc > 1)
|
||||||
throwCantUnpack("file damaged");
|
throwCantUnpack("file damaged");
|
||||||
if (!checkExeHeader())
|
if (!checkFileHeader())
|
||||||
throwCantUnpack("unsupported header flags");
|
throwCantUnpack("unsupported header flags");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual bool canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
virtual void fileInfo();
|
virtual void fileInfo();
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@ protected:
|
||||||
virtual const upx_byte *getLoader() const;
|
virtual const upx_byte *getLoader() const;
|
||||||
virtual int getLoaderSize() const;
|
virtual int getLoaderSize() const;
|
||||||
|
|
||||||
bool readExeHeader();
|
bool readFileHeader();
|
||||||
bool checkExeHeader();
|
bool checkFileHeader();
|
||||||
|
|
||||||
struct tos_header_t
|
struct tos_header_t
|
||||||
{
|
{
|
||||||
|
|
|
@ -172,7 +172,7 @@ void PackUnix::pack(OutputFile *fo)
|
||||||
total_out += ph.c_len;
|
total_out += ph.c_len;
|
||||||
}
|
}
|
||||||
if ((off_t)total_in != file_size)
|
if ((off_t)total_in != file_size)
|
||||||
throw EOFException();
|
throwEOFException();
|
||||||
|
|
||||||
// write block end marker (uncompressed size 0)
|
// write block end marker (uncompressed size 0)
|
||||||
fo->write("\x00\x00\x00\x00", 4);
|
fo->write("\x00\x00\x00\x00", 4);
|
||||||
|
@ -203,7 +203,7 @@ void PackUnix::pack(OutputFile *fo)
|
||||||
// Generic Unix canUnpack().
|
// Generic Unix canUnpack().
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackUnix::canUnpack()
|
int PackUnix::canUnpack()
|
||||||
{
|
{
|
||||||
upx_byte buf[128];
|
upx_byte buf[128];
|
||||||
const int bufsize = sizeof(buf);
|
const int bufsize = sizeof(buf);
|
||||||
|
@ -310,7 +310,7 @@ void PackUnix::unpack(OutputFile *fo)
|
||||||
|
|
||||||
// all bytes must be written
|
// all bytes must be written
|
||||||
if (ph.version > 8 && total_out != orig_file_size)
|
if (ph.version > 8 && total_out != orig_file_size)
|
||||||
throw EOFException();
|
throwEOFException();
|
||||||
|
|
||||||
// finally test the checksums
|
// finally test the checksums
|
||||||
if (ph.c_adler != c_adler || ph.u_adler != u_adler)
|
if (ph.c_adler != c_adler || ph.u_adler != u_adler)
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual bool canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// called by the generic pack()
|
// called by the generic pack()
|
||||||
|
@ -175,7 +175,7 @@ public:
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual bool canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// virtual const upx_byte *getLoader() const;
|
// virtual const upx_byte *getLoader() const;
|
||||||
|
|
|
@ -137,7 +137,7 @@ void PackBvmlinuxI386::pack(OutputFile *fo)
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackBvmlinuxI386::canUnpack()
|
int PackBvmlinuxI386::canUnpack()
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,15 +56,15 @@ public:
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual bool canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
// unpacker capabilities
|
// unpacker capabilities
|
||||||
virtual bool canUnpackVersion(int version) const
|
virtual bool canUnpackVersion(int version) const
|
||||||
{
|
{ return (version == 12); }
|
||||||
return (version == 12);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual bool testUnpackVersion(int version) const;
|
||||||
|
|
||||||
unsigned pe_offset;
|
unsigned pe_offset;
|
||||||
bool isrtm;
|
bool isrtm;
|
||||||
bool readFileHeader();
|
bool readFileHeader();
|
||||||
|
|
|
@ -740,12 +740,12 @@ void PackWcle::decodeEntryTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool PackWcle::canUnpack()
|
int PackWcle::canUnpack()
|
||||||
{
|
{
|
||||||
if (!LeFile::readFileHeader())
|
if (!LeFile::readFileHeader())
|
||||||
return false;
|
return false;
|
||||||
// FIXME: 1024 could be too large for some files
|
// FIXME: 1024 could be too large for some files
|
||||||
return super::readPackHeader(1024, ih.data_pages_offset+exe_offset);
|
return readPackHeader(1024, ih.data_pages_offset+exe_offset) ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
virtual void unpack(OutputFile *fo);
|
virtual void unpack(OutputFile *fo);
|
||||||
|
|
||||||
virtual bool canPack();
|
virtual bool canPack();
|
||||||
virtual bool canUnpack();
|
virtual int canUnpack();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void handleStub(OutputFile *fo);
|
virtual void handleStub(OutputFile *fo);
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
Packer::Packer(InputFile *f) :
|
Packer::Packer(InputFile *f) :
|
||||||
fi(f), file_size(-1),
|
fi(f), file_size(-1), ph_format(-1), ph_version(-1),
|
||||||
uip(NULL), pass(0), total_passes(0), linker(NULL),
|
uip(NULL), pass(0), total_passes(0), linker(NULL),
|
||||||
last_patch(NULL), last_patch_offset(0)
|
last_patch(NULL), last_patch_offset(0)
|
||||||
{
|
{
|
||||||
|
@ -119,6 +119,24 @@ void Packer::fileInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Packer::testUnpackVersion(int version) const
|
||||||
|
{
|
||||||
|
if (version != ph_version && ph_version != -1)
|
||||||
|
throwCantUnpack("program has been modified; run a virus checker!");
|
||||||
|
if (!canUnpackVersion(version))
|
||||||
|
throwCantUnpack("I am not compatible with older versions of UPX");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Packer::testUnpackFormat(int format) const
|
||||||
|
{
|
||||||
|
if (format != ph_format && ph_format != -1)
|
||||||
|
throwCantUnpack("program has been modified; run a virus checker!");
|
||||||
|
return canUnpackFormat(format);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// compress
|
// compress
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
@ -575,8 +593,8 @@ bool Packer::readPackHeader(unsigned len, off_t seek_offset, upx_byte *buf)
|
||||||
// Some formats might be able to unpack old versions because
|
// Some formats might be able to unpack old versions because
|
||||||
// their implementation hasn't changed. Ask them.
|
// their implementation hasn't changed. Ask them.
|
||||||
if (opt->cmd != CMD_FILEINFO)
|
if (opt->cmd != CMD_FILEINFO)
|
||||||
if (!canUnpackVersion(ph.version))
|
if (!testUnpackVersion(ph.version))
|
||||||
throwCantUnpack("I am not compatible with older versions of UPX");
|
return false;
|
||||||
|
|
||||||
if (ph.c_len >= ph.u_len || (off_t)ph.c_len >= file_size
|
if (ph.c_len >= ph.u_len || (off_t)ph.c_len >= file_size
|
||||||
|| ph.version <= 0 || ph.version >= 0xff)
|
|| ph.version <= 0 || ph.version >= 0xff)
|
||||||
|
@ -596,7 +614,7 @@ bool Packer::readPackHeader(unsigned len, off_t seek_offset, upx_byte *buf)
|
||||||
throwCantUnpack("unknown compression method");
|
throwCantUnpack("unknown compression method");
|
||||||
|
|
||||||
// Some formats might be able to unpack "subformats". Ask them.
|
// Some formats might be able to unpack "subformats". Ask them.
|
||||||
if (!canUnpackFormat(ph.format))
|
if (!testUnpackFormat(ph.format))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
17
src/packer.h
17
src/packer.h
|
@ -119,6 +119,11 @@ public:
|
||||||
virtual bool canUnpackFormat(int format) const
|
virtual bool canUnpackFormat(int format) const
|
||||||
{ return (format == getFormat()); }
|
{ return (format == getFormat()); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// unpacker tests - these may throw exceptions
|
||||||
|
virtual bool testUnpackVersion(int version) const;
|
||||||
|
virtual bool testUnpackFormat(int format) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void pack(OutputFile *fo) = 0;
|
virtual void pack(OutputFile *fo) = 0;
|
||||||
virtual void unpack(OutputFile *fo) = 0;
|
virtual void unpack(OutputFile *fo) = 0;
|
||||||
|
@ -127,10 +132,14 @@ protected:
|
||||||
virtual void fileInfo();
|
virtual void fileInfo();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// canPack() should throw a cantPackException eplaining why it
|
||||||
|
// cannot pack a recognized format.
|
||||||
|
// canUnpack() can return -1 meaning "format recognized, but file
|
||||||
|
// is definitely not packed" (see packmast.cpp).
|
||||||
virtual bool canPack() = 0;
|
virtual bool canPack() = 0;
|
||||||
virtual bool canUnpack() = 0;
|
virtual int canUnpack() = 0;
|
||||||
virtual bool canTest() { return canUnpack(); }
|
virtual int canTest() { return canUnpack(); }
|
||||||
virtual bool canList() { return canUnpack(); }
|
virtual int canList() { return canUnpack(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// main compression drivers
|
// main compression drivers
|
||||||
|
@ -215,6 +224,8 @@ protected:
|
||||||
InputFile *fi;
|
InputFile *fi;
|
||||||
off_t file_size; // will get set by constructor
|
off_t file_size; // will get set by constructor
|
||||||
PackHeader ph; // must be filled by canUnpack()
|
PackHeader ph; // must be filled by canUnpack()
|
||||||
|
int ph_format;
|
||||||
|
int ph_version;
|
||||||
|
|
||||||
// compression buffers
|
// compression buffers
|
||||||
MemBuffer ibuf; // input
|
MemBuffer ibuf; // input
|
||||||
|
|
|
@ -112,11 +112,17 @@ static Packer* try_unpack(Packer *p, InputFile *f)
|
||||||
try {
|
try {
|
||||||
p->initPackHeader();
|
p->initPackHeader();
|
||||||
f->seek(0,SEEK_SET);
|
f->seek(0,SEEK_SET);
|
||||||
if (p->canUnpack())
|
int r = p->canUnpack();
|
||||||
|
if (r > 0)
|
||||||
{
|
{
|
||||||
f->seek(0,SEEK_SET);
|
f->seek(0,SEEK_SET);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
// FIXME - could stop testing all other unpackers at this time
|
||||||
|
// see canUnpack() in packer.h
|
||||||
|
}
|
||||||
} catch (IOException&) {
|
} catch (IOException&) {
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
delete p;
|
delete p;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user