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

📄 p_ps1.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        }        else        {            if (M_IS_LZMA(ph.method))                addLoader(!foundBss ? "cdb.start.lzma" : "bss.cdb.start.lzma", "pad.code",                          !foundBss ? "cdb.entry.lzma" : "bss.cdb.entry.lzma",                          method, "cdb.lzma.cpr",                          ih.tx_ptr & 0xffff ?  "dec.ptr" : "dec.ptr.hi",                          "lzma.exec", NULL);            else            {                assert(foundBss != true);                addLoader("cdb.start", "pad.code", "cdb.entry",                          ih.tx_ptr & 0xffff ?  "cdb.dec.ptr" : "cdb.dec.ptr.hi",                          method,                          sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",                          "cdb.exit", NULL);            }        }        addLoader("UPX1HEAD", "IDENTSTR", NULL);    }}#define OPTYPE(x)     (((x) >> 13) & 0x7)#define OPCODE(x)     (((x) >> 10) & 0x7)#define REG1(x)       (((x) >> 5) & 0x1f)#define REG2(x)       ((x) & 0x1f)#define MIPS_IMM(a,b) ((((a) - (((b) & 0x8000) >> 15)) << 16) | (b))// Type#define REGIMM  1#define STORE   5// Op#define LUI     7#define ADDIU   1#define SW      3#define IS_LUI(a)     ((OPTYPE(a) == REGIMM && OPCODE(a) == LUI))#define IS_ADDIU(a)   ((OPTYPE(a) == REGIMM && OPCODE(a) == ADDIU))#define IS_SW_ZERO(a) ((OPTYPE(a) == STORE && OPCODE(a) == SW) && REG2(a) == 0)#define BSS_CHK_LIMIT (18)bool PackPs1::findBssSection(){    unsigned char reg;    LE32 *p1 = (LE32 *)(ibuf + (ih.epc - ih.tx_ptr));    if ((ih.epc - ih.tx_ptr + (BSS_CHK_LIMIT * 4)) > fdata_size)        return false;    // check 18 opcodes for sw zero,0(x)    for (signed i = BSS_CHK_LIMIT; i >= 0; i--)    {        unsigned short op = p1[i] >> 16;        if (IS_SW_ZERO(op))        {            // found! get reg (x) for bss_start            reg = REG1(op);            for (; i >= 0; i--)            {                bss_nfo *p = (bss_nfo *)&p1[i];                unsigned short op1 = p->op1, op2 = p->op2;                // check for la (x),bss_start                if ((IS_LUI(op1) && REG2(op1) == reg) &&                    (IS_ADDIU(op2) && REG1(op2) == reg))                {                    op1 = p->op3, op2 = p->op4;                    // check for la (y),bss_end                    if (IS_LUI(op1) && IS_ADDIU(op2))                    {                        // bss section info found!                        bss_start = MIPS_IMM(p->hi1, p->lo1);                        bss_end = MIPS_IMM(p->hi2, p->lo2);                        if (0 < ALIGN_DOWN(bss_end - bss_start, 4u))                        {                            unsigned wkmem_sz = M_IS_LZMA(ph.method) ? 32768 : 800;                            unsigned end_offs = ih.tx_ptr + fdata_size + overlap;                            if (bss_end > (end_offs + wkmem_sz))                                return isCon || (!isCon && M_IS_LZMA(ph.method));                            else                                return false;                        }                    }                    else                        return false;                }            }        }    }    return false;}/*************************************************************************//**************************************************************************/void PackPs1::pack(OutputFile *fo){    ibuf.alloc(fdata_size);    obuf.allocForCompression(fdata_size);    const upx_byte *p_scan = ibuf + fdata_size;    // read file    fi->seek(PS_HDR_SIZE,SEEK_SET);    fi->readx(ibuf,fdata_size);    // scan EOF for 2048 bytes sector alignment    // the removed space will secure in-place decompression    while (!(*--p_scan)) { if (sa_cnt++ > (0x10000 << 5) || sa_cnt >= fdata_size - 1024) break; }    if (sa_cnt > (0x10000 << 2))        sa_cnt = ALIGN_DOWN(sa_cnt, 32u);    else        sa_cnt = ALIGN_DOWN(sa_cnt, 4u);    // prepare packheader    ph.u_len = (fdata_size - sa_cnt);    ph.filter = 0;    Filter ft(ph.level);    // compress (max_match = 65535)    upx_compress_config_t cconf; cconf.reset();    cconf.conf_ucl.max_match = 65535;    cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack    compressWithFilters(&ft, sa_cnt, &cconf);    if (overlap)    {        opt->info_mode += !opt->info_mode ? 1 : 0;        infoWarning("overlap - relocating load address (+%d bytes)", overlap);        sa_cnt += overlap;    }/*    if (bss_start && bss_end && !foundBss)        infoWarning("%s: .bss section too small - use stack", fi->getName());*/    unsigned lzma_init = 0;    if (M_IS_LZMA(ph.method))    {        sz_lunc = getLoaderSize();        lzma_init = 0u - (sz_lunc - linker->getSymbolOffset("lzma.init"));        defineDecompressorSymbols();        linker->defineSymbol("entry", ih.epc);        linker->defineSymbol("SC",                             sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2);        relocateLoader();        buildPart2 = true;        buildLoader(&ft);    }    memcpy(&oh, &ih, sizeof(ih));    unsigned sz_cbh;    putBkupHeader((const unsigned char *)&ih.epc, (unsigned char *)&bh, &sz_cbh);    if (ih.is_ptr < (EXE_BS | (PS_RAM_SIZE - PS_STACK_SIZE)))        oh.is_ptr = (EXE_BS | (PS_RAM_SIZE - 16));    if (ih.da_ptr != 0 || ih.da_len != 0 ||        ih.bs_ptr != 0 || ih.bs_len != 0)        oh.da_ptr = oh.da_len =        oh.bs_ptr = oh.bs_len = 0;    const int lsize = getLoaderSize();    unsigned filelen = ALIGN_UP(ih.tx_len, 4);    const unsigned decomp_data_start = ih.tx_ptr;    const unsigned comp_data_start = (decomp_data_start + filelen + overlap) - ph.c_len;    const int h_len = lsize - getLoaderSectionStart("UPX1HEAD");    int d_len = 0;    int e_len = 0;    if (isCon)    {        e_len = lsize - h_len;        d_len = e_len - getLoaderSectionStart("con.entry");    }    else    {        const char* entry_lzma = !foundBss ? "cdb.entry.lzma" : "bss.cdb.entry.lzma";        d_len = (lsize - h_len) - getLoaderSectionStart(M_IS_LZMA(ph.method) ? entry_lzma : "cdb.entry");        e_len = (lsize - d_len) - h_len;    }    linker->defineSymbol("entry", ih.epc);    linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?                                       sa_cnt >> 5 : sa_cnt >> 2));    linker->defineSymbol("DECO", decomp_data_start);    linker->defineSymbol("ldr_sz", M_IS_LZMA(ph.method) ? sz_lunc + 16 : (d_len-pad_code));    if (foundBss)    {        if (M_IS_LZMA(ph.method))            linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()                                           - (sz_lunc + 16));        else            linker->defineSymbol("wrkmem", bss_end - 16 - (d_len - pad_code));    }    const unsigned entry = comp_data_start - e_len;    oh.epc = oh.tx_ptr = entry;    oh.tx_len = ph.c_len + e_len;    unsigned pad = 0;    if (!opt->ps1_exe.no_align || !isCon)    {        pad = oh.tx_len;        oh.tx_len = ALIGN_UP(oh.tx_len, CD_SEC);        pad = oh.tx_len - pad;        oh.tx_ptr -= pad;    }    ibuf.clear(0,fdata_size);    upx_bytep paddata = ibuf;    if (M_IS_LZMA(ph.method))    {        linker->defineSymbol("lzma_init_off", lzma_init);        linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e"));    }    else        if (isCon)            linker->defineSymbol("gb_e", linker->getSymbolOffset(is32Bit ? "gb32_e" : "gb8_e"));    if (isCon)    {        linker->defineSymbol("PAD", pad_code);        if (M_IS_LZMA(ph.method))            linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));        else            linker->defineSymbol("DCRT", (entry + (e_len - d_len)));    }    else    {        linker->defineSymbol("PSVR", FIX_PSVR);        linker->defineSymbol("CPDO", comp_data_start);        if (M_IS_LZMA(ph.method))        {            unsigned entry_lzma = getLoaderSectionStart( !foundBss ? "cdb.entry.lzma" :                                                                     "bss.cdb.entry.lzma");            linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec") - entry_lzma);        }    }    relocateLoader();    //linker->dumpSymbols();    MemBuffer loader(lsize);    assert(lsize == getLoaderSize());    memcpy(loader, getLoader(), lsize);    patchPackHeader(loader, lsize);    if (!isCon && M_IS_LZMA(ph.method) && (HD_CODE_OFS + d_len + h_len) > CD_SEC)        throwInternalError("lzma --boot-only loader > 2048");    // ps1_exe_t structure    fo->write(&oh, sizeof(oh));    fo->write(&bh, sz_cbh);    // decompressor    fo->write(loader + e_len, isCon ? h_len : (d_len + h_len));    // header size is 2048 bytes + sector alignment    fo->write(paddata, (pad + PS_HDR_SIZE) - fo->getBytesWritten());    // entry    fo->write(loader, e_len);    // compressed body    fo->write(obuf, ph.c_len);    verifyOverlappingDecompression();    if (!checkFinalCompressionRatio(fo))        throwNotCompressible();#if 0    printf("%-13s: uncompressed  : %8ld bytes\n", getName(), (long) ph.u_len);    printf("%-13s: compressed    : %8ld bytes\n", getName(), (long) ph.c_len);    printf("%-13s: decompressor  : %8ld bytes\n", getName(), (long) lsize - h_len - pad_code);    printf("%-13s: header comp   : %8ld bytes\n", getName(), (long) sz_cbh);    printf("%-13s: overlap       : %8ld bytes\n", getName(), (long) overlap);    printf("%-13s: load address  : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);    printf("%-13s: code entry    : %08X bytes\n", getName(), (unsigned int) oh.epc);    printf("%-13s: bbs start     : %08X bytes\n", getName(), (unsigned int) bss_start);    printf("%-13s: bbs end       : %08X bytes\n", getName(), (unsigned int) bss_end);    printf("%-13s: eof in mem IF : %08X bytes\n", getName(), (unsigned int) ih.tx_ptr + ih.tx_len);    printf("%-13s: eof in mem OF : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr + oh.tx_len);    unsigned char i = 0;    if (isCon) { if (foundBss) i = 1; }    else { i = 2; if (M_IS_LZMA(ph.method)) { if (!foundBss) i = 3; else i = 4; } }    const char *loader_method[] = { "con/stack", "con/bss", "cdb", "cdb/stack", "cdb/bss" };    char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);    printf("%-13s: methods       : %s, %s\n", getName(), method_name, loader_method[i]);#endif}/*************************************************************************//**************************************************************************/int PackPs1::canUnpack(){    if (!readFileHeader())        return false;    if (!readPackHeader(CD_SEC))        return false;    // check header as set by packer    if (!readBkupHeader() || ph.c_len >= fdata_size)        throwCantUnpack("header damaged");    // generic check    if (!checkFileHeader())        throwCantUnpack("unsupported header flags");    return true;}/*************************************************************************//**************************************************************************/void PackPs1::unpack(OutputFile *fo){    // restore orig exec hdr    memcpy(&oh, &ih, sizeof(ih));    memcpy(&oh.epc, &bh, SZ_IH_BKUP);    // check for removed sector alignment    assert(oh.tx_len >= ph.u_len);    const unsigned pad = oh.tx_len - ph.u_len;    ibuf.alloc(fdata_size > PS_HDR_SIZE ? fdata_size : PS_HDR_SIZE);    obuf.allocForUncompression(ph.u_len, pad);    fi->seek(PS_HDR_SIZE, SEEK_SET);    fi->readx(ibuf, fdata_size);    // decompress    decompress(ibuf + (fdata_size - ph.c_len), obuf);    // write decompressed file    if (fo)    {        // write header        fo->write(&oh, sizeof(oh));        // align the ps exe header (mode 2 sector data size)        ibuf.clear();        fo->write(ibuf, PS_HDR_SIZE - fo->getBytesWritten());        // write uncompressed data + pad        obuf.clear(ph.u_len, pad);        fo->write(obuf, ph.u_len + pad);    }}/*vi:ts=4:et:nowrap*/

⌨️ 快捷键说明

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