📄 p_lx_elf.cpp
字号:
addLoader("LXMRU007", NULL); } } else if (0x40==(ft->id & 0xF0)) { addLoader("LXUNF008", NULL); } addLoader("LXUNF010", NULL); } if (n_mru) { addLoader("LEXEC009", NULL); } } addLoader("LEXEC010", NULL); addLoader(getDecompressorSections(), NULL); addLoader("LEXEC015", NULL); if (ft->id) { { // decompr, unfilter are separate if (0x80!=(ft->id & 0xF0)) { addLoader("LXUNF042", NULL); } } addFilter32(ft->id); { // decompr, unfilter are separate if (0x80==(ft->id & 0xF0)) { if (0==n_mru) { addLoader("LXMRU058", NULL); } } addLoader("LXUNF035", NULL); } } else { addLoader("LEXEC017", NULL); } addLoader("IDENTSTR", NULL); addLoader("LEXEC020", NULL); addLoader("FOLDEXEC", NULL);}void PackLinuxElf32x86::defineSymbols(Filter const *const ft){ 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); } }}voidPackLinuxElf32::buildLinuxLoader( upx_byte const *const proto, unsigned const szproto, upx_byte const *const fold, unsigned const szfold, Filter const *ft){ initLoader(proto, szproto); struct b_info h; memset(&h, 0, sizeof(h)); unsigned fold_hdrlen = 0; if (0 < szfold) { cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold; fold_hdrlen = umax(0x80, sizeof(hf->ehdr) + get_native16(&hf->ehdr.e_phentsize) * get_native16(&hf->ehdr.e_phnum) + sizeof(l_info) ); h.sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen)); h.b_method = (unsigned char) ph.method; // FIXME: endian trouble h.b_ftid = (unsigned char) ph.filter; h.b_cto8 = (unsigned char) ph.filter_cto; } unsigned char const *const uncLoader = fold_hdrlen + fold; h.sz_cpr = MemBuffer::getSizeForCompression(h.sz_unc); unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_cpr]; if (0 < szfold) { int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &h.sz_cpr, NULL, ph.method, 10, NULL, NULL ); if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc) throwInternalError("loader compression failed");#if 0 //{ debugging only if (M_IS_LZMA(ph.method)) { ucl_uint tmp_len = h.sz_unc; // LZMA uses this as EOF unsigned char *tmp = new unsigned char[tmp_len]; memset(tmp, 0, tmp_len); r = upx_decompress(sizeof(h) + cprLoader, h.sz_cpr, tmp, &tmp_len, h.b_method, NULL); if (r == UPX_E_OUT_OF_MEMORY) throwOutOfMemoryException(); printf("\n%d %d: %d %d %d\n", h.b_method, r, h.sz_cpr, h.sz_unc, tmp_len); for (unsigned j=0; j < h.sz_unc; ++j) if (tmp[j]!=uncLoader[j]) { printf("%d: %x %x\n", j, tmp[j], uncLoader[j]); } delete[] tmp; }#endif //} } unsigned const sz_cpr = h.sz_cpr; set_native32(&h.sz_cpr, h.sz_cpr); set_native32(&h.sz_unc, h.sz_unc); memcpy(cprLoader, &h, sizeof(h)); // This adds the definition to the "library", to be used later. linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + sz_cpr, 0); delete [] cprLoader; addStubEntrySections(ft); defineSymbols(ft); relocateLoader();}voidPackLinuxElf64::buildLinuxLoader( upx_byte const *const proto, unsigned const szproto, upx_byte const *const fold, unsigned const szfold, Filter const *ft){ initLoader(proto, szproto); struct b_info h; memset(&h, 0, sizeof(h)); unsigned fold_hdrlen = 0; if (0 < szfold) { cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold; fold_hdrlen = umax(0x80, sizeof(hf->ehdr) + get_native16(&hf->ehdr.e_phentsize) * get_native16(&hf->ehdr.e_phnum) + sizeof(l_info) ); h.sz_unc = ((szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen)); h.b_method = (unsigned char) ph.method; // FIXME: endian trouble h.b_ftid = (unsigned char) ph.filter; h.b_cto8 = (unsigned char) ph.filter_cto; } unsigned char const *const uncLoader = fold_hdrlen + fold; h.sz_cpr = MemBuffer::getSizeForCompression(h.sz_unc); unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_cpr]; if (0 < szfold) { int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &h.sz_cpr, NULL, ph.method, 10, NULL, NULL ); if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc) throwInternalError("loader compression failed"); } unsigned const sz_cpr = h.sz_cpr; set_native32(&h.sz_cpr, h.sz_cpr); set_native32(&h.sz_unc, h.sz_unc); memcpy(cprLoader, &h, sizeof(h)); // This adds the definition to the "library", to be used later. linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + sz_cpr, 0); delete [] cprLoader; addStubEntrySections(ft); defineSymbols(ft); relocateLoader();}voidPackLinuxElf64amd::defineSymbols(Filter const *){ 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_LOAD64) as an upper bound. unsigned len = 0; acc_uint64l_t lo_va_user = ~0ull; // infinity for (int j= get_native16(&ehdri.e_phnum); --j>=0; ) { if (PT_LOAD64 == get_native32(&phdri[j].p_type)) { len += (unsigned)get_native64(&phdri[j].p_filesz); acc_uint64l_t const va = get_native64(&phdri[j].p_vaddr); if (va < lo_va_user) { lo_va_user = va; } } } lsize = /*getLoaderSize()*/ 64 * 1024; // XXX: upper bound; avoid circularity acc_uint64l_t lo_va_stub = get_native64(&elfout.phdr[0].p_vaddr); acc_uint64l_t adrc; acc_uint64l_t adrm; acc_uint64l_t adru; acc_uint64l_t 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_native64( &elfout.ehdr.e_entry, get_native64(&elfout.ehdr.e_entry) + lo_va_user - lo_va_stub); set_native64(&elfout.phdr[0].p_vaddr, lo_va_user); set_native64(&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("LENU", lenu); // len for unmap linker->defineSymbol("ADRC", adrc); // addr for copy linker->defineSymbol("ADRU", adru); // addr for unmap#define EI_NIDENT 16 /* <elf.h> */ linker->defineSymbol("JMPU", EI_NIDENT -4 + lo_va_user); // unmap trampoline#undef EI_NIDENT linker->defineSymbol("LENM", lenm); // len for map linker->defineSymbol("ADRM", adrm); // addr for map //linker->dumpSymbols(); // debug}static const#include "stub/i386-linux.elf-entry.h"static const#include "stub/i386-linux.elf-fold.h"voidPackLinuxElf32x86::buildLoader(const Filter *ft){ unsigned char tmp[sizeof(stub_i386_linux_elf_fold)]; memcpy(tmp, stub_i386_linux_elf_fold, sizeof(stub_i386_linux_elf_fold)); checkPatch(NULL, 0, 0, 0); // reset if (opt->o_unix.is_ptinterp) { unsigned j; for (j = 0; j < sizeof(stub_i386_linux_elf_fold)-1; ++j) { if (0x60==tmp[ j] && 0x47==tmp[1+j] ) { /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */ tmp[ j] = 0x47; tmp[1+j] = 0x60; break; } } } buildLinuxLoader( stub_i386_linux_elf_entry, sizeof(stub_i386_linux_elf_entry), tmp, sizeof(stub_i386_linux_elf_fold), ft );}static const#include "stub/i386-bsd.elf-entry.h"static const#include "stub/i386-bsd.elf-fold.h"voidPackBSDElf32x86::buildLoader(const Filter *ft){ unsigned char tmp[sizeof(stub_i386_bsd_elf_fold)]; memcpy(tmp, stub_i386_bsd_elf_fold, sizeof(stub_i386_bsd_elf_fold)); checkPatch(NULL, 0, 0, 0); // reset if (opt->o_unix.is_ptinterp) { unsigned j; for (j = 0; j < sizeof(stub_i386_bsd_elf_fold)-1; ++j) { if (0x60==tmp[ j] && 0x47==tmp[1+j] ) { /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */ tmp[ j] = 0x47; tmp[1+j] = 0x60; break; } } } buildLinuxLoader( stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry), tmp, sizeof(stub_i386_bsd_elf_fold), ft);}#if 0 //{ re-use for OpenBSD, toostatic const#include "stub/i386-bsd.elf-entry.h"#endif //}static const#include "stub/i386-openbsd.elf-fold.h"voidPackOpenBSDElf32x86::buildLoader(const Filter *ft){ unsigned char tmp[sizeof(stub_i386_openbsd_elf_fold)]; memcpy(tmp, stub_i386_openbsd_elf_fold, sizeof(stub_i386_openbsd_elf_fold)); checkPatch(NULL, 0, 0, 0); // reset if (opt->o_unix.is_ptinterp) { unsigned j; for (j = 0; j < sizeof(stub_i386_openbsd_elf_fold)-1; ++j) { if (0x60==tmp[ j] && 0x47==tmp[1+j] ) { /* put INC EDI before PUSHA: inhibits auxv_up for PT_INTERP */ tmp[ j] = 0x47; tmp[1+j] = 0x60; break; } } } buildLinuxLoader( stub_i386_bsd_elf_entry, sizeof(stub_i386_bsd_elf_entry), tmp, sizeof(stub_i386_openbsd_elf_fold), ft);}static const#include "stub/arm-linux.elf-entry.h"static const#include "stub/arm-linux.elf-fold.h"static const#include "stub/armeb-linux.elf-entry.h"static const#include "stub/armeb-linux.elf-fold.h"#include "mem.h"voidPackLinuxElf32armBe::buildLoader(Filter const *ft){ buildLinuxLoader( stub_armeb_linux_elf_entry, sizeof(stub_armeb_linux_elf_entry), stub_armeb_linux_elf_fold, sizeof(stub_armeb_linux_elf_fold), ft);}voidPackLinuxElf32armLe::buildLoader(Filter const *ft){ buildLinuxLoader( stub_arm_linux_elf_entry, sizeof(stub_arm_linux_elf_entry), stub_arm_linux_elf_fold, sizeof(stub_arm_linux_elf_fold), ft);}static const#include "stub/mipsel.r3000-linux.elf-entry.h"static const#include "stub/mipsel.r3000-linux.elf-fold.h"voidPackLinuxElf32mipsel::buildLoader(Filter const *ft){ buildLinuxLoader( stub_mipsel_r3000_linux_elf_entry, sizeof(stub_mipsel_r3000_linux_elf_entry), stub_mipsel_r3000_linux_elf_fold, sizeof(stub_mipsel_r3000_linux_elf_fold), ft);}static const#include "stub/mips.r3000-linux.elf-entry.h"static const#include "stub/mips.r3000-linux.elf-fold.h"voidPackLinuxElf32mipseb::buildLoader(Filter const *ft){ buildLinuxLoader( stub_mips_r3000_linux_elf_entry, sizeof(stub_mips_r3000_linux_elf_entry), stub_mips_r3000_linux_elf_fold, sizeof(stub_mips_r3000_linux_elf_fold), ft);}static const#include "stub/powerpc-linux.elf-entry.h"static const#include "stub/powerpc-linux.elf-fold.h"voidPackLinuxElf32ppc::buildLoader(const Filter *ft){ buildLinuxLoader( stub_powerpc_linux_elf_entry, sizeof(stub_powerpc_linux_elf_entry), stub_powerpc_linux_elf_fold, sizeof(stub_powerpc_linux_elf_fold), ft);}static const#include "stub/amd64-linux.elf-entry.h"static const#include "stub/amd64-linux.elf-fold.h"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -