📄 p_lx_exc.cpp
字号:
sizeof(l_info); if (0 == get_le32(fold_hdrlen + fold)) { // inconsistent SIZEOF_HEADERS in *.lds (ld, binutils) fold_hdrlen = umax(0x80, fold_hdrlen); } } // This adds the definition to the "library", to be used later. // NOTE: the stub is NOT compressed! The savings is not worth it. linker->addSection("FOLDEXEC", fold + fold_hdrlen, szfold - fold_hdrlen, 0); n_mru = ft->n_mru;// 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// (elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +// // checksum UPX! lsize version format// sizeof(l_info) +// // PT_DYNAMIC with DT_NEEDED "forwarded" from original file// ((elfout.ehdr.e_phnum==3) ? (unsigned) 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) { if (n_mru) { addLoader("LEXEC009", NULL); } } addLoader("LEXEC010", NULL); linker->defineSymbol("filter_cto", ft->cto); linker->defineSymbol("filter_length", (ft->id & 0xf) % 3 == 0 ? ft->calls : ft->lastcall - ft->calls * 4); addLoader(getDecompressorSections(), NULL); addLoader("LEXEC015", NULL); if (ft->id) { { // decompr, unfilter not separate if (0x80==(ft->id & 0xF0)) { addLoader("LEXEC110", NULL); if (n_mru) { addLoader("LEXEC100", NULL); } // bug in APP: jmp and label must be in same .asx/.asy addLoader("LEXEC016", NULL); } } addFilter32(ft->id); { // decompr always unfilters addLoader("LEXEC017", NULL); } } else { addLoader("LEXEC017", NULL); } addLoader("IDENTSTR", NULL); addLoader("LEXEC020", NULL); addLoader("FOLDEXEC", NULL); if (M_IS_LZMA(ph.method)) { const lzma_compress_result_t *res = &ph.compress_result.result_lzma; acc_uint32e_t properties = // lc, lp, pb, dummy (res->lit_context_bits << 0) | (res->lit_pos_bits << 8) | (res->pos_bits << 16); if (linker->bele->isBE()) // big endian - bswap32 acc_swab32s(&properties); linker->defineSymbol("lzma_properties", properties); // -2 for properties linker->defineSymbol("lzma_c_len", ph.c_len - 2); linker->defineSymbol("lzma_u_len", ph.u_len); unsigned const stack = getDecompressorWrkmemSize(); linker->defineSymbol("lzma_stack_adjust", 0u - stack); } 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); } } relocateLoader();}voidPackLinuxI386::buildLoader(Filter const *ft){ unsigned const sz_fold = sizeof(stub_i386_linux_elf_execve_fold); MemBuffer buf(sz_fold); memcpy(buf, stub_i386_linux_elf_execve_fold, sz_fold); // patch loader // note: we only can use /proc/<pid>/fd when exetype > 0. // also, we sleep much longer when compressing a script. checkPatch(NULL, 0, 0, 0); // reset patch_le32(buf,sz_fold,"UPX4",exetype > 0 ? 3 : 15); // sleep time patch_le32(buf,sz_fold,"UPX3",progid); patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff); buildLinuxLoader( stub_i386_linux_elf_execve_entry, sizeof(stub_i386_linux_elf_execve_entry), buf, sz_fold, ft );}voidPackBSDI386::buildLoader(Filter const *ft){ unsigned const sz_fold = sizeof(stub_i386_bsd_elf_execve_fold); MemBuffer buf(sz_fold); memcpy(buf, stub_i386_bsd_elf_execve_fold, sz_fold); // patch loader // note: we only can use /proc/<pid>/fd when exetype > 0. // also, we sleep much longer when compressing a script. checkPatch(NULL, 0, 0, 0); // reset patch_le32(buf,sz_fold,"UPX4",exetype > 0 ? 3 : 15); // sleep time patch_le32(buf,sz_fold,"UPX3",progid); patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff); buildLinuxLoader( stub_i386_bsd_elf_execve_entry, sizeof(stub_i386_bsd_elf_execve_entry), buf, sz_fold, ft );}// FIXME: getLoaderPrefixSize is unused?int PackLinuxI386::getLoaderPrefixSize() const{ return 116;}/*************************************************************************// some ELF utitlity functions**************************************************************************/// basic check of an Linux ELF Ehdrint PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const{ const unsigned char * const buf = ehdr->e_ident; if (memcmp(buf, "\x7f\x45\x4c\x46\x01\x01\x01", 7)) // ELF 32-bit LSB return -1; // now check the ELF header if (!memcmp(buf+8, "FreeBSD", 7)) // branded return 1; if (ehdr->e_type != Elf32_Ehdr::ET_EXEC && ehdr->e_type != Elf32_Ehdr::ET_DYN ) // executable return 2; if (ehdr->e_machine != Elf32_Ehdr::EM_386) // Intel 80386 return 3; if (ehdr->e_version != Elf32_Ehdr::EV_CURRENT) // version return 4; if (ehdr->e_phnum < 1) return 5; if (ehdr->e_phentsize != sizeof(Elf32_Phdr)) return 6; // check for Linux kernels if (ehdr->e_entry == 0xC0100000) // uncompressed vmlinux return 1000; if (ehdr->e_entry == 0x00001000) // compressed vmlinux return 1001; if (ehdr->e_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;}/*************************************************************************//**************************************************************************/bool PackLinuxI386::canPack(){ if (exetype != 0) return super::canPack(); Elf_LE32_Ehdr ehdr; unsigned char *buf = ehdr.e_ident; fi->seek(0, SEEK_SET); fi->readx(&ehdr, sizeof(ehdr)); fi->seek(0, SEEK_SET); exetype = 0; const unsigned l = get_le32(buf); int elf = checkEhdr(&ehdr); if (elf >= 0) { // NOTE: ELF executables are now handled by p_lx_elf.cpp, // so we only handle them here if force_execve if (elf == 0 && opt->o_unix.force_execve) { exetype = 1; unsigned osabi0 = ehdr.e_ident[Elf32_Ehdr::EI_OSABI]; switch (osabi0) { case Elf32_Ehdr::ELFOSABI_LINUX: case Elf32_Ehdr::ELFOSABI_FREEBSD: case Elf32_Ehdr::ELFOSABI_NETBSD: case Elf32_Ehdr::ELFOSABI_OPENBSD: ei_osabi = osabi0; // Proudly declares its osabi in Ehdr. break; default: unsigned const e_phnum = get_native16(&ehdr.e_phnum); if (e_phnum<=(512/sizeof(Elf32_Phdr))) { char buf2[512]; fi->seek(get_native32(&ehdr.e_phoff), SEEK_SET); fi->readx(buf2, sizeof(buf2)); fi->seek(0, SEEK_SET); Elf32_Phdr const *phdr = (Elf32_Phdr const *)buf2; for (unsigned j=0; j < e_phnum; ++phdr, ++j) { if (phdr->PT_NOTE == get_native32(&phdr->p_type)) { unsigned const offset = get_native32(&phdr->p_offset); struct Elf32_Note note; memset(¬e, 0, sizeof(note)); fi->seek(offset, SEEK_SET); fi->readx(¬e, sizeof(note)); fi->seek(0, SEEK_SET); if (4==get_native32(¬e.descsz) && 1==get_native32(¬e.type) && 0==note.end ) { if (0==strcmp("NetBSD", (char const *)¬e.text)) { ei_osabi = Elf32_Ehdr::ELFOSABI_NETBSD; break; } if (0==strcmp("OpenBSD", (char const *)¬e.text)) { ei_osabi = Elf32_Ehdr::ELFOSABI_OPENBSD; break; } } } } } } } if (UPX_F_BSD_i386==getFormat() && !(Elf32_Ehdr::ELFOSABI_FREEBSD==ei_osabi || Elf32_Ehdr::ELFOSABI_NETBSD ==ei_osabi || Elf32_Ehdr::ELFOSABI_OPENBSD==ei_osabi )) { return false; } } else if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc) { // OMAGIC / NMAGIC / ZMAGIC / QMAGIC exetype = 2; // FIXME: N_TRSIZE, N_DRSIZE // FIXME: check for aout shared libraries } else { // shell scripts and other interpreters if (Elf32_Ehdr::ELFOSABI_LINUX!=ei_osabi) { return false; // so far, only Linux has runtime stub for shell } else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh exetype = -1; else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh exetype = -1; else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode exetype = -2; } return super::canPack();}void PackLinuxI386::patchLoader() { }void PackLinuxI386::patchLoaderChecksum(){ unsigned char *const ptr = getLoader(); l_info *const lp = (l_info *)(sizeof(elfout.ehdr) + (elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout ); // checksum for loader + p_info lp->l_checksum = 0; lp->l_magic = UPX_ELF_MAGIC; lp->l_lsize = (unsigned short) lsize; lp->l_version = (unsigned char) ph.version; lp->l_format = (unsigned char) ph.format; // INFO: lp->l_checksum is currently unused lp->l_checksum = upx_adler32(ptr, lsize);}void PackLinuxI386::updateLoader(OutputFile *fo){ elfout.ehdr.e_entry = fo->getBytesWritten() + elfout.phdr[0].p_vaddr;}/*vi:ts=4:et*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -