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

📄 p_lx_elf.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
voidPackLinuxElf64amd::buildLoader(const Filter *ft){    buildLinuxLoader(        stub_amd64_linux_elf_entry, sizeof(stub_amd64_linux_elf_entry),        stub_amd64_linux_elf_fold,  sizeof(stub_amd64_linux_elf_fold), ft);}Elf32_Shdr const *PackLinuxElf32::elf_find_section_name(    char const *const name) const{    Elf32_Shdr const *shdr = shdri;    int j = n_elf_shnum;    for (; 0 <=--j; ++shdr) {        if (0==strcmp(name, &shstrtab[shdr->sh_name])) {            return shdr;        }    }    return 0;}Elf32_Shdr const *PackLinuxElf32::elf_find_section_type(    unsigned const type) const{    Elf32_Shdr const *shdr = shdri;    int j = n_elf_shnum;    for (; 0 <=--j; ++shdr) {        if (type==shdr->sh_type) {            return shdr;        }    }    return 0;}bool PackLinuxElf32::canPack(){    unsigned char buf[sizeof(Elf32_Ehdr) + 14*sizeof(Elf32_Phdr)];    COMPILE_TIME_ASSERT(sizeof(buf) <= 512);    fi->seek(0, SEEK_SET);    fi->readx(buf, sizeof(buf));    fi->seek(0, SEEK_SET);    Elf32_Ehdr const *const ehdr = (Elf32_Ehdr const *)buf;    // now check the ELF header    if (checkEhdr(ehdr) != 0)        return false;    // additional requirements for linux/elf386    if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) {        throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");        return false;    }    unsigned const e_shoff = get_native32(&ehdr->e_shoff);    unsigned const e_phoff = get_native32(&ehdr->e_phoff);    if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr        throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");        return false;    }    unsigned osabi0 = buf[Elf32_Ehdr::EI_OSABI];    // The first PT_LOAD32 must cover the beginning of the file (0==p_offset).    unsigned const e_phnum = get_native16(&ehdr->e_phnum);    Elf32_Phdr const *phdr = (Elf32_Phdr const *)(buf + e_phoff);    for (unsigned j=0; j < e_phnum; ++phdr, ++j) {        if (j >= 14)                return false;        unsigned const p_type = get_native32(&phdr->p_type);        unsigned const p_offset = get_native32(&phdr->p_offset);        if (1!=exetype && phdr->PT_LOAD32 == p_type) {            if (p_offset != 0) {                throwCantPack("invalid Phdr p_offset; try '--force-execve'");                return false;            }            exetype = 1;        }        if (Elf32_Ehdr::ELFOSABI_NONE==osabi0  // Still seems to be generic.        && NULL!=osabi_note && phdr->PT_NOTE == p_type) {            struct Elf32_Note note; memset(&note, 0, sizeof(note));            fi->seek(p_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            &&  (1+ strlen(osabi_note))==get_native32(&note.namesz)            &&  0==strcmp(osabi_note, (char const *)&note.text)            ) {                osabi0 = ei_osabi;  // Specified by PT_NOTE.            }        }    }    if (Elf32_Ehdr::ELFOSABI_NONE==osabi0) { // No EI_OSBAI, no PT_NOTE.        osabi0 = opt->o_unix.osabi0;  // Possibly specified by command-line.    }    if (osabi0!=ei_osabi) {        return false;    }    // We want to compress position-independent executable (gcc -pie)    // main programs, but compressing a shared library must be avoided    // because the result is no longer usable.  In theory, there is no way    // to tell them apart: both are just ET_DYN.  Also in theory,    // neither the presence nor the absence of any particular symbol name    // can be used to tell them apart; there are counterexamples.    // However, we will use the following heuristic suggested by    // Peter S. Mazinger <ps.m@gmx.net> September 2005:    // If a ET_DYN has __libc_start_main as a global undefined symbol,    // then the file is a position-independent executable main program    // (that depends on libc.so.6) and is eligible to be compressed.    // Otherwise (no __libc_start_main as global undefined): skip it.    // Also allow  __uClibc_main  and  __uClibc_start_main .    if (Elf32_Ehdr::ET_DYN==get_native16(&ehdr->e_type)) {        // The DT_STRTAB has no designated length.  Read the whole file.        file_image = new char[file_size];        fi->seek(0, SEEK_SET);        fi->readx(file_image, file_size);        ehdri= *ehdr;        phdri= (Elf32_Phdr *)(e_phoff + file_image);  // do not free() !!        shdri= (Elf32_Shdr *)(e_shoff + file_image);  // do not free() !!        n_elf_shnum = get_native16(&ehdr->e_shnum);        shdri = (Elf32_Shdr const *)(e_shoff + file_image);        //sec_strndx = &shdri[ehdr->e_shstrndx];        //shstrtab = (char const *)(sec_strndx->sh_offset + file_image);        sec_dynsym = elf_find_section_type(Elf32_Shdr::SHT_DYNSYM);        sec_dynstr = get_native32(&sec_dynsym->sh_link) + shdri;        int j= e_phnum;        phdr= phdri;        for (; --j>=0; ++phdr) if (Elf32_Phdr::PT_DYNAMIC==get_native32(&phdr->p_type)) {            dynseg= (Elf32_Dyn const *)(get_native32(&phdr->p_offset) + file_image);            break;        }        // elf_find_dynamic() returns 0 if 0==dynseg.        gashtab= (unsigned int const *)elf_find_dynamic(Elf32_Dyn::DT_GNU_HASH);        hashtab= (unsigned int const *)elf_find_dynamic(Elf32_Dyn::DT_HASH);        dynstr=          (char const *)elf_find_dynamic(Elf32_Dyn::DT_STRTAB);        dynsym=     (Elf32_Sym const *)elf_find_dynamic(Elf32_Dyn::DT_SYMTAB);        // FIXME 2007-09-10  It seems that DT_GNU_HASH does not have undefined        // symbols.  So if no DT_HASH, then we would have to look in .dynsym.        char const *const run_start[]= {            "__libc_start_main", "__uClibc_main", "__uClibc_start_main",        };        for (j=0; j<3; ++j) {            // elf_lookup() returns 0 if any required table is missing.            Elf32_Sym const *const lsm = elf_lookup(run_start[j]);            if (lsm && get_native16(&lsm->st_shndx)==Elf32_Sym::SHN_UNDEF            && get_native16(&lsm->st_info)==lsm->Elf32_Sym::make_st_info(Elf32_Sym::STB_GLOBAL, Elf32_Sym::STT_FUNC)            && get_native16(&lsm->st_other)==Elf32_Sym::STV_DEFAULT ) {                break;            }            if (sec_dynsym) {                Elf32_Sym const *symp = (Elf32_Sym const *)(get_native32(&sec_dynsym->sh_offset) + file_image);                Elf32_Sym const *const symlwa = (Elf32_Sym const *)(                    get_native32(&sec_dynsym->sh_size) +                    get_native32(&sec_dynsym->sh_offset) + file_image);                for (; symp < symlwa; ++symp)                if (0==strcmp(run_start[j], get_native32(&symp->st_name) + dynstr)) {                    goto found;                }            }        }found:        phdri = 0;  // done "borrowing" this member        if (3<=j) {            return false;        }    }    // XXX Theoretically the following test should be first,    // but PackUnix::canPack() wants 0!=exetype ?    if (!super::canPack())        return false;    assert(exetype == 1);    exetype = 0;    // set options    opt->o_unix.blocksize = blocksize = file_size;    return true;}boolPackLinuxElf64amd::canPack(){    unsigned char buf[sizeof(Elf64_Ehdr) + 14*sizeof(Elf64_Phdr)];    COMPILE_TIME_ASSERT(sizeof(buf) <= 1024);    fi->readx(buf, sizeof(buf));    fi->seek(0, SEEK_SET);    Elf64_Ehdr const *const ehdr = (Elf64_Ehdr const *)buf;    // now check the ELF header    if (checkEhdr(ehdr) != 0)        return false;    // additional requirements for linux/elf386    if (get_native16(&ehdr->e_ehsize) != sizeof(*ehdr)) {        throwCantPack("invalid Ehdr e_ehsize; try '--force-execve'");        return false;    }    acc_uint64l_t const e_phoff = get_native64(&ehdr->e_phoff);    if (e_phoff != sizeof(*ehdr)) {// Phdrs not contiguous with Ehdr        throwCantPack("non-contiguous Ehdr/Phdr; try '--force-execve'");        return false;    }    // The first PT_LOAD64 must cover the beginning of the file (0==p_offset).    unsigned const e_phnum = get_native16(&ehdr->e_phnum);    Elf64_Phdr const *phdr = (Elf64_Phdr const *)(buf + (unsigned) e_phoff);    for (unsigned j=0; j < e_phnum; ++phdr, ++j) {        if (j >= 14)            return false;        if (phdr->PT_LOAD64 == get_native32(&phdr->p_type)) {            // Just avoid the "rewind" when unpacking?            //if (phdr->p_offset != 0) {            //    throwCantPack("invalid Phdr p_offset; try '--force-execve'");            //    return false;            //}            exetype = 1;            break;        }    }    if (!super::canPack())        return false;    assert(exetype == 1);    exetype = 0;    // set options    opt->o_unix.blocksize = blocksize = file_size;    return true;}off_tPackLinuxElf32::getbrk(const Elf32_Phdr *phdr, int e_phnum) const{    off_t brka = 0;    for (int j = 0; j < e_phnum; ++phdr, ++j) {        if (PT_LOAD32 == get_native32(&phdr->p_type)) {            off_t b = get_native32(&phdr->p_vaddr) + get_native32(&phdr->p_memsz);            if (b > brka)                brka = b;        }    }    return brka;}off_tPackLinuxElf32::getbase(const Elf32_Phdr *phdr, int e_phnum) const{    off_t base = ~0u;    for (int j = 0; j < e_phnum; ++phdr, ++j) {        if (phdr->PT_LOAD == phdr->p_type) {            if (phdr->p_vaddr < (unsigned) base)                base = phdr->p_vaddr;        }    }    if (0!=base) {        return base;    }    return 0x12000;}off_tPackLinuxElf64::getbrk(const Elf64_Phdr *phdr, int e_phnum) const{    off_t brka = 0;    for (int j = 0; j < e_phnum; ++phdr, ++j) {        if (PT_LOAD64 == get_native32(&phdr->p_type)) {            off_t b = get_native64(&phdr->p_vaddr) + get_native64(&phdr->p_memsz);            if (b > brka)                brka = b;        }    }    return brka;}voidPackLinuxElf32::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    h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi;    if (Elf32_Ehdr::EM_MIPS==e_machine) { // MIPS R3000  FIXME        h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = Elf32_Ehdr::ELFOSABI_NONE;        h3->ehdr.e_flags = ehdri.e_flags;    }    assert(get_native32(&h2->ehdr.e_phoff)     == sizeof(Elf32_Ehdr));                         h2->ehdr.e_shoff = 0;    assert(get_native16(&h2->ehdr.e_ehsize)    == sizeof(Elf32_Ehdr));    assert(get_native16(&h2->ehdr.e_phentsize) == sizeof(Elf32_Phdr));           set_native16(&h2->ehdr.e_shentsize, sizeof(Elf32_Shdr));                         h2->ehdr.e_shnum = 0;                         h2->ehdr.e_shstrndx = 0;    sz_elf_hdrs = sizeof(*h2) - sizeof(linfo);  // default    set_native32(&h2->phdr[0].p_filesz, sizeof(*h2));  // + identsize;                  h2->phdr[0].p_memsz = h2->phdr[0].p_filesz;    unsigned const e_phnum = get_native16(&ehdri.e_phnum);    Elf32_Phdr const *phdr = phdri;    for (unsigned j=0; j < e_phnum; ++phdr, ++j) {        if (phdr->PT_LOAD32 == get_native32(&phdr->p_type)) {            unsigned x = get_native32(&phdr->p_align) >> lg2_page;            while (x>>=1) {                ++lg2_page;            }        }    }    page_size =  1u<<lg2_page;    page_mask = ~0u<<lg2_page;    for (unsigned j=0; j < 3; ++j) {        set_native32(&h3->phdr[j].p_align, page_size);    }    // Info for OS kernel to set the brk()    if (brka) {        // 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);        set_native32(&h2->phdr[1].p_type, PT_LOAD32);  // be sure        set_native32(&h2->phdr[1].p_offset, ~page_mask & brkb);        set_native32(&h2->phdr[1].p_vaddr, brkb);        set_native32(&h2->phdr[1].p_paddr, brkb);        h2->phdr[1].p_filesz = 0;        h2->phdr[1].p_memsz =  0;        set_native32(&h2->phdr[1].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);    }    if (ph.format==getFormat()) {        assert(2==get_native16(&h2->ehdr.e_phnum));        set_native32(&h2->phdr[0].p_flags, ~Elf32_Phdr::PF_W & get_native32(&h2->phdr[0].p_flags));        memset(&h2->linfo, 0, sizeof(h2->linfo));        fo->write(h2, sizeof(*h2));    }    else {        assert(false);  // unknown ph.format, PackLinuxElf32    }}voidPackOpenBSDElf32x86::generateElfHdr(    OutputFile *fo,    void const *proto,    unsigned const brka){    cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;    memcpy(h3, proto, sizeof(*h3));  // reads beyond, but OK    h3->ehdr.e_ident[Elf32_Ehdr::EI_OSABI] = ei_osabi;    assert(2==get_native16(&h3->ehdr.e_phnum));    set_native16(&h3->ehdr.e_phnum, 3);    assert(get_native32(&h3->ehdr.e_phoff)     == sizeof(Elf32_Ehdr));                         h3->ehdr.e_shoff = 0;    assert(get_native16(&h3->ehdr.e_ehsize)    == sizeof(Elf32_Ehdr));    assert(get_native16(&h3->ehdr.e_phentsize) == sizeof(Elf32_Phdr));           set_native16(&h3->ehdr.e_shentsize, sizeof(Elf32_Shdr));                         h3->ehdr.e_shnum = 0;                         h3->ehdr.e_shstrndx = 0;    sz_elf_hdrs = sizeof(*h3) - sizeof(linfo);    unsigned const note_offset = sz_elf_hdrs;    set_native32(&h3->phdr[0].p_filesz, sizeof(*h3)+sizeof(elfnote));  // + identsize;                  h3->phdr[0].p_memsz = h3->phdr[0].p_filesz;    unsigned const brkb = brka | ((0==(~page_mask & brka)) ? 0x20 : 0);    set_native32(&h3->phdr[1].p_type, PT_LOAD32);  // be sure    set_native32(&h3->phdr[1].p_offset, ~page_mask & brkb);    set_native32(&h3->phdr[1].p_vaddr, brkb);    set_native32(&h3->phdr[1].p_paddr, brkb);    h3->phdr[1].p_filesz = 0;    h3->phdr[1].p_memsz =  0;    set_native32(&h3->phdr[1].p_flags, Elf32_Phdr::PF_R | Elf32_Phdr::PF_W);    set_native32(&h3->phdr[2].p_type, Elf32_Phdr::PT_NOTE);    set_native32(&h3->phdr[2].p_offset, note_offset);    set_native32(&h3->phdr[2].p_vaddr, note_offset);    set_native32(&h3->phdr[2].p_paddr, note_offset);    set_native32(&h3->phdr[2].p_filesz, sizeof(elfnote));    set_native32(&h3->phdr[2].p_memsz,  sizeof(elfnote));    set_native32(&h3->phdr[2].p_flags, Elf32_Phdr::PF_R);    set_native32(&h3->phdr[2].p_align, 4);    set_native32(&elfnote.namesz, 8);    set_native32(&elfnote.descsz, 4);    set_native32(&elfnote.type,   1);

⌨️ 快捷键说明

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