mirror of
https://github.com/upx/upx
synced 2025-09-28 19:06:07 +08:00
Rewrote PackHeader handling. In particuliar, Packer::putPackHeader()
was renamed to patchPackHeader(), and it is now under control of the usual checkPatch() patch-order. committer: mfx <mfx> 976601615 +0000
This commit is contained in:
parent
a8eac4f2f8
commit
c6481575f9
|
@ -17,7 +17,7 @@ ifeq ($(strip $(UCLDIR)),)
|
|||
UCLDIR = $(HOME)/local/src/ucl-0.92
|
||||
endif
|
||||
|
||||
DEBUG = 0
|
||||
DEBUG = 1
|
||||
|
||||
|
||||
# -------------------------------------------------------
|
||||
|
@ -172,7 +172,7 @@ ifeq (1,2) # checkergcc
|
|||
else
|
||||
ifeq ($(DEBUG),1)
|
||||
##CFLAGS += -O0 -gstabs+3
|
||||
CFLAGS += -O0 -gstabs+3
|
||||
CFLAGS += -O0 -gdwarf-2
|
||||
else
|
||||
##LDFLAGS += -static
|
||||
STUBEDIT_EXE = objcopy -S -R .comment -R .note $@ && perl $(srcdir)/stub/scripts/brandelf.pl $@ && chmod 755 $@
|
||||
|
|
|
@ -78,7 +78,7 @@ bool PackCom::canPack()
|
|||
return false;
|
||||
if (!fn_has_ext(fi->getName(),"com"))
|
||||
return false;
|
||||
if (find_le32(buf,128,UPX_MAGIC_LE32))
|
||||
if (find_le32(buf,128,UPX_MAGIC_LE32) >= 0)
|
||||
throwAlreadyPacked();
|
||||
if (file_size < 1024)
|
||||
throwCantPack("file is too small");
|
||||
|
@ -111,6 +111,9 @@ void PackCom::patchLoader(OutputFile *fo,
|
|||
assert(calls > 0);
|
||||
patch_le16(loader,lsize,"CT",calls);
|
||||
}
|
||||
|
||||
patchPackHeader(loader,e_len);
|
||||
|
||||
// NOTE: Depends on: decompr_start == cutpoint+1 !!!
|
||||
patch_le16(loader,e_len,"JM",upper_end - 0xff - d_len - getLoaderSection("UPX1HEAD"));
|
||||
loader[getLoaderSection("COMSUBSI") - 1] = (upx_byte) -e_len;
|
||||
|
@ -212,7 +215,6 @@ void PackCom::pack(OutputFile *fo)
|
|||
const int lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader,getLoader(),lsize);
|
||||
putPackHeader(loader,lsize);
|
||||
|
||||
const unsigned calls = ft.id % 3 ? ft.lastcall - 2 * ft.calls : ft.calls;
|
||||
patchLoader(fo, loader, lsize, calls, overlapoh);
|
||||
|
|
|
@ -327,7 +327,7 @@ void PackDjgpp2::pack(OutputFile *fo)
|
|||
memcpy(loader,getLoader(),lsize);
|
||||
|
||||
// patch loader
|
||||
putPackHeader(loader,lsize);
|
||||
patchPackHeader(loader,lsize);
|
||||
patch_le32(loader,lsize,"ENTR",coff_hdr.a_entry);
|
||||
if (ft.id)
|
||||
{
|
||||
|
|
|
@ -229,14 +229,7 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||
set_le16 (crel_save,ones);
|
||||
set_le16 (crel_save+2,seg_high);
|
||||
|
||||
#if 0 // def TESTING
|
||||
//if (opt->debug >= 3)
|
||||
{
|
||||
FILE *f1=fopen ("x.rel","wb");
|
||||
fwrite (crel_save,crel-crel_save,1,f1);
|
||||
fclose (f1);
|
||||
}
|
||||
#endif
|
||||
//OutputFile::dump("x.rel", crel_save, crel - crel_save);
|
||||
return crel - crel_save;
|
||||
}
|
||||
|
||||
|
@ -250,7 +243,7 @@ void PackExe::pack(OutputFile *fo)
|
|||
unsigned ic;
|
||||
unsigned char flag = 0;
|
||||
|
||||
char extra_info[32];
|
||||
unsigned char extra_info[32];
|
||||
unsigned eisize = 0;
|
||||
|
||||
//
|
||||
|
@ -271,7 +264,7 @@ void PackExe::pack(OutputFile *fo)
|
|||
fi->seek(ih.headsize16*16,SEEK_SET);
|
||||
fi->readx(ibuf,imagesize);
|
||||
|
||||
if (find_le32(ibuf,imagesize < 127 ? imagesize : 127, UPX_MAGIC_LE32))
|
||||
if (find_le32(ibuf, UPX_MAX(imagesize, 127u), UPX_MAGIC_LE32) >= 0)
|
||||
throwAlreadyPacked();
|
||||
|
||||
// relocations
|
||||
|
@ -420,7 +413,6 @@ void PackExe::pack(OutputFile *fo)
|
|||
//OutputFile::dump("xxloader.dat", loader, lsize);
|
||||
|
||||
// patch loader
|
||||
putPackHeader(loader,lsize);
|
||||
const unsigned e_len = getLoaderSection("EXECUTPO");
|
||||
const unsigned d_len = lsize - e_len;
|
||||
assert((e_len&15) == 0);
|
||||
|
@ -452,21 +444,25 @@ void PackExe::pack(OutputFile *fo)
|
|||
flag |= MAXMEM;
|
||||
}
|
||||
|
||||
putPackHeader(loader,lsize);
|
||||
// upx_bytep p = find_le32(loader,lsize,get_le32("IPCS"));
|
||||
upx_bytep p = NULL;
|
||||
if (p == NULL)
|
||||
throwBadLoader();
|
||||
if (flag & USEJUMP)
|
||||
{
|
||||
memcpy(p,&ih.ip,4);
|
||||
// I use a relocation entry to set the original cs
|
||||
unsigned n = find_le32(loader,lsize,get_le32("IPCS"));
|
||||
patch_le32(loader,lsize,get_le32("IPCS"), ih.cs*0x10000 + ih.ip);
|
||||
n += packedsize + 2;
|
||||
oh.relocs = 1;
|
||||
oh.firstreloc = (n&0xf) + ((n>>4)<<16);
|
||||
}
|
||||
else
|
||||
{
|
||||
patch_le16(loader,lsize,"IP",ih.ip);
|
||||
if (ih.cs)
|
||||
patch_le16(loader,lsize,"CS",ih.cs);
|
||||
oh.relocs = 0;
|
||||
oh.firstreloc = ih.cs*0x10000 + ih.ip;
|
||||
}
|
||||
oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
||||
|
||||
if (flag & SP)
|
||||
patch_le16(loader,lsize,"SP",ih.sp);
|
||||
if (flag & SS)
|
||||
|
@ -474,6 +470,8 @@ void PackExe::pack(OutputFile *fo)
|
|||
if (relocsize)
|
||||
patch_le16(loader,lsize,"RS",(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? 0 : MAXRELOCS) - relocsize);
|
||||
|
||||
patchPackHeader(loader,e_len);
|
||||
|
||||
patch_le16(loader,e_len,"BX",0x800F + 0x10*((packedsize&15)+1) - 0x10);
|
||||
patch_le16(loader,e_len,"BP",(packedsize&15)+1);
|
||||
|
||||
|
@ -485,13 +483,6 @@ void PackExe::pack(OutputFile *fo)
|
|||
// finish --stub support
|
||||
//if (ih.relocoffs >= 0x40 && memcmp(&ih.relocoffs,">TIPPACH",8))
|
||||
// throwCantPack("FIXME");
|
||||
// I use a relocation entry to set the original cs
|
||||
oh.relocs = (flag & USEJUMP) ? 1 : 0;
|
||||
oh.relocoffs = (char*)(&oh.firstreloc)-(char*)&oh;
|
||||
oh.firstreloc = (p-loader) + packedsize + 2;
|
||||
oh.firstreloc = (oh.firstreloc&0xf)+((oh.firstreloc>>4)<<16);
|
||||
if (!(flag & USEJUMP))
|
||||
oh.firstreloc = ih.cs*0x10000 + ih.ip;
|
||||
|
||||
extra_info[eisize++] = flag;
|
||||
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
||||
|
@ -510,6 +501,7 @@ void PackExe::pack(OutputFile *fo)
|
|||
fo->write(obuf,packedsize);
|
||||
fo->write(loader+e_len,d_len); // decompressor
|
||||
fo->write(extra_info,eisize);
|
||||
assert(eisize <= 9);
|
||||
#if 0
|
||||
printf("%-13s: program hdr : %8ld bytes\n", getName(), (long) sizeof(oh));
|
||||
printf("%-13s: entry : %8ld bytes\n", getName(), (long) e_len);
|
||||
|
|
|
@ -351,7 +351,7 @@ void PackLinuxI386elf::pack(OutputFile *fo)
|
|||
// write header
|
||||
const int hsize = ph.getPackHeaderSize();
|
||||
set_le32(obuf, ph.magic); // note: always le32
|
||||
putPackHeader(obuf, hsize);
|
||||
patchPackHeader(obuf, hsize);
|
||||
fo->write(obuf, hsize);
|
||||
|
||||
// write overlay offset (needed for decompression)
|
||||
|
|
|
@ -50,7 +50,7 @@ bool PackSys::canPack()
|
|||
return false;
|
||||
if (!fn_has_ext(fi->getName(),"sys"))
|
||||
return false;
|
||||
if (find_le32(buf,128,UPX_MAGIC_LE32))
|
||||
if (find_le32(buf,128,UPX_MAGIC_LE32) >= 0)
|
||||
throwAlreadyPacked();
|
||||
if (file_size < 1024)
|
||||
throwCantPack("file is too small");
|
||||
|
|
|
@ -152,7 +152,7 @@ void PackTmt::pack(OutputFile *fo)
|
|||
fi->readx(wrkmem+4,rsize);
|
||||
const unsigned overlay = file_size - fi->tell();
|
||||
|
||||
if (find_le32(ibuf,128,get_le32("UPX ")))
|
||||
if (find_le32(ibuf,128,get_le32("UPX ")) >= 0)
|
||||
throwAlreadyPacked();
|
||||
if (rsize == 0)
|
||||
throwCantPack("file is already compressed with another packer");
|
||||
|
@ -232,13 +232,15 @@ void PackTmt::pack(OutputFile *fo)
|
|||
patch_le32(loader,lsize,"TEXL",(ft.id & 0xf) % 3 == 0 ? ft.calls :
|
||||
ft.lastcall - ft.calls * 4);
|
||||
}
|
||||
|
||||
patchPackHeader(loader,e_len);
|
||||
|
||||
const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD"));
|
||||
patch_le32(loader,e_len,"JMPD",ph.u_len+overlapoh-jmp_pos-4);
|
||||
|
||||
patch_le32(loader,e_len,"ECX0",ph.c_len+d_len);
|
||||
patch_le32(loader,e_len,"EDI0",ph.u_len+overlapoh+d_len-1);
|
||||
patch_le32(loader,e_len,"ESI0",ph.c_len+e_len+d_len-1);
|
||||
putPackHeader(loader,e_len);
|
||||
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x clen=%x \n\n",
|
||||
// e_len,d_len,copy_len,copy_to,overlapoh,jmp_pos,ph.u_len,ph.c_len);
|
||||
|
||||
|
|
|
@ -295,7 +295,7 @@ bool PackTos::canPack()
|
|||
|
||||
unsigned char buf[512];
|
||||
fi->readx(buf,sizeof(buf));
|
||||
if (find_le32(buf,sizeof(buf),UPX_MAGIC_LE32))
|
||||
if (find_le32(buf,sizeof(buf),UPX_MAGIC_LE32) >= 0)
|
||||
throwAlreadyPacked();
|
||||
|
||||
if (!checkFileHeader())
|
||||
|
@ -467,6 +467,7 @@ void PackTos::pack(OutputFile *fo)
|
|||
memcpy(loader,getLoader(),o_text);
|
||||
|
||||
// patch loader
|
||||
patchPackHeader(loader,o_text);
|
||||
if (!opt->small)
|
||||
patchVersion(loader,o_text);
|
||||
// patch "subq.l #1,d0" or "subq.w #1,d0" - see "up41" below
|
||||
|
@ -494,8 +495,6 @@ void PackTos::pack(OutputFile *fo)
|
|||
patch_be32(loader,o_text,"up12",i_data); // p_dlen
|
||||
patch_be32(loader,o_text,"up11",i_text); // p_tlen
|
||||
|
||||
putPackHeader(loader,o_text);
|
||||
|
||||
// patch decompressor
|
||||
upx_byte *p = obuf + d_off;
|
||||
// patch "moveq.l #1,d3" or "jmp (a5)"
|
||||
|
|
|
@ -69,7 +69,7 @@ bool PackUnix::canPack()
|
|||
unsigned char buf[256];
|
||||
fi->seek(-(long)sizeof(buf), SEEK_END);
|
||||
fi->readx(buf,sizeof(buf));
|
||||
if (find_le32(buf,sizeof(buf),UPX_MAGIC_LE32)) // note: always le32
|
||||
if (find_le32(buf,sizeof(buf),UPX_MAGIC_LE32) >= 0) // note: always le32
|
||||
throwAlreadyPacked();
|
||||
|
||||
return true;
|
||||
|
@ -187,7 +187,7 @@ void PackUnix::pack(OutputFile *fo)
|
|||
// write packheader
|
||||
const int hsize = ph.getPackHeaderSize();
|
||||
set_le32(obuf, ph.magic); // note: always le32
|
||||
putPackHeader(obuf, hsize);
|
||||
patchPackHeader(obuf, hsize);
|
||||
fo->write(obuf, hsize);
|
||||
|
||||
// write overlay offset (needed for decompression)
|
||||
|
|
|
@ -665,14 +665,9 @@ unsigned PackW32Pe::processImports() // pass 1
|
|||
|
||||
if (soimport == 4)
|
||||
soimport = 0;
|
||||
#if 0
|
||||
FILE *f1=fopen("x0.imp","wb");
|
||||
fwrite(oimport,1,soimport,f1);
|
||||
fclose(f1);
|
||||
f1=fopen("x1.imp","wb");
|
||||
fwrite(oimpdlls,1,soimpdlls,f1);
|
||||
fclose(f1);
|
||||
#endif
|
||||
|
||||
//OutputFile::dump("x0.imp", oimport, soimport);
|
||||
//OutputFile::dump("x1.imp", oimpdlls, soimpdlss);
|
||||
|
||||
unsigned ilen = 0;
|
||||
names.flatten();
|
||||
|
@ -1558,9 +1553,7 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||
processExports(&xport);
|
||||
processRelocs();
|
||||
|
||||
//FILE *f1=fopen("x1","wb");
|
||||
//fwrite(ibuf,1,usize,f1);
|
||||
//fclose(f1);
|
||||
//OutputFile::dump("x1", ibuf, usize);
|
||||
|
||||
// some checks for broken linkers - disable filter if neccessary
|
||||
bool allow_filter = true;
|
||||
|
@ -1670,6 +1663,7 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||
const unsigned lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader,getLoader(),lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
|
||||
int identsize = 0;
|
||||
const unsigned codesize = getLoaderSection("IDENTSTR",&identsize);
|
||||
|
@ -1763,8 +1757,6 @@ void PackW32Pe::pack(OutputFile *fo)
|
|||
Reloc rel(1024); // new relocations are put here
|
||||
rel.add(ic,3);
|
||||
|
||||
putPackHeader(loader,lsize);
|
||||
|
||||
// new PE header
|
||||
memcpy(&oh,&ih,sizeof(oh));
|
||||
oh.filealign = 0x200; // identsplit depends on this
|
||||
|
|
|
@ -418,7 +418,7 @@ void PackWcle::pack(OutputFile *fo)
|
|||
readImage();
|
||||
readNonResidentNames();
|
||||
|
||||
if (find_le32(iimage,20,get_le32("UPX ")))
|
||||
if (find_le32(iimage,20,get_le32("UPX ")) >= 0)
|
||||
throwAlreadyPacked();
|
||||
|
||||
if (ih.init_ss_object != objects)
|
||||
|
@ -526,6 +526,8 @@ void PackWcle::pack(OutputFile *fo)
|
|||
}
|
||||
patch_le32(p,d_len,"RELO",mps*pages);
|
||||
|
||||
patchPackHeader(oimage,e_len);
|
||||
|
||||
unsigned jpos = find_le32(oimage,e_len,get_le32("JMPD"));
|
||||
patch_le32(oimage,e_len,"JMPD",ic-jpos-4);
|
||||
|
||||
|
@ -533,7 +535,6 @@ void PackWcle::pack(OutputFile *fo)
|
|||
patch_le32(oimage,e_len,"ECX0",jpos);
|
||||
patch_le32(oimage,e_len,"EDI0",((ic+d_len+3)&~3)-4);
|
||||
patch_le32(oimage,e_len,"ESI0",e_len+jpos*4-4);
|
||||
putPackHeader(oimage,e_len);
|
||||
|
||||
writeFile(fo, opt->wcle.le);
|
||||
|
||||
|
|
|
@ -562,10 +562,18 @@ void Packer::updatePackHeader()
|
|||
}
|
||||
|
||||
|
||||
void Packer::putPackHeader(upx_bytep buf, unsigned len)
|
||||
int Packer::patchPackHeader(void *b, int blen)
|
||||
{
|
||||
const int size = ph.getPackHeaderSize();
|
||||
assert(isValidFilter(ph.filter));
|
||||
ph.putPackHeader(buf, len);
|
||||
|
||||
int boff = find_le32(b, blen, ph.magic);
|
||||
checkPatch(b, blen, boff, size);
|
||||
|
||||
unsigned char *p = (unsigned char *)b + boff;
|
||||
ph.putPackHeader(p);
|
||||
|
||||
return boff;
|
||||
}
|
||||
|
||||
|
||||
|
@ -590,8 +598,6 @@ bool Packer::readPackHeader(unsigned len, off_t seek_offset, upx_byte *buf)
|
|||
|
||||
if (!ph.fillPackHeader(buf, len))
|
||||
return false;
|
||||
if (!ph.checkPackHeader(buf + ph.buf_offset, len - ph.buf_offset))
|
||||
return false;
|
||||
|
||||
if (ph.version > getVersion())
|
||||
throwCantUnpack("need a newer version of UPX");
|
||||
|
@ -641,7 +647,7 @@ void Packer::checkPatch(void *b, int blen, int boff, int size)
|
|||
}
|
||||
if (b == NULL || blen <= 0 || boff < 0 || size <= 0)
|
||||
throwBadLoader();
|
||||
if (boff + size < 0 || boff + size > blen)
|
||||
if (boff + size <= 0 || boff + size > blen)
|
||||
throwBadLoader();
|
||||
//printf("checkPatch: %p %5d %5d %d\n", b, blen, boff, size);
|
||||
if (b == last_patch)
|
||||
|
@ -913,7 +919,7 @@ void Packer::addSection(const char *sname, const char *sdata, unsigned len)
|
|||
int Packer::getLoaderSection(const char *name, int *slen)
|
||||
{
|
||||
int ostart = linker->getSection(name, slen);
|
||||
if (ostart < 0)
|
||||
if (ostart <= 0)
|
||||
throwBadLoader();
|
||||
return ostart;
|
||||
}
|
||||
|
@ -923,7 +929,7 @@ const upx_byte *Packer::getLoader() const
|
|||
{
|
||||
int size = -1;
|
||||
const char *oloader = linker->getLoader(&size);
|
||||
if (oloader == NULL || size < 0)
|
||||
if (oloader == NULL || size <= 0)
|
||||
throwBadLoader();
|
||||
return (const upx_byte *) oloader;
|
||||
}
|
||||
|
@ -933,7 +939,7 @@ int Packer::getLoaderSize() const
|
|||
{
|
||||
int size = -1;
|
||||
const char *oloader = linker->getLoader(&size);
|
||||
if (oloader == NULL || size < 0)
|
||||
if (oloader == NULL || size <= 0)
|
||||
throwBadLoader();
|
||||
return size;
|
||||
}
|
||||
|
|
10
src/packer.h
10
src/packer.h
|
@ -48,11 +48,13 @@ class Filter;
|
|||
class PackHeader
|
||||
{
|
||||
public:
|
||||
bool fillPackHeader(upx_bytep buf, unsigned len);
|
||||
bool checkPackHeader(const upx_bytep hbuf, int hlen) const;
|
||||
void putPackHeader(upx_bytep buf, unsigned len);
|
||||
PackHeader();
|
||||
|
||||
int getPackHeaderSize() const;
|
||||
|
||||
void putPackHeader(upx_bytep p);
|
||||
bool fillPackHeader(const upx_bytep b, int blen);
|
||||
|
||||
public:
|
||||
// fields stored in compressed file
|
||||
unsigned magic; // UPX_MAGIC_LE32
|
||||
|
@ -173,7 +175,7 @@ protected:
|
|||
|
||||
|
||||
// packheader handling
|
||||
virtual void putPackHeader(upx_byte *buf, unsigned len);
|
||||
virtual int patchPackHeader(void *b, int blen);
|
||||
virtual bool readPackHeader(unsigned len, off_t seek_offset,
|
||||
upx_byte *buf=NULL);
|
||||
|
||||
|
|
180
src/packhead.cpp
180
src/packhead.cpp
|
@ -31,13 +31,22 @@
|
|||
|
||||
|
||||
/*************************************************************************
|
||||
// packheader
|
||||
// PackHeader
|
||||
//
|
||||
// We try to be able to unpack UPX 0.7x (versions 8 & 9) and at
|
||||
// least to detect older versions, so this is a little bit messy.
|
||||
**************************************************************************/
|
||||
|
||||
PackHeader::PackHeader() :
|
||||
version(-1), format(-1)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// simple checksum for the header itself (since version 10)
|
||||
**************************************************************************/
|
||||
|
||||
static unsigned char get_packheader_checksum(const upx_bytep buf, int len)
|
||||
{
|
||||
assert(get_le32(buf) == UPX_MAGIC_LE32);
|
||||
|
@ -57,8 +66,11 @@ static unsigned char get_packheader_checksum(const upx_bytep buf, int len)
|
|||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int get_packheader_size(int version, int format)
|
||||
int PackHeader::getPackHeaderSize() const
|
||||
{
|
||||
if (format < 0 || version < 0)
|
||||
throwInternalError("getPackHeaderSize");
|
||||
|
||||
int n = 0;
|
||||
if (version <= 3)
|
||||
n = 24;
|
||||
|
@ -80,80 +92,71 @@ static int get_packheader_size(int version, int format)
|
|||
else
|
||||
n = 32;
|
||||
}
|
||||
if (n == 0)
|
||||
if (n < 20)
|
||||
throwCantUnpack("unknown header version");
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int PackHeader::getPackHeaderSize() const
|
||||
{
|
||||
return get_packheader_size(version, format);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
void PackHeader::putPackHeader(upx_bytep buf, unsigned len)
|
||||
void PackHeader::putPackHeader(upx_bytep p)
|
||||
{
|
||||
#if defined(UNUPX)
|
||||
throwBadLoader();
|
||||
#else
|
||||
int offset = find_le32(buf,len,magic);
|
||||
if (offset < 0)
|
||||
throwBadLoader();
|
||||
upx_bytep l = buf + offset;
|
||||
assert(get_le32(p) == UPX_MAGIC_LE32);
|
||||
|
||||
l[4] = (unsigned char) version;
|
||||
l[5] = (unsigned char) format;
|
||||
l[6] = (unsigned char) method;
|
||||
l[7] = (unsigned char) level;
|
||||
p[4] = (unsigned char) version;
|
||||
p[5] = (unsigned char) format;
|
||||
p[6] = (unsigned char) method;
|
||||
p[7] = (unsigned char) level;
|
||||
|
||||
// the new variable length header
|
||||
if (format < 128)
|
||||
{
|
||||
set_le32(l+8,u_adler);
|
||||
set_le32(l+12,c_adler);
|
||||
set_le32(p+8,u_adler);
|
||||
set_le32(p+12,c_adler);
|
||||
if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS)
|
||||
{
|
||||
set_le16(l+16,u_len);
|
||||
set_le16(l+18,c_len);
|
||||
l[20] = (unsigned char) filter;
|
||||
set_le16(p+16,u_len);
|
||||
set_le16(p+18,c_len);
|
||||
p[20] = (unsigned char) filter;
|
||||
}
|
||||
else if (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH)
|
||||
{
|
||||
set_le24(l+16,u_len);
|
||||
set_le24(l+19,c_len);
|
||||
set_le24(l+22,u_file_size);
|
||||
l[25] = (unsigned char) filter;
|
||||
set_le24(p+16,u_len);
|
||||
set_le24(p+19,c_len);
|
||||
set_le24(p+22,u_file_size);
|
||||
p[25] = (unsigned char) filter;
|
||||
}
|
||||
else
|
||||
{
|
||||
set_le32(l+16,u_len);
|
||||
set_le32(l+20,c_len);
|
||||
set_le32(l+24,u_file_size);
|
||||
l[28] = (unsigned char) filter;
|
||||
l[29] = (unsigned char) filter_cto;
|
||||
l[30] = 0;
|
||||
set_le32(p+16,u_len);
|
||||
set_le32(p+20,c_len);
|
||||
set_le32(p+24,u_file_size);
|
||||
p[28] = (unsigned char) filter;
|
||||
p[29] = (unsigned char) filter_cto;
|
||||
p[30] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
set_be32(l+8,u_len);
|
||||
set_be32(l+12,c_len);
|
||||
set_be32(l+16,u_adler);
|
||||
set_be32(l+20,c_adler);
|
||||
set_be32(l+24,u_file_size);
|
||||
l[28] = (unsigned char) filter;
|
||||
l[29] = (unsigned char) filter_cto;
|
||||
l[30] = 0;
|
||||
set_be32(p+8,u_len);
|
||||
set_be32(p+12,c_len);
|
||||
set_be32(p+16,u_adler);
|
||||
set_be32(p+20,c_adler);
|
||||
set_be32(p+24,u_file_size);
|
||||
p[28] = (unsigned char) filter;
|
||||
p[29] = (unsigned char) filter_cto;
|
||||
p[30] = 0;
|
||||
}
|
||||
|
||||
// store header_checksum
|
||||
const int hs = getPackHeaderSize();
|
||||
l[hs - 1] = get_packheader_checksum(l, hs - 1);
|
||||
const int size = getPackHeaderSize();
|
||||
p[size - 1] = get_packheader_checksum(p, size - 1);
|
||||
#endif /* UNUPX */
|
||||
}
|
||||
|
||||
|
@ -162,70 +165,72 @@ void PackHeader::putPackHeader(upx_bytep buf, unsigned len)
|
|||
//
|
||||
**************************************************************************/
|
||||
|
||||
bool PackHeader::fillPackHeader(upx_bytep buf, unsigned len)
|
||||
bool PackHeader::fillPackHeader(const upx_bytep buf, int blen)
|
||||
{
|
||||
int offset = find_le32(buf,len,magic);
|
||||
if (offset < 0)
|
||||
return false;
|
||||
const int hlen = len - offset;
|
||||
if (hlen < 8)
|
||||
int boff = find_le32(buf, blen, magic);
|
||||
if (boff < 0)
|
||||
return false;
|
||||
|
||||
upx_bytep l = buf + offset;
|
||||
buf_offset = offset;
|
||||
if (boff + 8 <= 0 || boff + 8 > blen)
|
||||
throwCantUnpack("header corrupted 1");
|
||||
|
||||
version = l[4];
|
||||
format = l[5];
|
||||
method = l[6];
|
||||
level = l[7];
|
||||
const upx_bytep p = buf + boff;
|
||||
|
||||
version = p[4];
|
||||
format = p[5];
|
||||
method = p[6];
|
||||
level = p[7];
|
||||
filter_cto = 0;
|
||||
|
||||
const int hs = getPackHeaderSize();
|
||||
if (hs > hlen)
|
||||
throwCantUnpack("header corrupted");
|
||||
const int size = getPackHeaderSize();
|
||||
if (boff + size <= 0 || boff + size > blen)
|
||||
throwCantUnpack("header corrupted 2");
|
||||
|
||||
//
|
||||
// decode the new variable length header
|
||||
//
|
||||
|
||||
// the new variable length header
|
||||
int off_filter = 0;
|
||||
if (format < 128)
|
||||
{
|
||||
u_adler = get_le32(l+8);
|
||||
c_adler = get_le32(l+12);
|
||||
u_adler = get_le32(p+8);
|
||||
c_adler = get_le32(p+12);
|
||||
if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS)
|
||||
{
|
||||
u_len = get_le16(l+16);
|
||||
c_len = get_le16(l+18);
|
||||
u_len = get_le16(p+16);
|
||||
c_len = get_le16(p+18);
|
||||
u_file_size = u_len;
|
||||
off_filter = 20;
|
||||
}
|
||||
else if (format == UPX_F_DOS_EXE || format == UPX_F_DOS_EXEH)
|
||||
{
|
||||
u_len = get_le24(l+16);
|
||||
c_len = get_le24(l+19);
|
||||
u_file_size = get_le24(l+22);
|
||||
u_len = get_le24(p+16);
|
||||
c_len = get_le24(p+19);
|
||||
u_file_size = get_le24(p+22);
|
||||
off_filter = 25;
|
||||
}
|
||||
else
|
||||
{
|
||||
u_len = get_le32(l+16);
|
||||
c_len = get_le32(l+20);
|
||||
u_file_size = get_le32(l+24);
|
||||
u_len = get_le32(p+16);
|
||||
c_len = get_le32(p+20);
|
||||
u_file_size = get_le32(p+24);
|
||||
off_filter = 28;
|
||||
filter_cto = l[29];
|
||||
filter_cto = p[29];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
u_len = get_be32(l+8);
|
||||
c_len = get_be32(l+12);
|
||||
u_adler = get_be32(l+16);
|
||||
c_adler = get_be32(l+20);
|
||||
u_file_size = get_be32(l+24);
|
||||
u_len = get_be32(p+8);
|
||||
c_len = get_be32(p+12);
|
||||
u_adler = get_be32(p+16);
|
||||
c_adler = get_be32(p+20);
|
||||
u_file_size = get_be32(p+24);
|
||||
off_filter = 28;
|
||||
filter_cto = l[29];
|
||||
filter_cto = p[29];
|
||||
}
|
||||
|
||||
if (version >= 10)
|
||||
filter = l[off_filter];
|
||||
filter = p[off_filter];
|
||||
else if ((level & 128) == 0)
|
||||
filter = 0;
|
||||
else
|
||||
|
@ -239,24 +244,23 @@ bool PackHeader::fillPackHeader(upx_bytep buf, unsigned len)
|
|||
}
|
||||
level &= 15;
|
||||
|
||||
return true;
|
||||
}
|
||||
//
|
||||
// now some checks
|
||||
//
|
||||
|
||||
|
||||
bool PackHeader::checkPackHeader(const upx_bytep hbuf, int hlen) const
|
||||
{
|
||||
if (version == 0xff)
|
||||
throwCantUnpack("cannot unpack UPX ;-)");
|
||||
|
||||
const int hs = getPackHeaderSize();
|
||||
if (hlen <= 0 || hs > hlen)
|
||||
throwCantUnpack("header corrupted");
|
||||
|
||||
// check header_checksum
|
||||
if (version > 9)
|
||||
if (hbuf[hs - 1] != get_packheader_checksum(hbuf, hs - 1))
|
||||
throwCantUnpack("header corrupted");
|
||||
if (p[size - 1] != get_packheader_checksum(p, size - 1))
|
||||
throwCantUnpack("header corrupted 3");
|
||||
|
||||
//
|
||||
// success
|
||||
//
|
||||
|
||||
this->buf_offset = boff;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
40
src/util.cpp
40
src/util.cpp
|
@ -362,7 +362,7 @@ bool maketempname(char *ofilename, const char *ifilename,
|
|||
const char *ext, bool force)
|
||||
{
|
||||
char *ofext = NULL, *ofname;
|
||||
int ofile;
|
||||
int ofile = -1;
|
||||
|
||||
strcpy(ofilename, ifilename);
|
||||
for (ofname = fn_basename(ofilename); *ofname; ofname++)
|
||||
|
@ -373,15 +373,15 @@ bool maketempname(char *ofilename, const char *ifilename,
|
|||
if (ofext == NULL)
|
||||
ofext = ofilename + strlen(ofilename);
|
||||
strcpy(ofext, ext);
|
||||
if (!force)
|
||||
return true;
|
||||
if (file_exists(ofilename))
|
||||
for (ofile = 0; ofile < 999; ofile++)
|
||||
{
|
||||
sprintf(ofext, ".%03d", ofile);
|
||||
if (!file_exists(ofilename))
|
||||
return true;
|
||||
}
|
||||
|
||||
while (ofile < 1000)
|
||||
{
|
||||
if (!file_exists(ofilename))
|
||||
return true;
|
||||
if (!force)
|
||||
break;
|
||||
sprintf(ofext, ".%03d", ++ofile);
|
||||
}
|
||||
|
||||
ofilename[0] = 0;
|
||||
return false;
|
||||
|
@ -391,7 +391,7 @@ bool maketempname(char *ofilename, const char *ifilename,
|
|||
bool makebakname(char *ofilename, const char *ifilename, bool force)
|
||||
{
|
||||
char *ofext = NULL, *ofname;
|
||||
int ofile;
|
||||
int ofile = -1;
|
||||
|
||||
strcpy(ofilename, ifilename);
|
||||
for (ofname = fn_basename(ofilename); *ofname; ofname++)
|
||||
|
@ -408,15 +408,15 @@ bool makebakname(char *ofilename, const char *ifilename, bool force)
|
|||
strcat(ofilename, "~");
|
||||
else
|
||||
ofext[strlen(ofext)-1] = '~';
|
||||
if (!force)
|
||||
return true;
|
||||
if (file_exists(ofilename))
|
||||
for (ofile = 0; ofile < 999; ofile++)
|
||||
{
|
||||
sprintf(ofext, ".%03d", ofile);
|
||||
if (!file_exists(ofilename))
|
||||
return true;
|
||||
}
|
||||
|
||||
while (ofile < 1000)
|
||||
{
|
||||
if (!file_exists(ofilename))
|
||||
return true;
|
||||
if (!force)
|
||||
break;
|
||||
sprintf(ofext, ".%03d", ++ofile);
|
||||
}
|
||||
|
||||
ofilename[0] = 0;
|
||||
return false;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#define UPX_VERSION_STRING "1.09.4"
|
||||
#define UPX_VERSION_DATE "Nov 13th 2000"
|
||||
#define UPX_VERSION_STRING "1.09.5"
|
||||
#define UPX_VERSION_DATE "Dec 12th 2000"
|
||||
|
|
Loading…
Reference in New Issue
Block a user