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

📄 p_lx_exc.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* p_lx_exc.cpp --   This file is part of the UPX executable compressor.   Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer   Copyright (C) 1996-2007 Laszlo Molnar   Copyright (C) 2001-2007 John F. Reiser   All Rights Reserved.   UPX and the UCL library are free software; you can redistribute them   and/or modify them under the terms of the GNU General Public License as   published by the Free Software Foundation; either version 2 of   the License, or (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; see the file COPYING.   If not, write to the Free Software Foundation, Inc.,   59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.   Markus F.X.J. Oberhumer              Laszlo Molnar   <mfx@users.sourceforge.net>          <ml1050@users.sourceforge.net>   John F. Reiser   <jreiser@users.sourceforge.net> */#include "conf.h"#include "file.h"#include "filter.h"#include "linker.h"#include "packer.h"#include "p_elf.h"#include "p_unix.h"#include "p_lx_exc.h"#define PT_LOAD     Elf32_Phdr::PT_LOAD#define PT_DYNAMIC  Elf32_Phdr::PT_DYNAMIC#if 0 // UNUSED#define DT_NULL     Elf32_Dyn::DT_NULL#define DT_NEEDED   Elf32_Dyn::DT_NEEDED#define DT_STRTAB   Elf32_Dyn::DT_STRTAB#define DT_STRSZ    Elf32_Dyn::DT_STRSZ#endif/*************************************************************************// linux/386 (generic "execve" format)**************************************************************************/PackLinuxI386::PackLinuxI386(InputFile *f) : super(f),    ei_osabi(Elf32_Ehdr::ELFOSABI_LINUX), osabi_note(NULL){    bele = &N_BELE_RTP::le_policy;}PackBSDI386::PackBSDI386(InputFile *f) : super(f){    // Shell scripts need help specifying the target operating system.    // Elf input will override this with .e_ident[EI_OSABI] or PT_NOTE.    // [2006-09-27: Today's only runtime stub for shell is for linux.]    if (Elf32_Ehdr::ELFOSABI_LINUX==opt->o_unix.osabi0) {        // Disallow an incompatibility.        ei_osabi = Elf32_Ehdr::ELFOSABI_NONE;    }    else {        ei_osabi = opt->o_unix.osabi0;  // might be ELFOSABI_NONE    }}static const#include "stub/i386-linux.elf.execve-entry.h"static const#include "stub/i386-linux.elf.execve-fold.h"static const#include "stub/i386-bsd.elf.execve-entry.h"static const#include "stub/i386-bsd.elf.execve-fold.h"const int *PackLinuxI386::getCompressionMethods(int method, int level) const{    return Packer::getDefaultCompressionMethods_le32(method, level);}const int *PackLinuxI386::getFilters() const{    static const int filters[] = {        0x49, 0x46,        0x26, 0x24, 0x11, 0x14, 0x13, 0x16, 0x25, 0x15, 0x12,#if 0// 0x80..0x87 are regarded as "untested".        0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,        0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,#endif    FT_END };    return filters;}static voidset_stub_brk(Elf_LE32_Phdr *const phdr1, unsigned brka){#define PAGE_MASK (~0ul<<12)        // linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary        unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0);        phdr1->p_type = PT_LOAD;  // be sure        phdr1->p_offset = ~PAGE_MASK & brkb;        phdr1->p_vaddr = brkb;        phdr1->p_paddr = brkb;        phdr1->p_filesz = 0;        phdr1->p_memsz =  0;        if (0==phdr1->p_flags) {            phdr1->p_flags = Elf32_Phdr::PF_R|Elf32_Phdr::PF_W;        }        if (0==phdr1->p_align) {            phdr1->p_align = 0x1000;        }#undef PAGE_MASK}voidPackLinuxI386::generateElfHdr(    OutputFile *fo,    void const *proto,    unsigned const brka){    cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;    cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;    memcpy(h3, proto, sizeof(*h3));  // reads beyond, but OK    assert(h2->ehdr.e_phoff     == sizeof(Elf32_Ehdr));    assert(h2->ehdr.e_shoff     == 0);    assert(h2->ehdr.e_ehsize    == sizeof(Elf32_Ehdr));    assert(h2->ehdr.e_phentsize == sizeof(Elf32_Phdr));    assert(h2->ehdr.e_shnum     == 0);#if 0  //{    unsigned identsize;    char const *const ident = getIdentstr(&identsize);#endif  //}    h2->phdr[0].p_filesz = sizeof(*h2);  // + identsize;    h2->phdr[0].p_memsz  = h2->phdr[0].p_filesz;    // Info for OS kernel to set the brk()    if (brka) {        set_stub_brk(&h2->phdr[1], brka);    }    if (ph.format==UPX_F_LINUX_i386    ||  ph.format==UPX_F_LINUX_SH_i386    ||  ph.format==UPX_F_BSD_i386    ) {        // SELinux, PAx, grSecurity demand no PF_W if PF_X.        // kernel-2.6.12-2.3.legacy_FC3 has a bug which demands        // a PT_LOAD with PF_W, else SIGSEGV when clearing page fragment        // on low page of ".bss", which is the high page of .text.        // So the minimum number of PT_LOAD is 2.        assert(h2->ehdr.e_phnum==2);        memset(&h2->linfo, 0, sizeof(h2->linfo));        fo->write(h2, sizeof(*h2));    }    else if (ph.format==UPX_F_LINUX_ELFI_i386) {        assert(h3->ehdr.e_phnum==3);        memset(&h3->linfo, 0, sizeof(h3->linfo));        fo->write(h3, sizeof(*h3));    }    else {        assert(false);  // unknown ph.format, PackUnix::generateElfHdr    }}voidPackLinuxI386::pack1(OutputFile *fo, Filter &){    // create a pseudo-unique program id for our paranoid stub    progid = getRandomId();    generateElfHdr(fo, stub_i386_linux_elf_execve_fold, 0);}voidPackBSDI386::pack1(OutputFile *fo, Filter &){    // create a pseudo-unique program id for our paranoid stub    progid = getRandomId();    generateElfHdr(fo, stub_i386_bsd_elf_execve_fold, 0);}voidPackLinuxI386::pack4(OutputFile *fo, Filter &ft){    overlay_offset = sizeof(elfout.ehdr) +        (elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +        sizeof(l_info) +        ((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;    unsigned nw = fo->getBytesWritten();    elfout.phdr[0].p_filesz = nw;    nw = 0u-((0u-elfout.phdr[0].p_align) & (0u-nw));  // ALIGN_UP    super::pack4(fo, ft);  // write PackHeader and overlay_offset    set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr);#if 0  // {    // /usr/bin/strip from RedHat 8.0 (binutils-2.13.90.0.2-2)    // generates a 92-byte [only] output, because the "linking view"    // is empty.  This code supplies a "linking view".    // However, 'strip' then generates _plausible_ junk that gets    // "Illegal instruction"  because 'strip' changes p_hdr[1].p_align,    // .p_offset, and .p_vaddr incorrectly.  So the "cure" is worse than    // the disease.  It is obvious that a 92-byte file is bad,    // but it is not obvious that the changed .p_align is bad.    // Also, having a totally empty "linking view" is easier for 'strip'    // to fix: just detect that, and do nothing.    // So, we don't use this code for now [2003-01-11].    // Supply a "linking view" that covers everything,    // so that 'strip' does not omit everything.    Elf_LE32_Shdr shdr;    // The section header string table.    char const shstrtab[] = "\0.\0.shstrtab";    unsigned eod = elfout.phdr[0].p_filesz;    elfout.ehdr.e_shoff = eod;    elfout.ehdr.e_shentsize = sizeof(shdr);    elfout.ehdr.e_shnum = 3;    elfout.ehdr.e_shstrndx = 2;    // An empty Elf32_Shdr for space as a null index.    memset(&shdr, 0, sizeof(shdr));    shdr.sh_type = Elf32_Shdr::SHT_NULL;    fo->write(&shdr, sizeof(shdr));    // Cover all the bits we need at runtime.    memset(&shdr, 0, sizeof(shdr));    shdr.sh_name = 1;    shdr.sh_type = Elf32_Shdr::SHT_PROGBITS;    shdr.sh_flags = Elf32_Shdr::SHF_ALLOC;    shdr.sh_addr = elfout.phdr[0].p_vaddr;    shdr.sh_offset = overlay_offset;    shdr.sh_size = eod - overlay_offset;    shdr.sh_addralign = 4096;    fo->write(&shdr, sizeof(shdr));    // A section header for the section header string table.    memset(&shdr, 0, sizeof(shdr));    shdr.sh_name = 3;    shdr.sh_type = Elf32_Shdr::SHT_STRTAB;    shdr.sh_offset = 3*sizeof(shdr) + eod;    shdr.sh_size = sizeof(shstrtab);    fo->write(&shdr, sizeof(shdr));    fo->write(shstrtab, sizeof(shstrtab));#endif  // }    // 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  /*{*/#undef PAGE_MASK#define PAGE_MASK (~0u<<12)    // pre-calculate for benefit of runtime disappearing act via munmap()    elfout.phdr[0].p_memsz =  PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz);#undef PAGE_MASK#else  /*}{*/    elfout.phdr[0].p_memsz =  elfout.phdr[0].p_filesz;#endif  /*}*/    // rewrite Elf header    fo->seek(0, SEEK_SET);    fo->rewrite(&elfout, overlay_offset);}static unsignedumax(unsigned a, unsigned b){    if (a <= b) {        return b;    }    return a;}Linker *PackLinuxI386::newLinker() const{    return new ElfLinkerX86;}voidPackLinuxI386::buildLinuxLoader(    upx_byte const *const proto,    unsigned        const szproto,    upx_byte const *const fold,    unsigned        const szfold,    Filter const *ft){    initLoader(proto, szproto);    unsigned fold_hdrlen = 0;  if (0 < szfold) {    cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;    fold_hdrlen = sizeof(hf->ehdr) + hf->ehdr.e_phentsize * hf->ehdr.e_phnum +

⌨️ 快捷键说明

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