代码拉取完成,页面将自动刷新
/* p_wcle.cpp --
This file is part of the UPX executable compressor.
Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer
Copyright (C) 1996-2017 Laszlo Molnar
All Rights Reserved.
UPX and the UCL library are free software; you can redistribute them
and/or modify them under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.
If not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Markus F.X.J. Oberhumer Laszlo Molnar
*/
#include "conf.h"
#include "file.h"
#include "filter.h"
#include "packer.h"
#include "lefile.h"
#include "p_wcle.h"
#include "linker.h"
static const
#include "stub/i386-dos32.watcom.le.h"
#define LEOF_READ (1<<0)
#define LEOF_WRITE (1<<1)
#define LEOF_EXEC (1<<2)
#define LEOF_PRELOAD (1<<6)
#define LEOF_HUGE32 (1<<13)
#define IOT(x,y) iobject_table[x].y
#define OOT(x,y) oobject_table[x].y
#define LE_STUB_EDI (1)
#ifdef TESTING
# define dputc(x,y) do { if (opt->debug.debug_level) putc(x,y); } while (0)
# define Opt_debug opt->debug.debug_level
#else
# define dputc(x,y) ((void)0)
# define Opt_debug 0
#endif
#define my_base_address reserved
#define objects ih.object_table_entries
#define pages ih.memory_pages
#define mps ih.memory_page_size
#define opages oh.memory_pages
/*************************************************************************
//
**************************************************************************/
const int *PackWcle::getCompressionMethods(int method, int level) const
{
return Packer::getDefaultCompressionMethods_le32(method, level);
}
const int *PackWcle::getFilters() const
{
static const int filters[] = {
0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,
FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,
FT_END };
return filters;
}
Linker* PackWcle::newLinker() const
{
return new ElfLinkerX86;
}
void PackWcle::buildLoader(const Filter *ft)
{
// prepare loader
initLoader(stub_i386_dos32_watcom_le, sizeof(stub_i386_dos32_watcom_le));
addLoader("IDENTSTR,WCLEMAIN",
ph.first_offset_found == 1 ? "WCLEMAIN02" : "",
"WCLEMAIN03,UPX1HEAD,WCLECUTP", NULL);
// fake alignment for the start of the decompressor
linker->defineSymbol("WCLECUTP", 0x1000);
addLoader(getDecompressorSections(), "WCLEMAI2", NULL);
if (ft->id)
{
assert(ft->calls > 0);
addLoader(ft->addvalue ? "WCCTTPOS" : "WCCTTNUL", NULL);
addFilter32(ft->id);
}
#if 1
// FIXME: if (has_relocation)
{
addLoader("WCRELOC1,RELOC320",
big_relocs ? "REL32BIG" : "",
"RELOC32J",
NULL
);
}
#endif
addLoader(has_extra_code ? "WCRELSEL" : "",
"WCLEMAI4",
NULL
);
}
/*************************************************************************
// util
**************************************************************************/
void PackWcle::handleStub(OutputFile *fo)
{
if (fo && !opt->watcom_le.le)
Packer::handleStub(fi,fo,le_offset);
}
bool PackWcle::canPack()
{
if (!LeFile::readFileHeader())
return false;
return true;
}
/*************************************************************************
//
**************************************************************************/
// IDEA: as all the entries go into object #1, I could create bundles with 255
// elements (of course I still have to handle empty bundles)
void PackWcle::encodeEntryTable()
{
unsigned count,object,n;
upx_byte *p = ientries;
n = 0;
while (*p)
{
count = *p;
n += count;
if (p[1] == 0) // unused bundle
p += 2;
else if (p[1] == 3) // 32-bit bundle
{
object = get_le16(p+2)-1;
set_le16(p+2,1);
p += 4;
for (; count; count--, p += 5)
set_le32(p+1,IOT(object,my_base_address) + get_le32(p+1));
}
else
throwCantPack("unsupported bundle type in entry table");
}
//if (Opt_debug) printf("%d entries encoded.\n",n);
UNUSED(n);
soentries = ptr_diff(p, ientries) + 1;
oentries = ientries;
ientries = NULL;
}
void PackWcle::readObjectTable()
{
LeFile::readObjectTable();
// temporary copy of the object descriptors
iobject_desc.alloc(objects*sizeof(*iobject_table));
memcpy(iobject_desc,iobject_table,objects*sizeof(*iobject_table));
unsigned ic,jc,virtual_size;
for (ic = jc = virtual_size = 0; ic < objects; ic++)
{
jc += IOT(ic,npages);
IOT(ic,my_base_address) = virtual_size;
virtual_size += (IOT(ic,virtual_size)+mps-1) &~ (mps-1);
}
if (pages != jc)
throwCantPack("bad page number");
}
void PackWcle::encodeObjectTable()
{
unsigned ic,jc;
oobject_table = New(le_object_table_entry_t, soobject_table = 2);
memset(oobject_table,0,soobject_table * sizeof(*oobject_table));
// object #1:
OOT(0,base_address) = IOT(0,base_address);
ic = IOT(objects-1,my_base_address)+IOT(objects-1,virtual_size);
jc = pages*mps+sofixups+1024;
if (ic < jc)
ic = jc;
unsigned csection = (ic + ph.overlap_overhead + mps-1) &~ (mps-1);
OOT(0,virtual_size) = csection + mps;
OOT(0,flags) = LEOF_READ|LEOF_EXEC|LEOF_HUGE32|LEOF_PRELOAD;
OOT(0,pagemap_index) = 1;
OOT(0,npages) = opages;
// object #2: stack
OOT(1,base_address) = (OOT(0,base_address)
+OOT(0,virtual_size)+mps-1) & ~(mps-1);
OOT(1,virtual_size) = mps + getDecompressorWrkmemSize();
OOT(1,flags) = LEOF_READ|LEOF_HUGE32|LEOF_WRITE;
OOT(1,pagemap_index) = 1;
oh.init_cs_object = 1;
oh.init_eip_offset = neweip;
oh.init_ss_object = 2;
oh.init_esp_offset = OOT(1,virtual_size);
oh.automatic_data_object = 2;
}
void PackWcle::encodePageMap()
{
opm_entries = New(le_pagemap_entry_t, sopm_entries = opages);
for (unsigned ic = 0; ic < sopm_entries; ic++)
{
opm_entries[ic].l = (unsigned char) (ic+1);
opm_entries[ic].m = (unsigned char) ((ic+1)>>8);
opm_entries[ic].h = 0;
opm_entries[ic].type = 0;
}
}
void PackWcle::encodeFixupPageTable()
{
unsigned ic;
ofpage_table = New(unsigned, sofpage_table = 1 + opages);
for (ofpage_table[0] = ic = 0; ic < opages; ic++)
set_le32(ofpage_table+ic+1,sofixups-FIXUP_EXTRA);
}
void PackWcle::encodeFixups()
{
ofixups = New(upx_byte, sofixups = 1*7 + FIXUP_EXTRA);
memset(ofixups,0,sofixups);
ofixups[0] = 7;
set_le16(ofixups+2,(LE_STUB_EDI + neweip) & (mps-1));
ofixups[4] = 1;
}
void PackWcle::preprocessFixups()
{
big_relocs = 0;
unsigned ic,jc;
Array(unsigned, counts, objects+2);
countFixups(counts);
for (ic = jc = 0; ic < objects; ic++)
jc += counts[ic];
if (jc == 0)
{
// FIXME: implement this
throwCantPack("files without relocations are not supported");
}
ByteArray(rl, jc);
ByteArray(srf, counts[objects+0]+1);
ByteArray(slf, counts[objects+1]+1);
upx_byte *selector_fixups = srf;
upx_byte *selfrel_fixups = slf;
unsigned rc = 0;
upx_byte *fix = ifixups;
for (ic = jc = 0; ic < pages; ic++)
{
while ((unsigned)(fix - ifixups) < get_le32(ifpage_table+ic+1))
{
const int fixp2 = get_le16_signed(fix+2);
unsigned value;
switch (*fix)
{
case 2: // selector fixup
if (fixp2 < 0)
{
// cross page selector fixup
dputc('S',stdout);
fix += 5;
break;
}
dputc('s',stdout);
memcpy(selector_fixups,"\x8C\xCB\x66\x89\x9D",5); // mov bx, cs ; mov [xxx+ebp], bx
if (IOT(fix[4]-1,flags) & LEOF_WRITE)
selector_fixups[1] = 0xDB; // ds
set_le32(selector_fixups+5,jc+fixp2);
selector_fixups += 9;
fix += 5;
break;
case 5: // 16-bit offset
if ((unsigned)fixp2 < 4096 && IOT(fix[4]-1,my_base_address) == jc)
dputc('6',stdout);
else
throwCantPack("unsupported 16-bit offset relocation");
fix += (fix[1] & 0x10) ? 9 : 7;
break;
case 6: // 16:32 pointer
if (fixp2 < 0)
{
// cross page pointer fixup
dputc('P',stdout);
fix += (fix[1] & 0x10) ? 9 : 7;
break;
}
dputc('p',stdout);
memcpy(iimage+jc+fixp2,fix+5,(fix[1] & 0x10) ? 4 : 2);
set_le32(rl+4*rc++,jc+fixp2);
set_le32(iimage+jc+fixp2,get_le32(iimage+jc+fixp2)+IOT(fix[4]-1,my_base_address));
memcpy(selector_fixups,"\x8C\xCA\x66\x89\x95",5);
if (IOT(fix[4]-1,flags) & LEOF_WRITE)
selector_fixups[1] = 0xDA; // ds
set_le32(selector_fixups+5,jc+fixp2+4);
selector_fixups += 9;
fix += (fix[1] & 0x10) ? 9 : 7;
break;
case 7: // 32-bit offset
if (fixp2 < 0)
{
fix += (fix[1] & 0x10) ? 9 : 7;
break;
}
//if (memcmp(iimage+jc+fixp2,fix+5,(fix[1] & 0x10) ? 4 : 2))
// throwCantPack("illegal fixup offset");
// work around a pmwunlite bug: remove duplicated fixups
// FIXME: fix the other cases too
if (rc == 0 || get_le32(rl+4*rc-4) != jc+fixp2)
{
set_le32(rl+4*rc++,jc+fixp2);
set_le32(iimage+jc+fixp2,get_le32(iimage+jc+fixp2)+IOT(fix[4]-1,my_base_address));
}
fix += (fix[1] & 0x10) ? 9 : 7;
break;
case 8: // 32-bit self relative fixup
if (fixp2 < 0)
{
// cross page self relative fixup
dputc('R',stdout);
fix += (fix[1] & 0x10) ? 9 : 7;
break;
}
value = get_le32(fix+5);
if (fix[1] == 0)
value &= 0xffff;
set_le32(iimage+jc+fixp2,(value+IOT(fix[4]-1,my_base_address))-jc-fixp2-4);
set_le32(selfrel_fixups,jc+fixp2);
selfrel_fixups += 4;
dputc('r',stdout);
fix += (fix[1] & 0x10) ? 9 : 7;
break;
default:
throwCantPack("unsupported fixup record");
}
}
jc += mps;
}
// resize ifixups if it's too small
if (sofixups < 1000)
{
delete[] ifixups;
ifixups = new upx_byte[1000];
}
fix = optimizeReloc32 (rl,rc,ifixups,iimage,1,&big_relocs);
has_extra_code = srf != selector_fixups;
// FIXME: this could be removed if has_extra_code = false
// but then we'll need a flag
*selector_fixups++ = 0xC3; // ret
memcpy(fix,srf,selector_fixups-srf); // copy selector fixup code
fix += selector_fixups-srf;
memcpy(fix,slf,selfrel_fixups-slf); // copy self-relative fixup positions
fix += selfrel_fixups-slf;
set_le32(fix,0xFFFFFFFFUL);
fix += 4;
sofixups = ptr_diff(fix, ifixups);
}
#define RESERVED 0x1000
void PackWcle::encodeImage(Filter *ft)
{
// concatenate image & preprocessed fixups
unsigned isize = soimage + sofixups;
ibuf.alloc(isize);
memcpy(ibuf,iimage,soimage);
memcpy(ibuf+soimage,ifixups,sofixups);
delete[] ifixups; ifixups = NULL;
oimage.allocForCompression(isize, RESERVED+512);
// prepare packheader
ph.u_len = isize;
// prepare filter [already done]
// compress
upx_compress_config_t cconf; cconf.reset();
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack
compressWithFilters(ibuf, isize,
oimage + RESERVED,
ibuf + ft->addvalue, ft->buf_len,
NULL, 0,
ft, 512, &cconf, 0);
ibuf.dealloc();
soimage = ph.c_len;
while (soimage & 3)
oimage[RESERVED + soimage++] = 0;
}
void PackWcle::pack(OutputFile *fo)
{
handleStub(fo);
if (ih.byte_order || ih.word_order
|| ih.exe_format_level
|| ih.cpu_type < 2 || ih.cpu_type > 5
|| ih.target_os != 1
|| ih.module_type != 0x200
|| ih.object_iterate_data_map_offset
|| ih.resource_entries
|| ih.module_directives_entries
|| ih.imported_modules_count
|| ih.object_table_entries > 255)
throwCantPack("watcom/le: unexpected value in header");
readObjectTable();
readPageMap();
readResidentNames();
readEntryTable();
readFixupPageTable();
readFixups();
readImage();
readNonResidentNames();
// if (find_le32(iimage,20,get_le32("UPX ")) >= 0)
if (find_le32(iimage,UPX_MIN(soimage,256u),UPX_MAGIC_LE32) >= 0)
throwAlreadyPacked();
if (ih.init_ss_object != objects)
throwCantPack("the stack is not in the last object");
preprocessFixups();
const unsigned text_size = IOT(ih.init_cs_object-1,npages) * mps;
const unsigned text_vaddr = IOT(ih.init_cs_object-1,my_base_address);
// attach some useful data at the end of preprocessed fixups
ifixups[sofixups++] = (unsigned char) (ih.automatic_data_object & 0xff);
unsigned ic = objects*sizeof(*iobject_table);
memcpy(ifixups+sofixups,iobject_desc,ic);
iobject_desc.dealloc();
sofixups += ic;
set_le32(ifixups+sofixups,ih.init_esp_offset+IOT(ih.init_ss_object-1,my_base_address)); // old stack pointer
set_le32(ifixups+sofixups+4,ih.init_eip_offset+text_vaddr); // real entry point
set_le32(ifixups+sofixups+8,mps*pages); // virtual address of unpacked relocations
ifixups[sofixups+12] = (unsigned char) (unsigned) objects;
sofixups += 13;
// prepare filter
Filter ft(ph.level);
ft.buf_len = text_size;
ft.addvalue = text_vaddr;
// compress
encodeImage(&ft);
const unsigned lsize = getLoaderSize();
neweip = getLoaderSection("WCLEMAIN");
int e_len = getLoaderSectionStart("WCLECUTP");
const unsigned d_len = lsize - e_len;
assert(e_len > 0 && e_len < RESERVED);
memmove(oimage+e_len,oimage+RESERVED,soimage);
soimage += lsize;
opages = (soimage+mps-1)/mps;
oh.bytes_on_last_page = soimage%mps;
encodeObjectTable();
encodeFixups();
encodeFixupPageTable();
encodePageMap();
encodeEntryTable();
encodeResidentNames();
encodeNonResidentNames();
// patch loader
ic = (OOT(0,virtual_size) - d_len) &~ 15;
assert(ic > ((ph.u_len + ph.overlap_overhead + 31) &~ 15));
linker->defineSymbol("WCLECUTP", ic);
linker->defineSymbol("original_entry", ih.init_eip_offset + text_vaddr);
linker->defineSymbol("original_stack", ih.init_esp_offset +
IOT(ih.init_ss_object - 1, my_base_address));
linker->defineSymbol("start_of_relocs", mps*pages);
defineDecompressorSymbols();
defineFilterSymbols(&ft);
linker->defineSymbol("filter_buffer_start", text_vaddr);
unsigned jpos = (((ph.c_len + 3) &~ 3) + d_len + 3) / 4;
linker->defineSymbol("words_to_copy", jpos);
linker->defineSymbol("copy_dest", ((ic + d_len + 3) &~ 3) - 4);
linker->defineSymbol("copy_source", e_len + jpos * 4 - 4);
relocateLoader();
MemBuffer loader(lsize);
memcpy(loader, getLoader(), lsize);
patchPackHeader(loader, lsize);
memcpy(oimage, loader, e_len);
memcpy(oimage + soimage - d_len, loader + e_len, d_len);
writeFile(fo, opt->watcom_le.le);
// verify
verifyOverlappingDecompression(oimage + e_len, oimage.getSize() - e_len);
// copy the overlay
const unsigned overlaystart = ih.data_pages_offset + exe_offset
+ getImageSize();
const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length;
checkOverlay(overlay);
copyOverlay(fo, overlay, &oimage);
// finally check the compression ratio
if (!checkFinalCompressionRatio(fo))
throwNotCompressible();
}
/*************************************************************************
//
**************************************************************************/
void PackWcle::decodeFixups()
{
upx_byte *p = oimage + soimage;
iimage.dealloc();
MemBuffer tmpbuf;
unsigned fixupn = unoptimizeReloc32(&p,oimage,&tmpbuf,1);
MemBuffer wrkmem(8*fixupn+8);
unsigned ic,jc,o,r;
for (ic=0; ic<fixupn; ic++)
{
jc=get_le32(tmpbuf+4*ic);
set_le32(wrkmem+ic*8,jc);
o = soobject_table;
r = get_le32(oimage+jc);
virt2rela(oobject_table,&o,&r);
set_le32(wrkmem+ic*8+4,OOT(o-1,my_base_address));
set_le32(oimage+jc,r);
}
set_le32(wrkmem+ic*8,0xFFFFFFFF); // end of 32-bit offset fixups
tmpbuf.dealloc();
// selector fixups and self-relative fixups
const upx_byte *selector_fixups = p;
const upx_byte *selfrel_fixups = p;
while (*selfrel_fixups != 0xC3)
selfrel_fixups += 9;
selfrel_fixups++;
unsigned selectlen = ptr_diff(selfrel_fixups, selector_fixups)/9;
ofixups = New(upx_byte, fixupn*9+1000+selectlen*5);
upx_bytep fp = ofixups;
for (ic = 1, jc = 0; ic <= opages; ic++)
{
// self relative fixups
while ((r = get_le32(selfrel_fixups))/mps == ic-1)
{
fp[0] = 8;
set_le16(fp+2,r & (mps-1));
o = 4+get_le32(oimage+r);
set_le32(oimage+r,0);
r += o;
o = soobject_table;
virt2rela(oobject_table,&o,&r);
fp[4] = (unsigned char) o;
set_le32(fp+5,r);
fp[1] = (unsigned char) (r > 0xFFFF ? 0x10 : 0);
fp += fp[1] ? 9 : 7;
selfrel_fixups += 4;
dputc('r',stdout);
}
// selector fixups
while (selectlen && (r = get_le32(selector_fixups+5))/mps == ic-1)
{
fp[0] = 2;
fp[1] = 0;
set_le16(fp+2,r & (mps-1));
unsigned x = selector_fixups[1] > 0xD0 ? oh.init_ss_object : oh.init_cs_object;
fp[4] = (unsigned char) x;
fp += 5;
selector_fixups += 9;
selectlen--;
dputc('s',stdout);
}
// 32 bit offset fixups
while (get_le32(wrkmem+4*jc) < ic*mps)
{
if (jc > 1 && ((get_le32(wrkmem+4*(jc-2))+3) & (mps-1)) < 3) // cross page fixup?
{
r = get_le32(oimage+get_le32(wrkmem+4*(jc-2)));
fp[0] = 7;
fp[1] = (unsigned char) (r > 0xFFFF ? 0x10 : 0);
set_le16(fp+2,get_le32(wrkmem+4*(jc-2)) | ~3);
set_le32(fp+5,r);
o = soobject_table;
r = get_le32(wrkmem+4*(jc-1));
virt2rela(oobject_table,&o,&r);
fp[4] = (unsigned char) o;
fp += fp[1] ? 9 : 7;
dputc('0',stdout);
}
o = soobject_table;
r = get_le32(wrkmem+4*(jc+1));
virt2rela(oobject_table,&o,&r);
r = get_le32(oimage+get_le32(wrkmem+4*jc));
fp[0] = 7;
fp[1] = (unsigned char) (r > 0xFFFF ? 0x10 : 0);
set_le16(fp+2,get_le32(wrkmem+4*jc) & (mps-1));
fp[4] = (unsigned char) o;
set_le32(fp+5,r);
fp += fp[1] ? 9 : 7;
jc += 2;
}
set_le32(ofpage_table+ic,ptr_diff(fp,ofixups));
}
for (ic=0; ic < FIXUP_EXTRA; ic++)
*fp++ = 0;
sofixups = ptr_diff(fp, ofixups);
}
void PackWcle::decodeFixupPageTable()
{
ofpage_table = New(unsigned, sofpage_table = 1 + opages);
set_le32(ofpage_table,0);
// the rest of ofpage_table is filled by decodeFixups()
}
void PackWcle::decodeObjectTable()
{
soobject_table = oimage[ph.u_len - 1];
oobject_table = New(le_object_table_entry_t, soobject_table);
unsigned jc, ic = soobject_table * sizeof(*oobject_table);
const unsigned extradata = ph.version == 10 ? 17 : 13;
memcpy(oobject_table,oimage + ph.u_len - extradata - ic,ic);
if (ph.version >= 12)
oh.automatic_data_object = oimage[ph.u_len - ic - 14];
for (ic = jc = 0; ic < soobject_table; ic++)
{
OOT(ic,my_base_address) = jc;
jc += (OOT(ic,virtual_size)+mps-1) &~ (mps-1);
}
// restore original cs:eip & ss:esp
ic = soobject_table;
jc = get_le32(oimage + ph.u_len - (ph.version < 11 ? 13 : 9));
virt2rela(oobject_table,&ic,&jc);
oh.init_cs_object = ic;
oh.init_eip_offset = jc;
ic = soobject_table;
if (ph.version < 10)
jc = ih.init_esp_offset;
else
jc = get_le32(oimage + ph.u_len - (ph.version == 10 ? 17 : 13));
virt2rela(oobject_table,&ic,&jc);
oh.init_ss_object = ic;
oh.init_esp_offset = jc;
}
void PackWcle::decodeImage()
{
oimage.allocForUncompression(ph.u_len);
decompress(iimage + ph.buf_offset + ph.getPackHeaderSize(),oimage);
soimage = get_le32(oimage + ph.u_len - 5);
opages = soimage / mps;
oh.memory_page_size = mps;
}
void PackWcle::decodeEntryTable()
{
unsigned count,object,n,r;
upx_byte *p = ientries;
n = 0;
while (*p)
{
count = *p;
n += count;
if (p[1] == 0) // unused bundle
p += 2;
else if (p[1] == 3) // 32-bit offset bundle
{
object = get_le16(p+2);
if (object != 1)
throwCantUnpack("corrupted entry found");
object = soobject_table;
r = get_le32(p+5);
virt2rela(oobject_table,&object,&r);
set_le16(p+2,object--);
p += 4;
for (; count; count--, p += 5)
set_le32(p+1,get_le32(p+1) - OOT(object,my_base_address));
}
else
throwCantUnpack("unsupported bundle type in entry table");
}
//if (Opt_debug) printf("\n%d entries decoded.\n",n);
soentries = ptr_diff(p, ientries) + 1;
oentries = ientries;
ientries = NULL;
}
int PackWcle::canUnpack()
{
if (!LeFile::readFileHeader())
return false;
fi->seek(exe_offset + ih.data_pages_offset, SEEK_SET);
// FIXME: 1024 could be too large for some files
//int len = 1024;
int len = UPX_MIN(getImageSize(), 256u);
if (len == 0)
return false;
return readPackHeader(len) ? 1 : -1;
}
void PackWcle::virt2rela(const le_object_table_entry_t *entr,unsigned *objn,unsigned *addr)
{
for (; *objn > 1; objn[0]--)
{
if (entr[*objn-1].my_base_address > *addr)
continue;
*addr -= entr[*objn-1].my_base_address;
break;
}
}
/*************************************************************************
//
**************************************************************************/
void PackWcle::unpack(OutputFile *fo)
{
handleStub(fo);
readObjectTable();
iobject_desc.dealloc();
readPageMap();
readResidentNames();
readEntryTable();
readFixupPageTable();
readFixups();
readImage();
readNonResidentNames();
decodeImage();
decodeObjectTable();
// unfilter
if (ph.filter)
{
const unsigned text_size = OOT(oh.init_cs_object-1,npages) * mps;
const unsigned text_vaddr = OOT(oh.init_cs_object-1,my_base_address);
Filter ft(ph.level);
ft.init(ph.filter, text_vaddr);
ft.cto = (unsigned char) ph.filter_cto;
if (ph.version < 11)
ft.cto = (unsigned char) (get_le32(oimage+ph.u_len-9) >> 24);
ft.unfilter(oimage+text_vaddr, text_size);
}
decodeFixupPageTable();
decodeFixups();
decodeEntryTable();
decodePageMap();
decodeResidentNames();
decodeNonResidentNames();
for (unsigned ic = 0; ic < soobject_table; ic++)
OOT(ic,my_base_address) = 0;
while (oimage[soimage-1] == 0)
soimage--;
oh.bytes_on_last_page = soimage % mps;
// write decompressed file
if (fo)
writeFile(fo, opt->watcom_le.le);
// copy the overlay
const unsigned overlaystart = ih.data_pages_offset + exe_offset
+ getImageSize();
const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length;
checkOverlay(overlay);
copyOverlay(fo, overlay, &oimage);
}
/* vim:set ts=4 sw=4 et: */
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。