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

📄 p_lx_exc.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
         sizeof(l_info);    if (0 == get_le32(fold_hdrlen + fold)) {        // inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)        fold_hdrlen = umax(0x80, fold_hdrlen);    }  }    // This adds the definition to the "library", to be used later.    // NOTE: the stub is NOT compressed!  The savings is not worth it.    linker->addSection("FOLDEXEC", fold + fold_hdrlen, szfold - fold_hdrlen, 0);    n_mru = ft->n_mru;// Rely on "+80CXXXX" [etc] in getDecompressorSections() packer_c.cpp *///    // Here is a quick summary of the format of the output file://    linker->setLoaderAlignOffset(//            // Elf32_Edhr//        sizeof(elfout.ehdr) +//            // Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86//        (elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +//            // checksum UPX! lsize version format//        sizeof(l_info) +//            // PT_DYNAMIC with DT_NEEDED "forwarded" from original file//        ((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +//            // p_progid, p_filesize, p_blocksize//        sizeof(p_info) +//            // compressed data//        b_len + ph.c_len );//            // entry to stub    addLoader("LEXEC000", NULL);    if (ft->id) {        if (n_mru) {            addLoader("LEXEC009", NULL);        }    }    addLoader("LEXEC010", NULL);    linker->defineSymbol("filter_cto", ft->cto);    linker->defineSymbol("filter_length",                         (ft->id & 0xf) % 3 == 0 ? ft->calls :                         ft->lastcall - ft->calls * 4);    addLoader(getDecompressorSections(), NULL);    addLoader("LEXEC015", NULL);    if (ft->id) {        {  // decompr, unfilter not separate            if (0x80==(ft->id & 0xF0)) {                addLoader("LEXEC110", NULL);                if (n_mru) {                    addLoader("LEXEC100", NULL);                }                // bug in APP: jmp and label must be in same .asx/.asy                addLoader("LEXEC016", NULL);            }        }        addFilter32(ft->id);        {  // decompr always unfilters            addLoader("LEXEC017", NULL);        }    }    else {        addLoader("LEXEC017", NULL);    }    addLoader("IDENTSTR", NULL);    addLoader("LEXEC020", NULL);    addLoader("FOLDEXEC", NULL);    if (M_IS_LZMA(ph.method)) {        const lzma_compress_result_t *res = &ph.compress_result.result_lzma;        acc_uint32e_t properties = // lc, lp, pb, dummy            (res->lit_context_bits << 0) |            (res->lit_pos_bits << 8) |            (res->pos_bits << 16);        if (linker->bele->isBE()) // big endian - bswap32            acc_swab32s(&properties);        linker->defineSymbol("lzma_properties", properties);        // -2 for properties        linker->defineSymbol("lzma_c_len", ph.c_len - 2);        linker->defineSymbol("lzma_u_len", ph.u_len);        unsigned const stack = getDecompressorWrkmemSize();        linker->defineSymbol("lzma_stack_adjust", 0u - stack);    }    if (0x80==(ft->id & 0xF0)) {        int const mru = ft->n_mru ? 1+ ft->n_mru : 0;        if (mru && mru!=256) {            unsigned const is_pwr2 = (0==((mru -1) & mru));            linker->defineSymbol("NMRU", mru - is_pwr2);        }    }    relocateLoader();}voidPackLinuxI386::buildLoader(Filter const *ft){    unsigned const sz_fold = sizeof(stub_i386_linux_elf_execve_fold);    MemBuffer buf(sz_fold);    memcpy(buf, stub_i386_linux_elf_execve_fold, sz_fold);    // patch loader    // note: we only can use /proc/<pid>/fd when exetype > 0.    //   also, we sleep much longer when compressing a script.    checkPatch(NULL, 0, 0, 0);  // reset    patch_le32(buf,sz_fold,"UPX4",exetype > 0 ? 3 : 15);   // sleep time    patch_le32(buf,sz_fold,"UPX3",progid);    patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);    buildLinuxLoader(        stub_i386_linux_elf_execve_entry, sizeof(stub_i386_linux_elf_execve_entry),        buf, sz_fold, ft );}voidPackBSDI386::buildLoader(Filter const *ft){    unsigned const sz_fold = sizeof(stub_i386_bsd_elf_execve_fold);    MemBuffer buf(sz_fold);    memcpy(buf, stub_i386_bsd_elf_execve_fold, sz_fold);    // patch loader    // note: we only can use /proc/<pid>/fd when exetype > 0.    //   also, we sleep much longer when compressing a script.    checkPatch(NULL, 0, 0, 0);  // reset    patch_le32(buf,sz_fold,"UPX4",exetype > 0 ? 3 : 15);   // sleep time    patch_le32(buf,sz_fold,"UPX3",progid);    patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);    buildLinuxLoader(        stub_i386_bsd_elf_execve_entry, sizeof(stub_i386_bsd_elf_execve_entry),        buf, sz_fold, ft );}// FIXME: getLoaderPrefixSize is unused?int PackLinuxI386::getLoaderPrefixSize() const{    return 116;}/*************************************************************************// some ELF utitlity functions**************************************************************************/// basic check of an Linux ELF Ehdrint PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const{    const unsigned char * const buf = ehdr->e_ident;    if (memcmp(buf, "\x7f\x45\x4c\x46\x01\x01\x01", 7)) // ELF 32-bit LSB        return -1;    // now check the ELF header    if (!memcmp(buf+8, "FreeBSD", 7))                  // branded        return 1;    if (ehdr->e_type != Elf32_Ehdr::ET_EXEC    &&  ehdr->e_type != Elf32_Ehdr::ET_DYN )           // executable        return 2;    if (ehdr->e_machine != Elf32_Ehdr::EM_386)         // Intel 80386        return 3;    if (ehdr->e_version != Elf32_Ehdr::EV_CURRENT)     // version        return 4;    if (ehdr->e_phnum < 1)        return 5;    if (ehdr->e_phentsize != sizeof(Elf32_Phdr))        return 6;    // check for Linux kernels    if (ehdr->e_entry == 0xC0100000)                    // uncompressed vmlinux        return 1000;    if (ehdr->e_entry == 0x00001000)                    // compressed vmlinux        return 1001;    if (ehdr->e_entry == 0x00100000)                    // compressed bvmlinux        return 1002;    // FIXME: add more checks for kernels    // FIXME: add special checks for other ELF i386 formats, like    //        NetBSD, OpenBSD, Solaris, ....    // success    return 0;}/*************************************************************************//**************************************************************************/bool PackLinuxI386::canPack(){    if (exetype != 0)        return super::canPack();    Elf_LE32_Ehdr ehdr;    unsigned char *buf = ehdr.e_ident;    fi->seek(0, SEEK_SET);    fi->readx(&ehdr, sizeof(ehdr));    fi->seek(0, SEEK_SET);    exetype = 0;    const unsigned l = get_le32(buf);    int elf = checkEhdr(&ehdr);    if (elf >= 0) {        // NOTE: ELF executables are now handled by p_lx_elf.cpp,        //   so we only handle them here if force_execve        if (elf == 0 && opt->o_unix.force_execve) {            exetype = 1;            unsigned osabi0 = ehdr.e_ident[Elf32_Ehdr::EI_OSABI];            switch (osabi0) {            case Elf32_Ehdr::ELFOSABI_LINUX:            case Elf32_Ehdr::ELFOSABI_FREEBSD:            case Elf32_Ehdr::ELFOSABI_NETBSD:            case Elf32_Ehdr::ELFOSABI_OPENBSD:                ei_osabi = osabi0;  // Proudly declares its osabi in Ehdr.                break;            default:            unsigned const e_phnum = get_native16(&ehdr.e_phnum);            if (e_phnum<=(512/sizeof(Elf32_Phdr))) {                char buf2[512];                fi->seek(get_native32(&ehdr.e_phoff), SEEK_SET);                fi->readx(buf2, sizeof(buf2));                fi->seek(0, SEEK_SET);                Elf32_Phdr const *phdr = (Elf32_Phdr const *)buf2;                for (unsigned j=0; j < e_phnum; ++phdr, ++j) {                    if (phdr->PT_NOTE == get_native32(&phdr->p_type)) {                        unsigned const offset = get_native32(&phdr->p_offset);                        struct Elf32_Note note; memset(&note, 0, sizeof(note));                        fi->seek(offset, SEEK_SET);                        fi->readx(&note, sizeof(note));                        fi->seek(0, SEEK_SET);                        if (4==get_native32(&note.descsz)                        &&  1==get_native32(&note.type)                        &&  0==note.end ) {                            if (0==strcmp("NetBSD", (char const *)&note.text)) {                                ei_osabi = Elf32_Ehdr::ELFOSABI_NETBSD;                                break;                            }                            if (0==strcmp("OpenBSD", (char const *)&note.text)) {                                ei_osabi = Elf32_Ehdr::ELFOSABI_OPENBSD;                                break;                            }                        }                    }                }            }            }        }        if (UPX_F_BSD_i386==getFormat()        && !(Elf32_Ehdr::ELFOSABI_FREEBSD==ei_osabi          || Elf32_Ehdr::ELFOSABI_NETBSD ==ei_osabi          || Elf32_Ehdr::ELFOSABI_OPENBSD==ei_osabi )) {            return false;        }    }    else if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)    {        // OMAGIC / NMAGIC / ZMAGIC / QMAGIC        exetype = 2;        // FIXME: N_TRSIZE, N_DRSIZE        // FIXME: check for aout shared libraries    }    else { // shell scripts and other interpreters        if (Elf32_Ehdr::ELFOSABI_LINUX!=ei_osabi) {            return false;  // so far, only Linux has runtime stub for shell        }        else if (!memcmp(buf, "#!/", 3))                    // #!/bin/sh            exetype = -1;        else if (!memcmp(buf, "#! /", 4))                   // #! /bin/sh            exetype = -1;        else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4))       // Java bytecode            exetype = -2;    }    return super::canPack();}void PackLinuxI386::patchLoader() { }void PackLinuxI386::patchLoaderChecksum(){    unsigned char *const ptr = getLoader();    l_info *const lp = (l_info *)(sizeof(elfout.ehdr) +        (elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout );    // checksum for loader + p_info    lp->l_checksum = 0;    lp->l_magic = UPX_ELF_MAGIC;    lp->l_lsize = (unsigned short) lsize;    lp->l_version = (unsigned char) ph.version;    lp->l_format  = (unsigned char) ph.format;    // INFO: lp->l_checksum is currently unused    lp->l_checksum = upx_adler32(ptr, lsize);}void PackLinuxI386::updateLoader(OutputFile *fo){    elfout.ehdr.e_entry = fo->getBytesWritten() + elfout.phdr[0].p_vaddr;}/*vi:ts=4:et*/

⌨️ 快捷键说明

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