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

📄 p_armpe.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            iats.add(idlls[ic]->iat,esize);        }        names.add(idlls[ic]->name,strlen(idlls[ic]->name) + 1 + 1);    }    ppi += 4;    assert(ppi < oimport+soimport);    soimport = ptr_diff(ppi,oimport);    if (soimport == 4)        soimport = 0;    //OutputFile::dump("x0.imp", oimport, soimport);    //OutputFile::dump("x1.imp", oimpdlls, soimpdlls);    unsigned ilen = 0;    names.flatten();    if (names.ivnum > 1)    {        // The area occupied by the dll and imported names is not continuous        // so to still support uncompression, I can't zero the iat area.        // This decreases compression ratio, so FIXME somehow.        infoWarning("can't remove unneeded imports");        ilen += sizeof(import_desc) * dllnum;#if defined(DEBUG)        if (opt->verbose > 3)            names.dump();#endif        // do some work for the unpacker        im = im_save;        for (ic = 0; ic < dllnum; ic++, im++)        {            memset(im,FILLVAL,sizeof(*im));            im->dllname = ptr_diff(idlls[ic]->name,ibuf); // I only need this info        }    }    else    {        iats.add(im_save,sizeof(import_desc) * dllnum);        // zero unneeded data        iats.clear();        lookups.clear();    }    names.clear();    iats.add(&names);    iats.add(&lookups);    iats.flatten();    for (ic = 0; ic < iats.ivnum; ic++)        ilen += iats.ivarr[ic].len;    info("Imports: original size: %u bytes, preprocessed size: %u bytes",ilen,soimport);    return names.ivnum == 1 ? names.ivarr[0].start : 0;}void PackArmPe::processTls(Interval *) // pass 1{    if ((sotls = ALIGN_UP(IDSIZE(PEDIR_TLS),4u)) == 0)        return;    // never should happen on wince    throwCantPack("Static TLS entries found. Send a report please.");}/*************************************************************************// pack**************************************************************************/bool PackArmPe::canPack(){    if (!readFileHeader() || (ih.cpu != 0x1c0 && ih.cpu != 0x1c2))        return false;    use_thumb_stub |= ih.cpu == 0x1c2 || (ih.entry & 1) == 1;    use_thumb_stub |= (opt->cpu == opt->CPU_8086); // FIXME    return true;}void PackArmPe::buildLoader(const Filter *ft){    const unsigned char *loader = use_thumb_stub ? stub_arm_v4t_wince_pe : stub_arm_v4a_wince_pe;    unsigned size = use_thumb_stub ? sizeof(stub_arm_v4t_wince_pe) : sizeof(stub_arm_v4a_wince_pe);    // prepare loader    initLoader(loader, size);    if (isdll)        addLoader("DllStart", NULL);    addLoader("ExeStart", NULL);    if (ph.method == M_NRV2E_8)        addLoader("Call2E", NULL);    else if (ph.method == M_NRV2B_8)        addLoader("Call2B", NULL);    else if (ph.method == M_NRV2D_8)        addLoader("Call2D", NULL);    else if (M_IS_LZMA(ph.method))        addLoader("+40C,CallLZMA", NULL);    if (ft->id == 0x50)        addLoader("+40C,Unfilter_0x50", NULL);    if (sorelocs)        addLoader("+40C,Relocs", NULL);    addLoader("+40C,Imports", NULL);    addLoader("ProcessEnd", NULL);    if (ph.method == M_NRV2E_8)        addLoader(".ucl_nrv2e_decompress_8", NULL);    else if (ph.method == M_NRV2B_8)        addLoader(".ucl_nrv2b_decompress_8", NULL);    else if (ph.method == M_NRV2D_8)        addLoader(".ucl_nrv2d_decompress_8", NULL);    else if (M_IS_LZMA(ph.method))        addLoader("+40C,LZMA_DECODE,LZMA_DEC10", NULL);    addLoader("IDENTSTR,UPX1HEAD", NULL);}void PackArmPe::pack(OutputFile *fo){    // FIXME: we need to think about better support for --exact    if (opt->exact)        throwCantPackExact();    const unsigned objs = ih.objects;    isection = new pe_section_t[objs];    fi->seek(pe_offset+sizeof(ih),SEEK_SET);    fi->readx(isection,sizeof(pe_section_t)*objs);    rvamin = isection[0].vaddr;    infoHeader("[Processing %s, format %s, %d sections]", fn_basename(fi->getName()), getName(), objs);    // check the PE header    // FIXME: add more checks    if (!opt->force && (           (ih.cpu != 0x1c0 && ih.cpu != 0x1c2)        || (ih.opthdrsize != 0xe0)        || ((ih.flags & EXECUTABLE) == 0)        || (ih.subsystem != 9)        || (ih.entry == 0 /*&& !isdll*/)        || (ih.ddirsentries != 16)//        || IDSIZE(PEDIR_EXCEPTION) // is this used on arm?//        || IDSIZE(PEDIR_COPYRIGHT)       ))        throwCantPack("unexpected value in PE header (try --force)");    if (IDSIZE(PEDIR_SEC))        IDSIZE(PEDIR_SEC) = IDADDR(PEDIR_SEC) = 0;    //    throwCantPack("compressing certificate info is not supported");    if (IDSIZE(PEDIR_COMRT))        throwCantPack(".NET files (win32/net) are not yet supported");    if (isdll)        opt->win32_pe.strip_relocs = false;    else if (opt->win32_pe.strip_relocs < 0)        opt->win32_pe.strip_relocs = (ih.imagebase >= 0x10000);    if (opt->win32_pe.strip_relocs)    {        if (ih.imagebase < 0x10000)            throwCantPack("--strip-relocs is not allowed when imagebase < 0x10000");        else            ih.flags |= RELOCS_STRIPPED;    }    if (memcmp(isection[0].name,"UPX",3) == 0)        throwAlreadyPackedByUPX();    if (!opt->force && IDSIZE(15))        throwCantPack("file is possibly packed/protected (try --force)");    if (ih.entry && ih.entry < rvamin)        throwCantPack("run a virus scanner on this file!");    if (!opt->force && ih.subsystem == 1)        throwCantPack("subsystem 'native' is not supported (try --force)");    if (ih.filealign < 0x200)        throwCantPack("filealign < 0x200 is not yet supported");    handleStub(fi,fo,pe_offset);    const unsigned usize = ih.imagesize;    const unsigned xtrasize = UPX_MAX(ih.datasize, 65536u) + IDSIZE(PEDIR_IMPORT) + IDSIZE(PEDIR_BOUNDIM) + IDSIZE(PEDIR_IAT) + IDSIZE(PEDIR_DELAYIMP) + IDSIZE(PEDIR_RELOC);    ibuf.alloc(usize + xtrasize);    // BOUND IMPORT support. FIXME: is this ok?    fi->seek(0,SEEK_SET);    fi->readx(ibuf,isection[0].rawdataptr);    Interval holes(ibuf);    unsigned ic,jc,overlaystart = 0;    ibuf.clear(0, usize);    for (ic = jc = 0; ic < objs; ic++)    {        if (isection[ic].rawdataptr && overlaystart < isection[ic].rawdataptr + isection[ic].size)            overlaystart = ALIGN_UP(isection[ic].rawdataptr + isection[ic].size,ih.filealign);        if (isection[ic].vsize == 0)            isection[ic].vsize = isection[ic].size;        if ((isection[ic].flags & PEFL_BSS) || isection[ic].rawdataptr == 0            || (isection[ic].flags & PEFL_INFO))        {            holes.add(isection[ic].vaddr,isection[ic].vsize);            continue;        }        if (isection[ic].vaddr + isection[ic].size > usize)            throwCantPack("section size problem");        if (((isection[ic].flags & (PEFL_WRITE|PEFL_SHARED))            == (PEFL_WRITE|PEFL_SHARED)))            if (!opt->force)                throwCantPack("writeable shared sections not supported (try --force)");        if (jc && isection[ic].rawdataptr - jc > ih.filealign)            throwCantPack("superfluous data between sections");        fi->seek(isection[ic].rawdataptr,SEEK_SET);        jc = isection[ic].size;        if (jc > isection[ic].vsize)            jc = isection[ic].vsize;        if (isection[ic].vsize == 0) // hack for some tricky programs - may this break other progs?            jc = isection[ic].vsize = isection[ic].size;        if (isection[ic].vaddr + jc > ibuf.getSize())            throwInternalError("buffer too small 1");        fi->readx(ibuf + isection[ic].vaddr,jc);        jc += isection[ic].rawdataptr;    }    // check for NeoLite    if (find(ibuf + ih.entry, 64+7, "NeoLite", 7) >= 0)        throwCantPack("file is already compressed with another packer");    unsigned overlay = file_size - stripDebug(overlaystart);    if (overlay >= (unsigned) file_size)    {#if 0        if (overlay < file_size + ih.filealign)            overlay = 0;        else if (!opt->force)            throwNotCompressible("overlay problem (try --force)");#endif        overlay = 0;    }    checkOverlay(overlay);    Resource res;    Interval tlsiv(ibuf);    Export xport((char*)(unsigned char*)ibuf);    const unsigned dllstrings = processImports();    processTls(&tlsiv); // call before processRelocs!!    processResources(&res);    processExports(&xport);    processRelocs();    //OutputFile::dump("x1", ibuf, usize);    // some checks for broken linkers - disable filter if necessary    bool allow_filter = true;    if (ih.codebase == ih.database        || ih.codebase + ih.codesize > ih.imagesize        || (isection[virta2objnum(ih.codebase,isection,objs)].flags & PEFL_CODE) == 0)        allow_filter = false;    const unsigned oam1 = ih.objectalign - 1;    // FIXME: disabled: the uncompressor would not allocate enough memory    //objs = tryremove(IDADDR(PEDIR_RELOC),objs);    // FIXME: if the last object has a bss then this won't work    // newvsize = (isection[objs-1].vaddr + isection[objs-1].size + oam1) &~ oam1;    // temporary solution:    unsigned newvsize = (isection[objs-1].vaddr + isection[objs-1].vsize + oam1) &~ oam1;    //fprintf(stderr,"newvsize=%x objs=%d\n",newvsize,objs);    if (newvsize + soimport + sorelocs > ibuf.getSize())         throwInternalError("buffer too small 2");    memcpy(ibuf+newvsize,oimport,soimport);    memcpy(ibuf+newvsize+soimport,orelocs,sorelocs);    cimports = newvsize - rvamin;   // rva of preprocessed imports    crelocs = cimports + soimport;  // rva of preprocessed fixups    ph.u_len = newvsize + soimport + sorelocs;    // some extra data for uncompression support    unsigned s = 0;    upx_byte * const p1 = ibuf + ph.u_len;    memcpy(p1 + s,&ih,sizeof (ih));    s += sizeof (ih);    memcpy(p1 + s,isection,ih.objects * sizeof(*isection));    s += ih.objects * sizeof(*isection);    if (soimport)    {        set_le32(p1 + s,cimports);        set_le32(p1 + s + 4,dllstrings);        s += 8;    }    if (sorelocs)    {        set_le32(p1 + s,crelocs);        p1[s + 4] = (unsigned char) (big_relocs & 6);        s += 5;    }    if (soresources)    {        set_le16(p1 + s,icondir_count);        s += 2;    }    // end of extra data    set_le32(p1 + s,ptr_diff(p1,ibuf) - rvamin);    s += 4;    ph.u_len += s;    obuf.allocForCompression(ph.u_len);    // prepare packheader    ph.u_len -= rvamin;    // prepare filter    Filter ft(ph.level);    ft.buf_len = ih.codesize;    ft.addvalue = ih.codebase - rvamin;    // compress    int filter_strategy = allow_filter ? 0 : -3;    // disable filters for files with broken headers    if (ih.codebase + ih.codesize > ph.u_len)    {        ft.buf_len = 1;        filter_strategy = -3;    }    // limit stack size needed for runtime decompression    upx_compress_config_t cconf; cconf.reset();    cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack    compressWithFilters(&ft, 2048, &cconf, filter_strategy,                        ih.codebase, rvamin, 0, NULL, 0);// info: see buildLoader()    newvsize = (ph.u_len + rvamin + ph.overlap_overhead + oam1) &~ oam1;    /*    if (tlsindex && ((newvsize - ph.c_len - 1024 + oam1) &~ oam1) > tlsindex + 4)    tlsindex = 0;    */    const unsigned lsize = getLoaderSize();    int identsize = 0;    const unsigned codesize = getLoaderSection("IDENTSTR",&identsize);    assert(identsize > 0);    getLoaderSection("UPX1HEAD",(int*)&ic);    identsize += ic;    pe_section_t osection[4];    // section 0 : bss    //         1 : [ident + header] + packed_data + unpacker + tls    //         2 : not compressed data    //         3 : resource data -- wince 5 needs a new section for this    // identsplit - number of ident + (upx header) bytes to put into the PE header    int identsplit = pe_offset + sizeof(osection) + sizeof(oh);    if ((identsplit & 0x1ff) == 0)        identsplit = 0;    else if (((identsplit + identsize) ^ identsplit) < 0x200)        identsplit = identsize;    else        identsplit = ALIGN_GAP(identsplit, 0x200);    ic = identsize - identsplit;    const unsigned c_len = ((ph.c_len + ic) & 15) == 0 ? ph.c_len : ph.c_len + 16 - ((ph.c_len + ic) & 15);    obuf.clear(ph.c_len, c_len - ph.c_len);    const unsigned s1size = ALIGN_UP(ic + c_len + codesize,4u) + sotls;    const unsigned s1addr = (newvsize - (ic + c_len) + oam1) &~ oam1;    const unsigned ncsection = (s1addr + s1size + oam1) &~ oam1;    const unsigned upxsection = s1addr + ic + c_len;    Reloc rel(1024); // new relocations are put here    static const char* symbols_to_relocate[] = {        "ONAM", "BIMP", "BREL", "FIBE", "FIBS", "ENTR", "DST0", "SRC0"    };    for (unsigned s2r = 0; s2r < TABLESIZE(symbols_to_relocate); s2r++)    {        unsigned off = linker->getSymbolOffset(symbols_to_relocate[s2r]);        if (off != 0xdeaddead)            rel.add(off + upxsection, 3);

⌨️ 快捷键说明

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