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

📄 p_vmlinz.cpp

📁 UPX 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* p_vmlinz.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   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   markus@oberhumer.com      ml1050@users.sourceforge.net */#include "conf.h"#include "file.h"#include "filter.h"#include "packer.h"#include "p_vmlinz.h"#include "linker.h"#include <zlib.h>static const#include "stub/i386-linux.kernel.vmlinuz.h"static const unsigned stack_offset_during_uncompression = 0x9000;// add to "real mode pointer" in %esi; total 0x99000 is typical// from /usr/src/linux/arch/i386/boot/compressed/Makefilestatic const unsigned zimage_offset = 0x1000;static const unsigned bzimage_offset = 0x100000;/*************************************************************************//**************************************************************************/PackVmlinuzI386::PackVmlinuzI386(InputFile *f) :    super(f), physical_start(0x100000){    bele = &N_BELE_RTP::le_policy;    COMPILE_TIME_ASSERT(sizeof(boot_sect_t) == 0x218);}const int *PackVmlinuzI386::getCompressionMethods(int method, int level) const{    return Packer::getDefaultCompressionMethods_le32(method, level);}const int *PackVmlinuzI386::getFilters() const{    static const int filters[] = {        0x26, 0x24, 0x49, 0x46, 0x16, 0x13, 0x14, 0x11,        FT_ULTRA_BRUTE, 0x25, 0x15, 0x12,    FT_END };    return filters;}bool PackVmlinuzI386::canPack(){    return readFileHeader() == getFormat();}/*************************************************************************// common util routines**************************************************************************/int PackVmlinuzI386::readFileHeader(){    boot_sect_t h;    setup_size = 0;    fi->readx(&h, sizeof(h));    if (h.boot_flag != 0xAA55)        return 0;    const bool hdrs = (memcmp(h.hdrs, "HdrS", 4) == 0);    setup_size = (1 + (h.setup_sects ? h.setup_sects : 4)) * 0x200;    if (setup_size <= 0 || setup_size >= file_size)        return 0;    int format = UPX_F_VMLINUZ_i386;    unsigned sys_size = ALIGN_UP((unsigned) file_size, 16u) - setup_size;    const unsigned char *p = (const unsigned char *) &h + 0x1e3;    if (hdrs && memcmp(p, "\x0d\x0a\x07""ELKS", 7) == 0)    {        format = UPX_F_ELKS_8086;    }    else if (hdrs && (h.load_flags & 1) != 0)    {        format = UPX_F_BVMLINUZ_i386;        // account for 16-bit h.sys_size, wrap around at 20 bits        sys_size &= (1 << 20) - 1;    }    if (16u * h.sys_size != sys_size)        return 0;    // FIXME: add more checks for a valid kernel    return format;}// read full kernel into obuf[], gzip-decompress into ibuf[],// return decompressed sizeint PackVmlinuzI386::decompressKernel(){    // read whole kernel image    obuf.alloc(file_size);    fi->seek(0, SEEK_SET);    fi->readx(obuf, file_size);    // See startup_32: in linux/arch/i386/boot/compressed/head.S    char const *p = (char const *)&obuf[setup_size];    for (int j= 0; j < 0x200; ++j, ++p) {        if (0==memcmp("\xE8\x00\x00\x00\x00\x5D", p, 6)) {            /* "call 1f; 1f: pop %ebp"  determines actual execution address; */            /* linux-2.6.21 (spring 2007) and later; upx stub needs work. */            throwCantPack("Relocatable kernel is not yet supported");        }        // Find "ljmp $__BOOT_CS,$__PHYSICAL_START" if any.        if (0==memcmp("\xEA\x00\x00", p, 3) && 0==(0xf & p[3]) && 0==p[4]) {            /* whole megabyte < 16MB */            physical_start = get_le32(1+ p);            break;        }    }    checkAlreadyPacked(obuf + setup_size, UPX_MIN(file_size - setup_size, (off_t)1024));    for (int gzoff = setup_size; gzoff < file_size; gzoff++)    {        // find gzip header (2 bytes magic + 1 byte method "deflated")        int off = find(obuf + gzoff, file_size - gzoff, "\x1F\x8B\x08", 3);        if (off < 0)            break;        gzoff += off;        const int gzlen = file_size - gzoff;        if (gzlen < 256)            break;        // check gzip flag byte        unsigned char flags = obuf[gzoff + 3];        if ((flags & 0xe0) != 0)        // reserved bits set            continue;        //printf("found gzip header at offset %d\n", gzoff);        // try to decompress        int klen;        int fd;        off_t fd_pos;        for (;;)        {            klen = -1;            fd = -1;            fd_pos = -1;            // open            fi->seek(gzoff, SEEK_SET);            fd = dup(fi->getFd());            if (fd < 0)                break;            gzFile zf = gzdopen(fd, "rb");            if (zf == NULL)                break;            // estimate gzip-decompressed kernel size & alloc buffer            if (ibuf.getSize() == 0)                ibuf.alloc(gzlen * 3);            // decompress            klen = gzread(zf, ibuf, ibuf.getSize());            fd_pos = lseek(fd, 0, SEEK_CUR);            gzclose(zf);            fd = -1;            if (klen != (int)ibuf.getSize())                break;            // realloc and try again            unsigned s = ibuf.getSize();            ibuf.dealloc();            ibuf.alloc(3 * s / 2);        }        if (fd >= 0)            (void) close(fd);        if (klen <= 0)            continue;        if (klen <= gzlen)            continue;        if (opt->force > 0)            return klen;        // some checks        if (fd_pos != file_size)        {            //printf("fd_pos: %ld, file_size: %ld\n", (long)fd_pos, (long)file_size);            // linux-2.6.21.5/arch/i386/boot/compressed/vmlinux.lds            // puts .data.compressed ahead of .text, .rodata, etc;            // so piggy.o need not be last in bzImage.  Alas.            //throwCantPack("trailing bytes after kernel image; use option '-f' to force packing");        }        // see /usr/src/linux/arch/i386/kernel/head.S        // 2.4.x: [cli;] cld; mov $...,%eax        if (memcmp(ibuf,     "\xFC\xB8", 2) == 0) goto head_ok;        if (memcmp(ibuf, "\xFA\xFC\xB8", 3) == 0) goto head_ok;        // 2.6.21.5 CONFIG_PARAVIRT  mov %cs,%eax; test $3,%eax; jne ...;        if (memcmp(ibuf, "\x8c\xc8\xa9\x03\x00\x00\x00\x0f\x85", 9) == 0) goto head_ok;        if (memcmp(ibuf, "\x8c\xc8\xa8\x03\x0f\x85", 6) == 0) goto head_ok;        // 2.6.x: [cli;] cld; lgdt ...        if (memcmp(ibuf,     "\xFC\x0F\x01", 3) == 0) goto head_ok;        if (memcmp(ibuf, "\xFA\xFC\x0F\x01", 4) == 0) goto head_ok;        // 2.6.x+grsecurity+strongswan+openwall+trustix: ljmp $0x10,...        if (ibuf[0] == 0xEA && memcmp(ibuf+5, "\x10\x00", 2) == 0) goto head_ok;        // x86_64 2.6.x        if (0xB8==ibuf[0]  // mov $...,%eax        &&  0x8E==ibuf[5] && 0xD8==ibuf[6]  // mov %eax,%ds        &&  0x0F==ibuf[7] && 0x01==ibuf[8] && 020==(070 & ibuf[9]) // lgdtl        &&  0xB8==ibuf[14]  // mov $...,%eax        &&  0x0F==ibuf[19] && 0xA2==ibuf[20]  // cpuid        ) goto head_ok;        throwCantPack("unrecognized kernel architecture; use option '-f' to force packing");    head_ok:        // FIXME: more checks for special magic bytes in ibuf ???        // FIXME: more checks for kernel architecture ???        return klen;    }    return 0;}void PackVmlinuzI386::readKernel(){    int klen = decompressKernel();    if (klen <= 0)        throwCantPack("kernel decompression failed");    //OutputFile::dump("kernel.img", ibuf, klen);    // copy the setup boot code

⌨️ 快捷键说明

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