Major rewrite: added buildLoader() and fillExeHeader().
committer: mfx <mfx> 978189850 +0000
This commit is contained in:
+146
-126
@@ -39,6 +39,8 @@ static const
|
|||||||
#define MAXMATCH 0x2000
|
#define MAXMATCH 0x2000
|
||||||
#define MAXRELOCS (0x8000-MAXMATCH)
|
#define MAXRELOCS (0x8000-MAXMATCH)
|
||||||
|
|
||||||
|
#define DI_LIMIT 0xff00 // see the assembly why
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -68,16 +70,113 @@ const int *PackExe::getFilters() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||||
|
{
|
||||||
|
#define oh (*eh)
|
||||||
|
// fill new exe header
|
||||||
|
int flag = 0;
|
||||||
|
if (!opt->dos.no_reloc)
|
||||||
|
flag |= USEJUMP;
|
||||||
|
if (ih.relocs == 0)
|
||||||
|
flag |= NORELOC;
|
||||||
|
|
||||||
|
memset(&oh,0,sizeof(oh));
|
||||||
|
oh.ident = 'M' + 'Z' * 256;
|
||||||
|
oh.headsize16 = 2;
|
||||||
|
oh.ip = 0;
|
||||||
|
|
||||||
|
unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16;
|
||||||
|
|
||||||
|
oh.ss = ph.c_len/16 + destpara;
|
||||||
|
if (ih.ss*16 + ih.sp < 0x100000 && ih.ss > oh.ss && ih.sp > 0x200)
|
||||||
|
oh.ss = ih.ss;
|
||||||
|
oh.sp = ih.sp > 0x200 ? ih.sp : 0x200;
|
||||||
|
if (oh.ss*16u + 0x50 < ih.ss*16u + ih.sp
|
||||||
|
&& oh.ss*16u + 0x200 > ih.ss*16u + ih.sp)
|
||||||
|
oh.ss += 0x20;
|
||||||
|
|
||||||
|
if (oh.ss != ih.ss)
|
||||||
|
flag |= SS;
|
||||||
|
if (oh.sp != ih.sp)
|
||||||
|
flag |= SP;
|
||||||
|
return flag;
|
||||||
|
#undef oh
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PackExe::buildLoader(const Filter *)
|
||||||
|
{
|
||||||
|
struct exe_header_t tmp_oh;
|
||||||
|
int flag = fillExeHeader(&tmp_oh);
|
||||||
|
|
||||||
|
// prepare loader
|
||||||
|
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||||
|
addLoader("EXEENTRY",
|
||||||
|
relocsize ? "EXERELPU" : "",
|
||||||
|
"EXEMAIN4""+G5DXXXX""UPX1HEAD""EXECUTPO",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (ph.method == M_NRV2B_8)
|
||||||
|
addLoader("NRV2B16S", // decompressor
|
||||||
|
ph.u_len > DI_LIMIT ? "NDIGT64K" : "",
|
||||||
|
"NRV2BEX1",
|
||||||
|
opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601",
|
||||||
|
"NRV2BEX2",
|
||||||
|
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
||||||
|
"NRV2BEX3",
|
||||||
|
ph.c_len > 0xffff ? "NSIGT64K" : "",
|
||||||
|
"NRV2BEX9""NRV2B16E",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
else if (ph.method == M_NRV2D_8)
|
||||||
|
addLoader("NRV2D16S",
|
||||||
|
ph.u_len > DI_LIMIT ? "NDIGT64D" : "",
|
||||||
|
"NRV2DEX1",
|
||||||
|
opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601",
|
||||||
|
"NRV2DEX2",
|
||||||
|
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
||||||
|
"NRV2DEX3",
|
||||||
|
ph.c_len > 0xffff ? "NSIGT64D" : "",
|
||||||
|
"NRV2DEX9""NRV2D16E",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
else
|
||||||
|
throwInternalError("unknown compression method");
|
||||||
|
addLoader("EXEMAIN5", NULL);
|
||||||
|
if (relocsize)
|
||||||
|
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
|
||||||
|
"EXERELO1",
|
||||||
|
has_9a ? "EXEREL9A" : "",
|
||||||
|
"EXERELO2",
|
||||||
|
ih_exesize > 0xFE00 ? "EXEREBIG" : "",
|
||||||
|
"EXERELO3",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
addLoader("EXEMAIN8",
|
||||||
|
(flag & SS) ? "EXESTACK" : "",
|
||||||
|
(flag & SP) ? "EXESTASP" : "",
|
||||||
|
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (!(flag & USEJUMP))
|
||||||
|
addLoader(ih.cs ? "EXERCSPO" : "",
|
||||||
|
"EXERETIP",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
return getLoaderSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
//
|
//
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
bool PackExe::readFileHeader()
|
int 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));
|
||||||
if (ih.ident != 'M' + 'Z'*256 && ih.ident != 'Z' + 'M'*256)
|
if (ih.ident != 'M' + 'Z'*256 && ih.ident != 'Z' + 'M'*256)
|
||||||
return false;
|
return 0;
|
||||||
ih_exesize = ih.m512 + ih.p512*512 - (ih.m512 ? 512 : 0);
|
ih_exesize = ih.m512 + ih.p512*512 - (ih.m512 ? 512 : 0);
|
||||||
ih_imagesize = ih_exesize - ih.headsize16*16;
|
ih_imagesize = ih_exesize - ih.headsize16*16;
|
||||||
ih_overlay = file_size - ih_exesize;
|
ih_overlay = file_size - ih_exesize;
|
||||||
@@ -88,7 +187,7 @@ bool PackExe::readFileHeader()
|
|||||||
#if 0
|
#if 0
|
||||||
printf("dos/exe header: %d %d %d\n", ih_exesize, ih_imagesize, ih_overlay);
|
printf("dos/exe header: %d %d %d\n", ih_exesize, ih_imagesize, ih_overlay);
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return UPX_F_DOS_EXE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -241,34 +340,25 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
|||||||
void PackExe::pack(OutputFile *fo)
|
void PackExe::pack(OutputFile *fo)
|
||||||
{
|
{
|
||||||
unsigned ic;
|
unsigned ic;
|
||||||
unsigned char flag = 0;
|
|
||||||
|
|
||||||
unsigned char extra_info[32];
|
|
||||||
unsigned eisize = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
const unsigned exesize = ih_exesize;
|
|
||||||
const unsigned imagesize = ih_imagesize;
|
|
||||||
const unsigned overlay = ih_overlay;
|
|
||||||
if (ih.relocs > MAXRELOCS)
|
if (ih.relocs > MAXRELOCS)
|
||||||
throwCantPack("too many relocations");
|
throwCantPack("too many relocations");
|
||||||
checkOverlay(overlay);
|
checkOverlay(ih_overlay);
|
||||||
|
|
||||||
// alloc buffers
|
// alloc buffers
|
||||||
unsigned relocsize = RSFCRI + 4*ih.relocs;
|
relocsize = RSFCRI + 4*ih.relocs;
|
||||||
|
ibuf.alloc(ih_imagesize+16+relocsize+2);
|
||||||
ibuf.alloc(imagesize+16+relocsize+2);
|
obuf.allocForCompression(ih_imagesize+16+relocsize+2);
|
||||||
obuf.allocForCompression(imagesize+16+relocsize+2);
|
|
||||||
|
|
||||||
// read image
|
// read image
|
||||||
fi->seek(ih.headsize16*16,SEEK_SET);
|
fi->seek(ih.headsize16*16,SEEK_SET);
|
||||||
fi->readx(ibuf,imagesize);
|
fi->readx(ibuf,ih_imagesize);
|
||||||
|
|
||||||
checkAlreadyPacked(ibuf, UPX_MIN(imagesize, 127u));
|
checkAlreadyPacked(ibuf, UPX_MIN(ih_imagesize, 127u));
|
||||||
|
|
||||||
// relocations
|
// relocations
|
||||||
has_9a = false;
|
has_9a = false;
|
||||||
upx_byte *w = ibuf + imagesize;
|
upx_byte *w = ibuf + ih_imagesize;
|
||||||
if (ih.relocs)
|
if (ih.relocs)
|
||||||
{
|
{
|
||||||
upx_byte *wr = w + RSFCRI;
|
upx_byte *wr = w + RSFCRI;
|
||||||
@@ -282,7 +372,7 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
set_le32(wr+4*ic, (jc>>16)*16+(jc&0xffff));
|
set_le32(wr+4*ic, (jc>>16)*16+(jc&0xffff));
|
||||||
}
|
}
|
||||||
qsort(wr,ih.relocs,4,le32_compare);
|
qsort(wr,ih.relocs,4,le32_compare);
|
||||||
relocsize = optimize_relocs(ibuf, imagesize, wr, ih.relocs, w, &has_9a);
|
relocsize = optimize_relocs(ibuf, ih_imagesize, wr, ih.relocs, w, &has_9a);
|
||||||
set_le16(w+relocsize, relocsize+2);
|
set_le16(w+relocsize, relocsize+2);
|
||||||
relocsize += 2;
|
relocsize += 2;
|
||||||
if (relocsize > MAXRELOCS)
|
if (relocsize > MAXRELOCS)
|
||||||
@@ -297,121 +387,38 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flag |= NORELOC;
|
|
||||||
relocsize = 0;
|
relocsize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ph.u_len = imagesize + relocsize;
|
Filter ft(opt->level);
|
||||||
|
|
||||||
|
ph.u_len = ih_imagesize + relocsize;
|
||||||
if (!compress(ibuf,obuf,0,MAXMATCH))
|
if (!compress(ibuf,obuf,0,MAXMATCH))
|
||||||
throwNotCompressible();
|
throwNotCompressible();
|
||||||
const unsigned overlapoh = findOverlapOverhead(obuf,32);
|
|
||||||
|
|
||||||
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
||||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||||
|
|
||||||
|
ph.overlap_overhead = findOverlapOverhead(obuf,32);
|
||||||
|
|
||||||
#ifdef TESTING
|
#ifdef TESTING
|
||||||
if (opt->debug)
|
if (opt->debug)
|
||||||
{
|
{
|
||||||
printf("image+relocs %d -> %d\n",imagesize+relocsize,ph.c_len);
|
printf("image+relocs %d -> %d\n",ih_imagesize+relocsize,ph.c_len);
|
||||||
printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n",
|
printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n",
|
||||||
0/*ph.min_offset_found*/,ph.max_offset_found,
|
0/*ph.min_offset_found*/,ph.max_offset_found,
|
||||||
0/*ph.min_match_found*/,ph.max_match_found,
|
0/*ph.min_match_found*/,ph.max_match_found,
|
||||||
0/*ph.min_run_found*/,ph.max_run_found);
|
0/*ph.min_run_found*/,ph.max_run_found);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
const unsigned packedsize = ph.c_len;
|
|
||||||
|
|
||||||
if (!opt->dos.no_reloc)
|
int flag = fillExeHeader(&oh);
|
||||||
flag |= USEJUMP;
|
const unsigned lsize = buildLoader(&ft);
|
||||||
|
|
||||||
// fill new exe header
|
|
||||||
memset(&oh,0,sizeof(oh));
|
|
||||||
oh.ident = 'M' + 'Z' * 256;
|
|
||||||
|
|
||||||
unsigned destpara = (ph.u_len+overlapoh-packedsize+31)/16;
|
|
||||||
|
|
||||||
oh.ss = packedsize/16 + destpara;
|
|
||||||
if (ih.ss*16 + ih.sp < 0x100000 && ih.ss > oh.ss && ih.sp > 0x200)
|
|
||||||
oh.ss = ih.ss;
|
|
||||||
oh.sp = ih.sp > 0x200 ? ih.sp : 0x200;
|
|
||||||
if (oh.ss*16u + 0x50 < ih.ss*16u + ih.sp
|
|
||||||
&& oh.ss*16u + 0x200 > ih.ss*16u + ih.sp)
|
|
||||||
oh.ss += 0x20;
|
|
||||||
|
|
||||||
destpara = oh.ss - packedsize/16;
|
|
||||||
if (oh.ss != ih.ss)
|
|
||||||
{
|
|
||||||
set_le16(extra_info+eisize,ih.ss);
|
|
||||||
eisize += 2;
|
|
||||||
flag |= SS;
|
|
||||||
}
|
|
||||||
if (oh.sp != ih.sp)
|
|
||||||
{
|
|
||||||
set_le16(extra_info+eisize,ih.sp);
|
|
||||||
eisize += 2;
|
|
||||||
flag |= SP;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DI_LIMIT 0xff00 // see the assembly why
|
|
||||||
// prepare loader
|
|
||||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
|
||||||
addLoader("EXEENTRY",
|
|
||||||
relocsize ? "EXERELPU" : "",
|
|
||||||
"EXEMAIN4""+G5DXXXX""UPX1HEAD""EXECUTPO",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (ph.method == M_NRV2B_8)
|
|
||||||
addLoader("NRV2B16S", // decompressor
|
|
||||||
ph.u_len > DI_LIMIT ? "NDIGT64K" : "",
|
|
||||||
"NRV2BEX1",
|
|
||||||
opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601",
|
|
||||||
"NRV2BEX2",
|
|
||||||
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
|
||||||
"NRV2BEX3",
|
|
||||||
packedsize > 0xffff ? "NSIGT64K" : "",
|
|
||||||
"NRV2BEX9""NRV2B16E",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
else if (ph.method == M_NRV2D_8)
|
|
||||||
addLoader("NRV2D16S",
|
|
||||||
ph.u_len > DI_LIMIT ? "NDIGT64D" : "",
|
|
||||||
"NRV2DEX1",
|
|
||||||
opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601",
|
|
||||||
"NRV2DEX2",
|
|
||||||
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
|
||||||
"NRV2DEX3",
|
|
||||||
packedsize > 0xffff ? "NSIGT64D" : "",
|
|
||||||
"NRV2DEX9""NRV2D16E",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
else
|
|
||||||
throwInternalError("unknown compression method");
|
|
||||||
addLoader("EXEMAIN5", NULL);
|
|
||||||
if (relocsize)
|
|
||||||
addLoader(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? "EXENOADJ" : "EXEADJUS",
|
|
||||||
"EXERELO1",
|
|
||||||
has_9a ? "EXEREL9A" : "",
|
|
||||||
"EXERELO2",
|
|
||||||
exesize > 0xFE00 ? "EXEREBIG" : "",
|
|
||||||
"EXERELO3",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
addLoader("EXEMAIN8",
|
|
||||||
(flag & SS) ? "EXESTACK" : "",
|
|
||||||
(flag & SP) ? "EXESTASP" : "",
|
|
||||||
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
if (!(flag & USEJUMP))
|
|
||||||
addLoader(ih.cs ? "EXERCSPO" : "",
|
|
||||||
"EXERETIP",
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
const unsigned lsize = getLoaderSize();
|
|
||||||
MemBuffer loader(lsize);
|
MemBuffer loader(lsize);
|
||||||
memcpy(loader,getLoader(),lsize);
|
memcpy(loader,getLoader(),lsize);
|
||||||
//OutputFile::dump("xxloader.dat", loader, lsize);
|
//OutputFile::dump("xxloader.dat", loader, lsize);
|
||||||
|
|
||||||
// patch loader
|
// patch loader
|
||||||
|
const unsigned packedsize = ph.c_len;
|
||||||
const unsigned e_len = getLoaderSectionStart("EXECUTPO");
|
const unsigned e_len = getLoaderSectionStart("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);
|
||||||
@@ -419,17 +426,29 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
const unsigned copysize = (1+packedsize+d_len) & ~1;
|
const unsigned copysize = (1+packedsize+d_len) & ~1;
|
||||||
const unsigned firstcopy = copysize%0x10000 ? copysize%0x10000 : 0x10000;
|
const unsigned firstcopy = copysize%0x10000 ? copysize%0x10000 : 0x10000;
|
||||||
|
|
||||||
oh.headsize16 = 2;
|
// set oh.min & oh.max
|
||||||
oh.ip = 0;
|
ic = ih.min*16 + ih_imagesize;
|
||||||
|
|
||||||
ic = ih.min*16+imagesize;
|
|
||||||
if (ic < oh.ss*16u + oh.sp)
|
if (ic < oh.ss*16u + oh.sp)
|
||||||
ic = oh.ss*16u + oh.sp;
|
ic = oh.ss*16u + oh.sp;
|
||||||
|
|
||||||
oh.min = (ic - (packedsize + lsize)) / 16;
|
oh.min = (ic - (packedsize + lsize)) / 16;
|
||||||
ic = ((unsigned) oh.min) + (ih.max - ih.min);
|
ic = oh.min + (ih.max - ih.min);
|
||||||
oh.max = ic < 0xffff && ih.max != 0xffff ? ic : 0xffff;
|
oh.max = ic < 0xffff && ih.max != 0xffff ? ic : 0xffff;
|
||||||
|
|
||||||
|
// set extra info
|
||||||
|
unsigned char extra_info[9];
|
||||||
|
unsigned eisize = 0;
|
||||||
|
if (oh.ss != ih.ss)
|
||||||
|
{
|
||||||
|
set_le16(extra_info+eisize,ih.ss);
|
||||||
|
eisize += 2;
|
||||||
|
assert((flag & SS) != 0); // set in fillExeHeader()
|
||||||
|
}
|
||||||
|
if (oh.sp != ih.sp)
|
||||||
|
{
|
||||||
|
set_le16(extra_info+eisize,ih.sp);
|
||||||
|
eisize += 2;
|
||||||
|
assert((flag & SP) != 0); // set in fillExeHeader()
|
||||||
|
}
|
||||||
if (ih.min != oh.min)
|
if (ih.min != oh.min)
|
||||||
{
|
{
|
||||||
set_le16(extra_info+eisize,ih.min);
|
set_le16(extra_info+eisize,ih.min);
|
||||||
@@ -442,7 +461,9 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
eisize += 2;
|
eisize += 2;
|
||||||
flag |= MAXMEM;
|
flag |= MAXMEM;
|
||||||
}
|
}
|
||||||
|
extra_info[eisize++] = (unsigned char) flag;
|
||||||
|
|
||||||
|
// patch loader
|
||||||
if (flag & USEJUMP)
|
if (flag & USEJUMP)
|
||||||
{
|
{
|
||||||
// I use a relocation entry to set the original cs
|
// I use a relocation entry to set the original cs
|
||||||
@@ -474,6 +495,7 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
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);
|
||||||
|
|
||||||
|
unsigned destpara = oh.ss - ph.c_len/16;
|
||||||
patch_le16(loader,e_len,"ES",destpara-e_len/16);
|
patch_le16(loader,e_len,"ES",destpara-e_len/16);
|
||||||
patch_le16(loader,e_len,"DS",e_len/16+(copysize-firstcopy)/16);
|
patch_le16(loader,e_len,"DS",e_len/16+(copysize-firstcopy)/16);
|
||||||
patch_le16(loader,e_len,"SI",firstcopy-2);
|
patch_le16(loader,e_len,"SI",firstcopy-2);
|
||||||
@@ -483,12 +505,11 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
//if (ih.relocoffs >= 0x40 && memcmp(&ih.relocoffs,">TIPPACH",8))
|
//if (ih.relocoffs >= 0x40 && memcmp(&ih.relocoffs,">TIPPACH",8))
|
||||||
// throwCantPack("FIXME");
|
// throwCantPack("FIXME");
|
||||||
|
|
||||||
extra_info[eisize++] = flag;
|
|
||||||
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
||||||
oh.m512 = outputlen & 511;
|
oh.m512 = outputlen & 511;
|
||||||
oh.p512 = (outputlen + 511) >> 9;
|
oh.p512 = (outputlen + 511) >> 9;
|
||||||
|
|
||||||
//fprintf(stderr,"\ne_len=%x d_len=%x clen=%x oo=%x ulen=%x destp=%x copys=%x images=%x",e_len,d_len,packedsize,overlapoh,ph.u_len,destpara,copysize,imagesize);
|
//fprintf(stderr,"\ne_len=%x d_len=%x clen=%x oo=%x ulen=%x destp=%x copys=%x images=%x",e_len,d_len,packedsize,ph.overlap_overhead,ph.u_len,destpara,copysize,ih_imagesize);
|
||||||
|
|
||||||
// write header + write loader + compressed file
|
// write header + write loader + compressed file
|
||||||
#ifdef TESTING
|
#ifdef TESTING
|
||||||
@@ -510,10 +531,10 @@ void PackExe::pack(OutputFile *fo)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// verify
|
// verify
|
||||||
verifyOverlappingDecompression(&obuf, overlapoh);
|
verifyOverlappingDecompression(&obuf, ph.overlap_overhead);
|
||||||
|
|
||||||
// copy the overlay
|
// copy the overlay
|
||||||
copyOverlay(fo, overlay, &obuf);
|
copyOverlay(fo, ih_overlay, &obuf);
|
||||||
//fprintf (stderr,"%x %x\n",relocsize,ph.u_len);
|
//fprintf (stderr,"%x %x\n",relocsize,ph.u_len);
|
||||||
|
|
||||||
// finally check the compression ratio
|
// finally check the compression ratio
|
||||||
@@ -548,7 +569,6 @@ void PackExe::unpack(OutputFile *fo)
|
|||||||
|
|
||||||
// read the file
|
// read the file
|
||||||
unsigned imagesize = ih_imagesize;
|
unsigned imagesize = ih_imagesize;
|
||||||
const unsigned overlay = ih_overlay;
|
|
||||||
|
|
||||||
fi->seek(ih.headsize16*16,SEEK_SET);
|
fi->seek(ih.headsize16*16,SEEK_SET);
|
||||||
fi->readx(ibuf,imagesize);
|
fi->readx(ibuf,imagesize);
|
||||||
@@ -558,7 +578,7 @@ void PackExe::unpack(OutputFile *fo)
|
|||||||
if (imagesize <= e_len + ph.c_len)
|
if (imagesize <= e_len + ph.c_len)
|
||||||
throwCantUnpack("file damaged");
|
throwCantUnpack("file damaged");
|
||||||
|
|
||||||
checkOverlay(overlay);
|
checkOverlay(ih_overlay);
|
||||||
|
|
||||||
// decompress
|
// decompress
|
||||||
decompress(ibuf+e_len,obuf);
|
decompress(ibuf+e_len,obuf);
|
||||||
@@ -656,7 +676,7 @@ void PackExe::unpack(OutputFile *fo)
|
|||||||
fo->write(obuf,relocs-obuf);
|
fo->write(obuf,relocs-obuf);
|
||||||
|
|
||||||
// copy the overlay
|
// copy the overlay
|
||||||
copyOverlay(fo, overlay, &obuf);
|
copyOverlay(fo, ih_overlay, &obuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -63,7 +63,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual bool readFileHeader(void);
|
struct exe_header_t;
|
||||||
|
|
||||||
|
virtual int readFileHeader(void);
|
||||||
|
|
||||||
|
virtual int fillExeHeader(struct exe_header_t *) const;
|
||||||
|
virtual int buildLoader(const Filter *ft);
|
||||||
|
|
||||||
struct exe_header_t
|
struct exe_header_t
|
||||||
{
|
{
|
||||||
@@ -87,6 +92,7 @@ protected:
|
|||||||
unsigned ih_exesize;
|
unsigned ih_exesize;
|
||||||
unsigned ih_imagesize;
|
unsigned ih_imagesize;
|
||||||
unsigned ih_overlay;
|
unsigned ih_overlay;
|
||||||
|
unsigned relocsize;
|
||||||
|
|
||||||
bool has_9a;
|
bool has_9a;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user