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

📄 p_lx_elf.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    static const int f_none[] = { FT_END };    return f_none;}const int *PackLinuxElf32mipsel::getFilters() const{    static const int f_none[] = { FT_END };    return f_none;}void PackLinuxElf32::ARM_defineSymbols(Filter const * /*ft*/){    unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);    lsize = /*getLoaderSize()*/  4 * 1024;  // upper bound; avoid circularity    unsigned const lo_va_user = 0x8000;  // XXX    unsigned lo_va_stub = get_native32(&elfout.phdr[0].p_vaddr);    unsigned adrc;    unsigned adrm;    unsigned adrx;    bool const is_big = true;    if (is_big) {        set_native32(    &elfout.ehdr.e_entry, linker->getSymbolOffset("_start") +            get_native32(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub);        set_native32(&elfout.phdr[0].p_vaddr, lo_va_user);        set_native32(&elfout.phdr[0].p_paddr, lo_va_user);                              lo_va_stub    = lo_va_user;        adrc = lo_va_stub;        adrm = getbrk(phdri, get_native16(&ehdri.e_phnum));        adrx = hlen + (page_mask & (~page_mask + adrm));  // round up to page boundary    }    adrm = page_mask & (~page_mask + adrm);  // round up to page boundary    adrc = page_mask & (~page_mask + adrc);  // round up to page boundary    linker->defineSymbol("CPR0", 4+ linker->getSymbolOffset("cpr0"));    linker->defineSymbol("LENF", 4+ linker->getSymbolOffset("end_decompress"));    linker->defineSymbol("ADRM", adrm);  // addr for map}void PackLinuxElf32armLe::defineSymbols(Filter const *ft){    ARM_defineSymbols(ft);}void PackLinuxElf32armBe::defineSymbols(Filter const *ft){    ARM_defineSymbols(ft);}void PackLinuxElf32mipseb::defineSymbols(Filter const * /*ft*/){    unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);    // We want to know if compressed data, plus stub, plus a couple pages,    // will fit below the uncompressed program in memory.  But we don't    // know the final total compressed size yet, so use the uncompressed    // size (total over all PT_LOAD32) as an upper bound.    unsigned len = 0;    unsigned lo_va_user = ~0u;  // infinity    for (int j= get_native16(&ehdri.e_phnum); --j>=0; ) {        if (PT_LOAD32 == get_native32(&phdri[j].p_type)) {            len += (unsigned)get_native32(&phdri[j].p_filesz);            unsigned const va = get_native32(&phdri[j].p_vaddr);            if (va < lo_va_user) {                lo_va_user = va;            }        }    }    lsize = /*getLoaderSize()*/  64 * 1024;  // XXX: upper bound; avoid circularity    unsigned lo_va_stub = get_native32(&elfout.phdr[0].p_vaddr);    unsigned adrc;    unsigned adrm;    unsigned adru;    unsigned adrx;    unsigned cntc;    unsigned lenm;    unsigned lenu;    len += (7&-lsize) + lsize;    bool const is_big = (lo_va_user < (lo_va_stub + len + 2*page_size));    if (is_big) {        set_native32(    &elfout.ehdr.e_entry,            get_native32(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub);        set_native32(&elfout.phdr[0].p_vaddr, lo_va_user);        set_native32(&elfout.phdr[0].p_paddr, lo_va_user);               lo_va_stub      = lo_va_user;        adrc = lo_va_stub;        adrm = getbrk(phdri, get_native16(&ehdri.e_phnum));        adru = page_mask & (~page_mask + adrm);  // round up to page boundary        adrx = adru + hlen;        lenm = page_size + len;        lenu = page_size + len;        cntc = len >> 3;  // over-estimate; corrected at runtime    }    else {        adrm = lo_va_stub + len;        adrc = adrm;        adru = lo_va_stub;        adrx = lo_va_stub + hlen;        lenm = page_size;        lenu = page_size + len;        cntc = 0;    }    adrm = page_mask & (~page_mask + adrm);  // round up to page boundary    adrc = page_mask & (~page_mask + adrc);  // round up to page boundary    linker->defineSymbol("ADRX", adrx); // compressed input for eXpansion    // For actual moving, we need the true count, which depends on sz_pack2    // and is not yet known.  So the runtime stub detects "no move"    // if adrm==adrc, and otherwise uses actual sz_pack2 to compute cntc.    //linker->defineSymbol("CNTC", cntc);  // count  for copy    linker->defineSymbol("ADRC", adrc);  // addr for copy    linker->defineSymbol("LENU", lenu);  // len  for unmap    linker->defineSymbol("ADRU", adru);  // addr for unmap    linker->defineSymbol("LENM", lenm);  // len  for map    linker->defineSymbol("ADRM", adrm);  // addr for map    //linker->dumpSymbols();  // debug}void PackLinuxElf32mipsel::defineSymbols(Filter const * /*ft*/){    unsigned const hlen = sz_elf_hdrs + sizeof(l_info) + sizeof(p_info);    // We want to know if compressed data, plus stub, plus a couple pages,    // will fit below the uncompressed program in memory.  But we don't    // know the final total compressed size yet, so use the uncompressed    // size (total over all PT_LOAD32) as an upper bound.    unsigned len = 0;    unsigned lo_va_user = ~0u;  // infinity    for (int j= get_native16(&ehdri.e_phnum); --j>=0; ) {        if (PT_LOAD32 == get_native32(&phdri[j].p_type)) {            len += (unsigned)get_native32(&phdri[j].p_filesz);            unsigned const va = get_native32(&phdri[j].p_vaddr);            if (va < lo_va_user) {                lo_va_user = va;            }        }    }    lsize = /*getLoaderSize()*/  64 * 1024;  // XXX: upper bound; avoid circularity    unsigned lo_va_stub = get_native32(&elfout.phdr[0].p_vaddr);    unsigned adrc;    unsigned adrm;    unsigned adru;    unsigned adrx;    unsigned cntc;    unsigned lenm;    unsigned lenu;    len += (7&-lsize) + lsize;    bool const is_big = (lo_va_user < (lo_va_stub + len + 2*page_size));    if (is_big) {        set_native32(    &elfout.ehdr.e_entry,            get_native32(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub);        set_native32(&elfout.phdr[0].p_vaddr, lo_va_user);        set_native32(&elfout.phdr[0].p_paddr, lo_va_user);               lo_va_stub      = lo_va_user;        adrc = lo_va_stub;        adrm = getbrk(phdri, get_native16(&ehdri.e_phnum));        adru = page_mask & (~page_mask + adrm);  // round up to page boundary        adrx = adru + hlen;        lenm = page_size + len;        lenu = page_size + len;        cntc = len >> 3;  // over-estimate; corrected at runtime    }    else {        adrm = lo_va_stub + len;        adrc = adrm;        adru = lo_va_stub;        adrx = lo_va_stub + hlen;        lenm = page_size;        lenu = page_size + len;        cntc = 0;    }    adrm = page_mask & (~page_mask + adrm);  // round up to page boundary    adrc = page_mask & (~page_mask + adrc);  // round up to page boundary    linker->defineSymbol("ADRX", adrx); // compressed input for eXpansion    // For actual moving, we need the true count, which depends on sz_pack2    // and is not yet known.  So the runtime stub detects "no move"    // if adrm==adrc, and otherwise uses actual sz_pack2 to compute cntc.    //linker->defineSymbol("CNTC", cntc);  // count  for copy    linker->defineSymbol("ADRC", adrc);  // addr for copy    linker->defineSymbol("LENU", lenu);  // len  for unmap    linker->defineSymbol("ADRU", adru);  // addr for unmap    linker->defineSymbol("LENM", lenm);  // len  for map    linker->defineSymbol("ADRM", adrm);  // addr for map    //linker->dumpSymbols();  // debug}void PackLinuxElf32::pack4(OutputFile *fo, Filter &ft){    overlay_offset = sz_elf_hdrs + sizeof(linfo);    unsigned const zero = 0;    unsigned len = fo->getBytesWritten();    fo->write(&zero, 3& -len);  // align to 0 mod 4    len += 3& -len;    set_native32(&elfout.phdr[0].p_filesz, len);    super::pack4(fo, ft);  // write PackHeader and overlay_offset    // Cannot pre-round .p_memsz.  If .p_filesz < .p_memsz, then kernel    // tries to make .bss, which requires PF_W.    // But strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X.#if 0  /*{*/    // pre-calculate for benefit of runtime disappearing act via munmap()    set_native32(&elfout.phdr[0].p_memsz, page_mask & (~page_mask + len));#else  /*}{*/    set_native32(&elfout.phdr[0].p_memsz, len);#endif  /*}*/    // rewrite Elf header    if (Elf32_Ehdr::ET_DYN==get_native16(&ehdri.e_type)) {        unsigned const base= get_native32(&elfout.phdr[0].p_vaddr);        set_native16(&elfout.ehdr.e_type, Elf32_Ehdr::ET_DYN);        set_native16(&elfout.ehdr.e_phnum, 1);        set_native32(    &elfout.ehdr.e_entry,            get_native32(&elfout.ehdr.e_entry) -  base);        set_native32(&elfout.phdr[0].p_vaddr, get_native32(&elfout.phdr[0].p_vaddr) - base);        set_native32(&elfout.phdr[0].p_paddr, get_native32(&elfout.phdr[0].p_paddr) - base);        // Strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X        //elfout.phdr[0].p_flags |= Elf32_Phdr::PF_W;    }    fo->seek(0, SEEK_SET);    if (Elf32_Phdr::PT_NOTE==get_native32(&elfout.phdr[2].p_type)) {        unsigned const reloc = get_native32(&elfout.phdr[0].p_vaddr);        set_native32(            &elfout.phdr[2].p_vaddr,            reloc + get_native32(&elfout.phdr[2].p_vaddr));        set_native32(            &elfout.phdr[2].p_paddr,            reloc + get_native32(&elfout.phdr[2].p_paddr));        fo->rewrite(&elfout, sz_elf_hdrs);        fo->rewrite(&elfnote, sizeof(elfnote));    }    else {        fo->rewrite(&elfout, sz_elf_hdrs);    }    fo->rewrite(&linfo, sizeof(linfo));}void PackLinuxElf64::pack4(OutputFile *fo, Filter &ft){    overlay_offset = sz_elf_hdrs + sizeof(linfo);    unsigned const zero = 0;    unsigned len = fo->getBytesWritten();    fo->write(&zero, 3& -len);  // align to 0 mod 4    len += 3& -len;    set_native64(&elfout.phdr[0].p_filesz, len);    super::pack4(fo, ft);  // write PackHeader and overlay_offset    // Cannot pre-round .p_memsz.  If .p_filesz < .p_memsz, then kernel    // tries to make .bss, which requires PF_W.    // But strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X.#if 0  /*{*/    // pre-calculate for benefit of runtime disappearing act via munmap()    set_native64(&elfout.phdr[0].p_memsz, page_mask & (~page_mask + len));#else  /*}{*/    set_native64(&elfout.phdr[0].p_memsz, len);#endif  /*}*/    // rewrite Elf header    fo->seek(0, SEEK_SET);    fo->rewrite(&elfout, sz_elf_hdrs);    fo->rewrite(&linfo, sizeof(linfo));}void PackLinuxElf32::unpack(OutputFile *fo){#define MAX_ELF_HDR 512    char bufehdr[MAX_ELF_HDR];    Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)bufehdr;    Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ehdr);    unsigned szb_info = sizeof(b_info);    {        fi->seek(0, SEEK_SET);        fi->readx(bufehdr, MAX_ELF_HDR);        unsigned const e_entry = get_native32(&ehdr->e_entry);        if (e_entry < 0x401180        &&  ehdr->e_machine==Elf32_Ehdr::EM_386) { /* old style, 8-byte b_info */            szb_info = 2*sizeof(unsigned);        }    }    fi->seek(overlay_offset, SEEK_SET);    p_info hbuf;    fi->readx(&hbuf, sizeof(hbuf));    unsigned orig_file_size = get_native32(&hbuf.p_filesize);    blocksize = get_native32(&hbuf.p_blocksize);    if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)        throwCantUnpack("file header corrupted");    ibuf.alloc(blocksize + OVERHEAD);    b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));    fi->readx(&bhdr, szb_info);    ph.u_len = get_native32(&bhdr.sz_unc);    ph.c_len = get_native32(&bhdr.sz_cpr);    ph.filter_cto = bhdr.b_cto8;    // Uncompress Ehdr and Phdrs.    fi->readx(ibuf, ph.c_len);    decompress(ibuf, (upx_byte *)ehdr, false);    unsigned total_in = 0;    unsigned total_out = 0;    unsigned c_adler = upx_adler32(NULL, 0);    unsigned u_adler = upx_adler32(NULL, 0);    // decompress PT_LOAD32    bool first_PF_X = true;    unsigned const phnum = get_native16(&ehdr->e_phnum);    fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);    for (unsigned j=0; j < phnum; ++phdr, ++j) {        if (PT_LOAD32==get_native32(&phdr->p_type)) {            unsigned const filesz = get_native32(&phdr->p_filesz);            unsigned const offset = get_native32(&phdr->p_offset);            if (fo)                fo->seek(offset, SEEK_SET);            if (Elf32_Phdr::PF_X & get_native32(&phdr->p_flags)) {                unpackExtent(filesz, fo, total_in, total_out,                    c_adler, u_adler, first_PF_X, szb_info);                first_PF_X = false;            }            else {                unpackExtent(filesz, fo, total_in, total_out,                    c_adler, u_adler, false, szb_info);            }        }    }    phdr = (Elf32_Phdr *)(1+ehdr);    for (unsigned j = 0; j < phnum; ++j) {        unsigned const size = find_LOAD_gap(phdr, j, phnum);        if (size) {            unsigned const where = get_native32(&phdr[j].p_offset) +                                   get_native32(&phdr[j].p_filesz);            if (fo)                fo->seek(where, SEEK_SET);            unpackExtent(size, fo, total_in, total_out,                c_adler, u_adler, false, szb_info);        }    }    // check for end-of-file    fi->readx(&bhdr, szb_info);    unsigned const sz_unc = ph.u_len = get_native32(&bhdr.sz_unc);    if (sz_unc == 0) { // uncompressed size 0 -> EOF        // note: magic is always stored le32        unsigned const sz_cpr = get_le32(&bhdr.sz_cpr);        if (sz_cpr != UPX_MAGIC_LE32)  // sz_cpr must be h->magic            throwCompressedDataViolation();    }    else { // extra bytes after end?        throwCompressedDataViolation();    }    // update header with totals    ph.c_len = total_in;    ph.u_len = total_out;    // all bytes must be written    if (total_out != orig_file_size)        throwEOFException();    // finally test the checksums    if (ph.c_adler != c_adler || ph.u_adler != u_adler)        throwChecksumError();#undef MAX_ELF_HDR}void PackLinuxElf64::unpack(OutputFile *fo){#define MAX_ELF_HDR 1024    char bufehdr[MAX_ELF_HDR];    Elf64_Ehdr *const ehdr = (Elf64_Ehdr *)bufehdr;    Elf64_Phdr const *phdr = (Elf64_Phdr *)(1+ehdr);    unsigned szb_info = sizeof(b_info);    {        fi->seek(0, SEEK_SET);        fi->readx(bufehdr, MAX_ELF_HDR);        acc_uint64l_t const e_entry = get_native64(&ehdr->e_entry);        if (e_entry < 0x401180        &&  ehdr->e_machine==Elf64_Ehdr::EM_386) { /* old style, 8-byte b_info */            szb_info = 2*sizeof(unsigned);        }    }    fi->seek(overlay_offset, SEEK_SET);    p_info hbuf;    fi->readx(&hbuf, sizeof

⌨️ 快捷键说明

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