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