⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_wcle.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    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: ~28KB 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;    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 (ic > 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);    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.version < 11 ? (get_le32(oimage+ph.u_len-9) >> 24) : ph.filter_cto);        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);}/*vi:ts=4:et*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -