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

📄 p_wcle.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* p_wcle.cpp --   This file is part of the UPX executable compressor.   Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer   Copyright (C) 1996-2007 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   <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net> */#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 an 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 0x1000void 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

⌨️ 快捷键说明

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