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

📄 p_w32pe.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        // rva of the most significant byte of member "flags" in section "UPX0"        const unsigned swri = pe_offset + sizeof(oh) + sizeof(pe_section_t) - 1;        // make sure we only touch the minimum number of pages        const unsigned addr = 0u - rvamin + swri;        linker->defineSymbol("swri", addr &  0xfff);    // page offset        // check whether osection[0].flags and osection[1].flags        // are on the same page        linker->defineSymbol("vp_size", ((addr & 0xfff) + 0x28 >= 0x1000) ?                             0x2000 : 0x1000);          // 2 pages or 1 page        linker->defineSymbol("vp_base", addr &~ 0xfff); // page mask        linker->defineSymbol("VirtualProtect", myimport + get_le32(oimpdlls + 16) + 8);    }    linker->defineSymbol("reloc_delt", 0u - (unsigned) ih.imagebase - rvamin);    linker->defineSymbol("start_of_relocs", crelocs);    linker->defineSymbol("ExitProcess", myimport + get_le32(oimpdlls + 16) + 20);    linker->defineSymbol("GetProcAddress", myimport + get_le32(oimpdlls + 16) + 4);    linker->defineSymbol("kernel32_ordinals", myimport);    linker->defineSymbol("LoadLibraryA", myimport + get_le32(oimpdlls + 16));    linker->defineSymbol("start_of_imports", myimport);    linker->defineSymbol("compressed_imports", cimports);#if 0    linker->defineSymbol("VirtualAlloc", myimport + get_le32(oimpdlls + 16) + 12);    linker->defineSymbol("VirtualFree", myimport + get_le32(oimpdlls + 16) + 16);#endif    defineDecompressorSymbols();    defineFilterSymbols(&ft);    linker->defineSymbol("filter_buffer_start", ih.codebase - rvamin);    // in case of overlapping decompression, this hack is needed,    // because windoze zeroes the word pointed by tlsindex before    // it starts programs    linker->defineSymbol("tls_value", (tlsindex + 4 > s1addr) ?                         get_le32(obuf + tlsindex - s1addr - ic) : 0);    linker->defineSymbol("tls_address", tlsindex - rvamin);    linker->defineSymbol("icon_delta", icondir_count - 1);    linker->defineSymbol("icon_offset", ncsection + icondir_offset - rvamin);    const unsigned esi0 = s1addr + ic;    linker->defineSymbol("start_of_uncompressed", 0u - esi0 + rvamin);    linker->defineSymbol("start_of_compressed", esi0 + ih.imagebase);    linker->defineSymbol(isdll ? "PEISDLL1" : "PEMAIN01", upxsection);    //linker->dumpSymbols();    relocateLoader();    const unsigned lsize = getLoaderSize();    MemBuffer loader(lsize);    memcpy(loader,getLoader(),lsize);    patchPackHeader(loader, lsize);    Reloc rel(1024); // new relocations are put here    rel.add(linker->getSymbolOffset("PEMAIN01") + 2, 3);    // new PE header    memcpy(&oh,&ih,sizeof(oh));    oh.filealign = 0x200; // identsplit depends on this    memset(osection,0,sizeof(osection));    oh.entry = upxsection;    oh.objects = 3;    oh.chksum = 0;    // fill the data directory    ODADDR(PEDIR_DEBUG) = 0;    ODSIZE(PEDIR_DEBUG) = 0;    ODADDR(PEDIR_IAT) = 0;    ODSIZE(PEDIR_IAT) = 0;    ODADDR(PEDIR_BOUNDIM) = 0;    ODSIZE(PEDIR_BOUNDIM) = 0;    // tls & loadconf are put into section 1    ic = s1addr + s1size - sotls - soloadconf;    processTls(&rel,&tlsiv,ic);    ODADDR(PEDIR_TLS) = sotls ? ic : 0;    ODSIZE(PEDIR_TLS) = sotls ? 0x18 : 0;    ic += sotls;    processLoadConf(&rel, &loadconfiv, ic);    ODADDR(PEDIR_LOADCONF) = soloadconf ? ic : 0;    ODSIZE(PEDIR_LOADCONF) = soloadconf;    ic += soloadconf;    // these are put into section 2    ic = ncsection;    if (soresources)        processResources(&res,ic);    ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0;    ODSIZE(PEDIR_RESOURCE) = soresources;    ic += soresources;    processImports(ic, 0);    ODADDR(PEDIR_IMPORT) = ic;    ODSIZE(PEDIR_IMPORT) = soimpdlls;    ic += soimpdlls;    processExports(&xport,ic);    ODADDR(PEDIR_EXPORT) = soexport ? ic : 0;    ODSIZE(PEDIR_EXPORT) = soexport;    if (!isdll && opt->win32_pe.compress_exports)    {        ODADDR(PEDIR_EXPORT) = IDADDR(PEDIR_EXPORT);        ODSIZE(PEDIR_EXPORT) = IDSIZE(PEDIR_EXPORT);    }    ic += soexport;    processRelocs(&rel);    ODADDR(PEDIR_RELOC) = soxrelocs ? ic : 0;    ODSIZE(PEDIR_RELOC) = soxrelocs;    ic += soxrelocs;    // this is computed here, because soxrelocs changes some lines above    const unsigned ncsize = soresources + soimpdlls + soexport + soxrelocs;    ic = oh.filealign - 1;    // this one is tricky: it seems windoze touches 4 bytes after    // the end of the relocation data - so we have to increase    // the virtual size of this section    const unsigned ncsize_virt_increase = (ncsize & oam1) == 0 ? 8 : 0;    // fill the sections    strcpy(osection[0].name,"UPX0");    strcpy(osection[1].name,"UPX1");    // after some windoze debugging I found that the name of the sections    // DOES matter :( .rsrc is used by oleaut32.dll (TYPELIBS)    // and because of this lame dll, the resource stuff must be the    // first in the 3rd section - the author of this dll seems to be    // too idiot to use the data directories... M$ suxx 4 ever!    // ... even worse: exploder.exe in NiceTry also depends on this to    // locate version info    strcpy(osection[2].name,soresources ? ".rsrc" : "UPX2");    osection[0].vaddr = rvamin;    osection[1].vaddr = s1addr;    osection[2].vaddr = ncsection;    osection[0].size = 0;    osection[1].size = (s1size + ic) &~ ic;    osection[2].size = (ncsize + ic) &~ ic;    osection[0].vsize = osection[1].vaddr - osection[0].vaddr;    osection[1].vsize = (osection[1].size + oam1) &~ oam1;    osection[2].vsize = (osection[2].size + ncsize_virt_increase + oam1) &~ oam1;    osection[0].rawdataptr = (pe_offset + sizeof(oh) + sizeof(osection) + ic) &~ ic;    osection[1].rawdataptr = osection[0].rawdataptr;    osection[2].rawdataptr = osection[1].rawdataptr + osection[1].size;    osection[0].flags = (unsigned) (PEFL_BSS|PEFL_EXEC|PEFL_WRITE|PEFL_READ);    osection[1].flags = (unsigned) (PEFL_DATA|PEFL_EXEC|PEFL_WRITE|PEFL_READ);    osection[2].flags = (unsigned) (PEFL_DATA|PEFL_WRITE|PEFL_READ);    oh.imagesize = osection[2].vaddr + osection[2].vsize;    oh.bsssize  = osection[0].vsize;    oh.datasize = osection[2].vsize;    oh.database = osection[2].vaddr;    oh.codesize = osection[1].vsize;    oh.codebase = osection[1].vaddr;    // oh.headersize = osection[0].rawdataptr;    oh.headersize = rvamin;    if (rvamin < osection[0].rawdataptr)        throwCantPack("object alignment too small");    if (opt->win32_pe.strip_relocs && !isdll)        oh.flags |= RELOCS_STRIPPED;    //for (ic = 0; ic < oh.filealign; ic += 4)    //    set_le32(ibuf + ic,get_le32("UPX "));    ibuf.clear(0, oh.filealign);    info("Image size change: %u -> %u kBytes",         ih.imagesize / 1024, oh.imagesize / 1024);    infoHeader("[Writing compressed file]");    // write loader + compressed file    fo->write(&oh,sizeof(oh));    fo->write(osection,sizeof(osection));    // some alignment    if (identsplit == identsize)    {        unsigned n = osection[0].rawdataptr - fo->getBytesWritten() - identsize;        assert(n <= oh.filealign);        fo->write(ibuf, n);    }    fo->write(loader + codesize,identsize);    infoWriting("loader", fo->getBytesWritten());    fo->write(obuf,c_len);    infoWriting("compressed data", c_len);    fo->write(loader,codesize);    if (opt->debug.dump_stub_loader)        OutputFile::dump(opt->debug.dump_stub_loader, loader, codesize);    if ((ic = fo->getBytesWritten() & 3) != 0)        fo->write(ibuf,4 - ic);    fo->write(otls,sotls);    fo->write(oloadconf, soloadconf);    if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)        fo->write(ibuf,oh.filealign - ic);    fo->write(oresources,soresources);    fo->write(oimpdlls,soimpdlls);    fo->write(oexport,soexport);    fo->write(oxrelocs,soxrelocs);    if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0)        fo->write(ibuf,oh.filealign - ic);#if 0    printf("%-13s: program hdr  : %8ld bytes\n", getName(), (long) sizeof(oh));    printf("%-13s: sections     : %8ld bytes\n", getName(), (long) sizeof(osection));    printf("%-13s: ident        : %8ld bytes\n", getName(), (long) identsize);    printf("%-13s: compressed   : %8ld bytes\n", getName(), (long) c_len);    printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) codesize);    printf("%-13s: tls          : %8ld bytes\n", getName(), (long) sotls);    printf("%-13s: resources    : %8ld bytes\n", getName(), (long) soresources);    printf("%-13s: imports      : %8ld bytes\n", getName(), (long) soimpdlls);    printf("%-13s: exports      : %8ld bytes\n", getName(), (long) soexport);    printf("%-13s: relocs       : %8ld bytes\n", getName(), (long) soxrelocs);    printf("%-13s: loadconf     : %8ld bytes\n", getName(), (long) soloadconf);#endif    // verify    verifyOverlappingDecompression();    // copy the overlay    copyOverlay(fo, overlay, &obuf);    // finally check the compression ratio    if (!checkFinalCompressionRatio(fo))        throwNotCompressible();}/*************************************************************************// unpack**************************************************************************/int PackW32Pe::canUnpack(){    if (!readFileHeader())        return false;    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);    if (ih.objects < 3)        return -1;    bool is_packed = (ih.objects == 3 &&                      (IDSIZE(15) || ih.entry > isection[1].vaddr));    bool found_ph = false;    if (memcmp(isection[0].name,"UPX",3) == 0)    {        // current version        fi->seek(isection[1].rawdataptr - 64, SEEK_SET);        found_ph = readPackHeader(1024);        if (!found_ph)        {            // old versions            fi->seek(isection[2].rawdataptr, SEEK_SET);            found_ph = readPackHeader(1024);        }    }    if (is_packed && found_ph)        return true;    if (!is_packed && !found_ph)        return -1;    if (is_packed && ih.entry < isection[2].vaddr)    {        unsigned char buf[256];        bool x = false;        memset(buf, 0, sizeof(buf));        try {            fi->seek(ih.entry - isection[1].vaddr + isection[1].rawdataptr, SEEK_SET);            fi->read(buf, sizeof(buf));            static const unsigned char magic[] = "\x8b\x1e\x83\xee\xfc\x11\xdb";            // mov ebx, [esi];    sub esi, -4;    adc ebx,ebx            int offset = find(buf, sizeof(buf), magic, 7);            if (offset >= 0 && find(buf + offset + 1, sizeof(buf) - offset - 1, magic, 7) >= 0)                x = true;        } catch (...) {            //x = true;        }        if (x)            throwCantUnpack("file is modified/hacked/protected; take care!!!");        else            throwCantUnpack("file is possibly modified/hacked/protected; take care!");        return false;   // not reached    }    // FIXME: what should we say here ?    //throwCantUnpack("file is possibly modified/hacked/protected; take care!");    return false;}void PackW32Pe::rebuildImports(upx_byte *& extrainfo){    if (ODADDR(PEDIR_IMPORT) == 0        || ODSIZE(PEDIR_IMPORT) <= sizeof(import_desc))        return;//    const upx_byte * const idata = obuf + get_le32(extrainfo);    OPTR_C(const upx_byte, idata, obuf + get_le32(extrainfo));    const unsigned inamespos = get_le32(extrainfo + 4);    extrainfo += 8;    unsigned sdllnames = 0;//    const upx_byte *import = ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr;//    const upx_byte *p;    IPTR_I(const upx_byte, import, ibuf + IDADDR(PEDIR_IMPORT) - isection[2].vaddr);    OPTR(const upx_byte, p);    for (p = idata; get_le32(p) != 0; ++p)    {        const upx_byte *dname = get_le32(p) + import;        ICHECK(dname, 1);        const unsigned dlen = strlen(dname);        ICHECK(dname, dlen + 1);        sdllnames += dlen + 1;        for (p += 8; *p;)            if (*p == 1)                p += strlen(++p) + 1;            else if (*p == 0xff)                p += 3; // ordinal            else                p += 5;    }    sdllnames = ALIGN_UP(sdllnames, 2u);    upx_byte * const Obuf = obuf - rvamin;    import_desc * const im0 = (import_desc*) (Obuf + ODADDR(PEDIR_IMPORT));    import_desc *im = im0;    upx_byte *dllnames = Obuf + inamespos;    upx_byte *importednames = dllnames + sdllnames;    upx_byte * const importednames_start = importednames;    for (p = idata; get_le32(p) != 0; ++p)    {        // restore the name of the dll        const upx_byte *dname = get_le32(p) + import;        ICHECK(dname, 1);        const unsigned dlen = strlen(dname);        ICHECK(dname, dlen + 1);        const unsigned iatoffs = get_le32(p + 4) + rvamin;        if (inamespos)        {            // now I rebuild the dll names            OCHECK(dllnames, dlen + 1);            strcpy(dllnames, dname);            im->dllname = ptr_diff(dllnames,Obuf);            //;;;printf("\ndll: %s:",dllnames);            dllnames += dlen + 1;        }        else        {            OCHECK(Obuf + im->dllname, dlen + 1);            strcpy(Obuf + im->dllname, dname);        }        im->iat = iatoffs;//        LE32 *newiat = (LE32 *) (Obuf + iatoffs);        OPTR_I(LE32, newiat, (LE32 *) (Obuf + iatoffs));        // restore the imported names+ordinals        for (p += 8; *p; ++newiat)            if (*p == 1)            {                const unsigned ilen = strlen(++p) + 1;                if (inamespos)                {                    if (ptr_diff(importednames, importednames_start) & 1)                        importednames -= 1;                    omemcpy(importednames + 2, p, ilen);                    //;;;printf(" %s",importednames+2);                    *newiat = ptr_diff(importednames, Obuf);                    importednames += 2 + ilen;                }                else                {                    OCHECK(Obuf + *newiat + 2, ilen + 1);                    strcpy(Obuf + *newiat + 2, p);                }                p += ilen;            }            else if (*p == 0xff)            {                *newiat = get_le16(p + 1) + 0x80000000;                //;;;printf(" %x",(unsigned)*newiat);                p += 3;            }            else            {                *newiat = get_le32(get_le32(p + 1) + import);                assert(*newiat & 0x80000000);                p += 5;            }        *newiat = 0;        im++;    }    //memset(idata,0,p - idata);}/* extra info added to help uncompression: <ih sizeof(pe_head)> <pe_section_t objs*sizeof(pe_section_t)> <start of compressed imports 4> - optional           \ <start of the names from uncompressed imports> - opt / <start of compressed relocs 4> - optional   \ <relocation type indicator 1> - optional    / <icondir_count 2> - optional <offset of extra info 4>*//*vi:ts=4:et*/

⌨️ 快捷键说明

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