📄 p_lx_elf.cpp
字号:
/* p_lx_elf.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) 2000-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"#include "p_lx_elf.h"#include "ui.h"#define PT_LOAD32 Elf32_Phdr::PT_LOAD#define PT_LOAD64 Elf64_Phdr::PT_LOADintPackLinuxElf32::checkEhdr(Elf32_Ehdr const *ehdr) const{ const unsigned char * const buf = ehdr->e_ident; if (0!=memcmp(buf, "\x7f\x45\x4c\x46", 4) // "\177ELF" || buf[Elf32_Ehdr::EI_CLASS]!=ei_class || buf[Elf32_Ehdr::EI_DATA] !=ei_data ) { return -1; } if (!memcmp(buf+8, "FreeBSD", 7)) // branded return 1; int const type = get_native16(&ehdr->e_type); if (type != Elf32_Ehdr::ET_EXEC && type != Elf32_Ehdr::ET_DYN) return 2; if (get_native16(&ehdr->e_machine) != e_machine) return 3; if (get_native32(&ehdr->e_version) != Elf32_Ehdr::EV_CURRENT) return 4; if (get_native16(&ehdr->e_phnum) < 1) return 5; if (get_native16(&ehdr->e_phentsize) != sizeof(Elf32_Phdr)) return 6; // check for Linux kernels unsigned const entry = get_native32(&ehdr->e_entry); if (entry == 0xC0100000) // uncompressed vmlinux return 1000; if (entry == 0x00001000) // compressed vmlinux return 1001; if (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;}intPackLinuxElf64::checkEhdr(Elf64_Ehdr const *ehdr) const{ const unsigned char * const buf = ehdr->e_ident; unsigned osabi0 = buf[Elf32_Ehdr::EI_OSABI]; if (0==osabi0) { osabi0 = opt->o_unix.osabi0; } if (0!=memcmp(buf, "\x7f\x45\x4c\x46", 4) // "\177ELF" || buf[Elf64_Ehdr::EI_CLASS]!=ei_class || buf[Elf64_Ehdr::EI_DATA] !=ei_data || osabi0!=ei_osabi ) { return -1; } if (!memcmp(buf+8, "FreeBSD", 7)) // branded return 1; int const type = get_native16(&ehdr->e_type); if (type != Elf64_Ehdr::ET_EXEC && type != Elf64_Ehdr::ET_DYN) return 2; if (get_native16(&ehdr->e_machine) != e_machine) return 3; if (get_native32(&ehdr->e_version) != Elf64_Ehdr::EV_CURRENT) return 4; if (get_native16(&ehdr->e_phnum) < 1) return 5; if (get_native16(&ehdr->e_phentsize) != sizeof(Elf64_Phdr)) return 6; // check for Linux kernels acc_uint64l_t const entry = get_native64(&ehdr->e_entry); if (entry == 0xC0100000) // uncompressed vmlinux return 1000; if (entry == 0x00001000) // compressed vmlinux return 1001; if (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;}PackLinuxElf::PackLinuxElf(InputFile *f) : super(f), file_image(NULL), dynstr(NULL), sz_phdrs(0), sz_elf_hdrs(0), sz_pack2(0), lg2_page(12), page_size(1u<<lg2_page), e_machine(0), ei_class(0), ei_data(0), ei_osabi(0), osabi_note(NULL){}PackLinuxElf::~PackLinuxElf(){ delete[] file_image;}void PackLinuxElf::pack3(OutputFile *fo, Filter &ft){ unsigned disp; unsigned const zero = 0; unsigned len = fo->getBytesWritten(); fo->write(&zero, 3& -len); // ALIGN_UP 0 mod 4 len += (3& -len); // 0 mod 4 if (0==(4 & len)) { fo->write(&zero, 4); len += 4; } // 4 mod 8 set_native32(&disp, len); // FIXME? -(sz_elf_hdrs+sizeof(l_info)+sizeof(p_info)) fo->write(&disp, sizeof(disp)); sz_pack2 = sizeof(disp) + len; // 0 mod 8 super::pack3(fo, ft);}void PackLinuxElf32::pack3(OutputFile *fo, Filter &ft){ super::pack3(fo, ft); set_native32(&elfout.phdr[0].p_filesz, sz_pack2);}void PackLinuxElf64::pack3(OutputFile *fo, Filter &ft){ super::pack3(fo, ft); set_native64(&elfout.phdr[0].p_filesz, sz_pack2);}voidPackLinuxElf::addStubEntrySections(Filter const *){ addLoader("ELFMAINX", NULL); //addLoader(getDecompressorSections(), NULL); addLoader( ( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL" : M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL" : M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL" : M_IS_LZMA(ph.method) ? "LZMA_ELF00,+80C,LZMA_DEC20,LZMA_DEC30" : NULL), NULL); addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);}void PackLinuxElf::defineSymbols(Filter const *){ // empty}PackLinuxElf32::PackLinuxElf32(InputFile *f) : super(f), phdri(NULL), shdri(NULL), page_mask(~0u<<lg2_page), dynseg(NULL), hashtab(NULL), dynsym(NULL), shstrtab(NULL), n_elf_shnum(0), sec_strndx(NULL), sec_dynsym(NULL), sec_dynstr(NULL){}PackLinuxElf32::~PackLinuxElf32(){ delete[] phdri;}PackLinuxElf64::PackLinuxElf64(InputFile *f) : super(f), phdri(NULL), page_mask(~0ull<<lg2_page){}PackLinuxElf64::~PackLinuxElf64(){ delete[] phdri;}Linker* PackLinuxElf64amd::newLinker() const{ return new ElfLinkerAMD64;}int const *PackLinuxElf::getCompressionMethods(int method, int level) const{ // No real dependency on LE32. return Packer::getDefaultCompressionMethods_le32(method, level);}int const *PackLinuxElf32armLe::getCompressionMethods(int method, int level) const{ return Packer::getDefaultCompressionMethods_8(method, level);}int const *PackLinuxElf32armBe::getCompressionMethods(int method, int level) const{ return Packer::getDefaultCompressionMethods_8(method, level);}int const *PackLinuxElf32ppc::getFilters() const{ static const int filters[] = { 0xd0, FT_END }; return filters;}int const *PackLinuxElf64amd::getFilters() const{ static const int filters[] = { 0x49, FT_END }; return filters;}void PackLinuxElf32::patchLoader(){}void PackLinuxElf64::patchLoader(){}void PackLinuxElf32::ARM_updateLoader(OutputFile *fo){ set_native32(&elfout.ehdr.e_entry, fo->getBytesWritten() + linker->getSymbolOffset("_start") + get_native32(&elfout.phdr[0].p_vaddr));}void PackLinuxElf32armLe::updateLoader(OutputFile *fo){ ARM_updateLoader(fo);}void PackLinuxElf32armBe::updateLoader(OutputFile *fo){ ARM_updateLoader(fo);}void PackLinuxElf32mipsel::updateLoader(OutputFile *fo){ ARM_updateLoader(fo); // not ARM specific; (no 32-bit immediates)}void PackLinuxElf32mipseb::updateLoader(OutputFile *fo){ ARM_updateLoader(fo); // not ARM specific; (no 32-bit immediates)}void PackLinuxElf32::updateLoader(OutputFile *fo){ set_native32(&elfout.ehdr.e_entry, fo->getBytesWritten() + get_native32(&elfout.phdr[0].p_vaddr));}void PackLinuxElf64::updateLoader(OutputFile *fo){ set_native64(&elfout.ehdr.e_entry, fo->getBytesWritten() + get_native64(&elfout.phdr[0].p_vaddr));}PackLinuxElf32ppc::PackLinuxElf32ppc(InputFile *f) : super(f){ e_machine = Elf32_Ehdr::EM_PPC; ei_class = Elf32_Ehdr::ELFCLASS32; ei_data = Elf32_Ehdr::ELFDATA2MSB; ei_osabi = Elf32_Ehdr::ELFOSABI_LINUX;}PackLinuxElf32ppc::~PackLinuxElf32ppc(){}Linker* PackLinuxElf32ppc::newLinker() const{ return new ElfLinkerPpc32;}PackLinuxElf64amd::PackLinuxElf64amd(InputFile *f) : super(f){ e_machine = Elf64_Ehdr::EM_X86_64; ei_class = Elf64_Ehdr::ELFCLASS64; ei_data = Elf64_Ehdr::ELFDATA2LSB; ei_osabi = Elf32_Ehdr::ELFOSABI_LINUX;}PackLinuxElf64amd::~PackLinuxElf64amd(){}static unsignedumax(unsigned a, unsigned b){ if (a <= b) { return b; } return a;}void PackLinuxElf32x86::addStubEntrySections(Filter const *ft){ int const n_mru = ft->n_mru; // FIXME: belongs to filter? packerf?// 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// (get_native16(&elfout.ehdr.e_phentsize) * get_native16(&elfout.ehdr.e_phnum)) +// // checksum UPX! lsize version format// sizeof(l_info) +// // PT_DYNAMIC with DT_NEEDED "forwarded" from original file// ((get_native16(&elfout.ehdr.e_phnum)==3)// ? (unsigned) get_native32(&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) { { // decompr, unfilter are separate addLoader("LXUNF000", NULL); addLoader("LXUNF002", NULL); if (0x80==(ft->id & 0xF0)) { if (256==n_mru) { addLoader("MRUBYTE0", NULL); } else if (n_mru) { addLoader("LXMRU005", NULL); } if (n_mru) { addLoader("LXMRU006", NULL); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -