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

📄 i386-bsd.elf-main.c

📁 UPX 源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* i386-bsd.elf-main.c -- stub loader for Linux x86 ELF executable   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 "include/bsd.h"/*************************************************************************// configuration section**************************************************************************/// In order to make it much easier to move this code at runtime and execute// it at an address different from it load address:  there must be no// static data, and no string constants.#if 1  /*{*/#define DPRINTF(a) /* empty: no debug drivel */#else  /*}{*/#include "stdarg.h"static intunsimal(unsigned x, char *ptr, int n){    if (10<=x) {        n = unsimal(x/10, ptr, n);        x %= 10;    }    ptr[n] = '0' + x;    return 1+ n;}static intdecimal(int x, char *ptr, int n){    if (x < 0) {        *ptr++ = '-'; ++n;        x = -x;    }    return unsimal(x, ptr, n);}extern char const *STR_hex();static intheximal(unsigned x, char *ptr, int n){    if (16<=x) {        n = heximal(x>>4, ptr, n);        x &= 0xf;    }    ptr[n] = STR_hex()[x];    return 1+ n;}#define DPRINTF(a) dprintf aextern char const *STR_0x();extern char const *STR_xread();extern char const *STR_unpackExtent();extern char const *STR_make_hatch_arm();extern char const *STR_auxv_up();extern char const *STR_xfind_pages();extern char const *STR_do_xmap();extern char const *STR_upx_main();static intdprintf(char const *fmt, ...){    char c;    int n= 0;    char *ptr;    char buf[20];    va_list va; va_start(va, fmt);    ptr= &buf[0];    while (0!=(c= *fmt++)) if ('%'!=c) goto literal;    else switch (c= *fmt++) {    default: {literal:        n+= write(2, fmt-1, 1);    } break;    case 0: goto done;  /* early */    case 'u': {        n+= write(2, buf, unsimal(va_arg(va, unsigned), buf, 0));    } break;    case 'd': {        n+= write(2, buf, decimal(va_arg(va, int), buf, 0));    } break;    case 'p':  /* same as 'x'; relies on sizeof(int)==sizeof(void *) */    case 'x': {        buf[0] = '0';        buf[1] = 'x';        n+= write(2, buf, heximal(va_arg(va, int), buf, 2));    } break;    }done:    va_end(va);    return n;}#endif  /*}*/#define MAX_ELF_HDR 512  // Elf32_Ehdr + n*Elf32_Phdr must fit in this/*************************************************************************// "file" util**************************************************************************/struct Extent {    size_t size;  // must be first to match size[0] uncompressed size    char *buf;};static void#if (ACC_CC_GNUC >= 0x030300) && defined(__i386__)  /*{*/__attribute__((__noinline__, __used__, regparm(3), stdcall))#endif  /*}*/xread(struct Extent *x, char *buf, size_t count){    char *p=x->buf, *q=buf;    size_t j;    DPRINTF((STR_xread(), x, x->size, x->buf, buf, count));    if (x->size < count) {        exit(127);    }    for (j = count; 0!=j--; ++p, ++q) {        *q = *p;    }    x->buf  += count;    x->size -= count;}/*************************************************************************// util**************************************************************************/#if 1  //{  save space#define ERR_LAB error: exit(127);#define err_exit(a) goto error#else  //}{  save debugging time#define ERR_LABstatic voiderr_exit(int a) __attribute__ ((__noreturn__));{    (void)a;  // debugging convenience    exit(127);}#endif  //}static void *do_brk(void *addr){    return brk(addr);}/*************************************************************************// UPX & NRV stuff**************************************************************************/typedef void f_unfilter(    nrv_byte *,  // also addvalue    nrv_uint,    unsigned cto8, // junk in high 24 bits    unsigned ftid);typedef int f_expand(    const nrv_byte *, nrv_uint,          nrv_byte *, nrv_uint *, unsigned );static voidunpackExtent(    struct Extent *const xi,  // input    struct Extent *const xo,  // output    f_expand *const f_decompress,    f_unfilter *f_unf){    DPRINTF((STR_unpackExtent(),        xi, xi->size, xi->buf, xo, xo->size, xo->buf, f_decompress, f_unf));    while (xo->size) {        struct b_info h;        //   Note: if h.sz_unc == h.sz_cpr then the block was not        //   compressible and is stored in its uncompressed form.        // Read and check block sizes.        xread(xi, (char *)&h, sizeof(h));        if (h.sz_unc == 0) {                     // uncompressed size 0 -> EOF            if (h.sz_cpr != UPX_MAGIC_LE32)      // h.sz_cpr must be h->magic                err_exit(2);            if (xi->size != 0)                 // all bytes must be written                err_exit(3);            break;        }        if (h.sz_cpr <= 0) {            err_exit(4);ERR_LAB        }        if (h.sz_cpr > h.sz_unc        ||  h.sz_unc > xo->size ) {            err_exit(5);        }        // Now we have:        //   assert(h.sz_cpr <= h.sz_unc);        //   assert(h.sz_unc > 0 && h.sz_unc <= blocksize);        //   assert(h.sz_cpr > 0 && h.sz_cpr <= blocksize);        if (h.sz_cpr < h.sz_unc) { // Decompress block            nrv_uint out_len = h.sz_unc;  // EOF for lzma            int const j = (*f_decompress)((unsigned char *)xi->buf, h.sz_cpr,                (unsigned char *)xo->buf, &out_len, *(int *)(void *)&h.b_method );            if (j != 0 || out_len != (nrv_uint)h.sz_unc)                err_exit(7);            // Skip Ehdr+Phdrs: separate 1st block, not filtered            if (h.b_ftid!=0 && f_unf  // have filter            &&  ((512 < out_len)  // this block is longer than Ehdr+Phdrs              || (xo->size==(unsigned)h.sz_unc) )  // block is last in Extent            ) {                (*f_unf)((unsigned char *)xo->buf, out_len, h.b_cto8, h.b_ftid);            }            xi->buf  += h.sz_cpr;            xi->size -= h.sz_cpr;        }        else { // copy literal block            xread(xi, xo->buf, h.sz_cpr);        }        xo->buf  += h.sz_unc;        xo->size -= h.sz_unc;    }}#if defined(__i386__)  /*{*/// Create (or find) an escape hatch to use when munmapping ourselves the stub.// Called by do_xmap to create it; remembered in AT_NULL.d_valstatic void *make_hatch_x86(Elf32_Phdr const *const phdr, unsigned const reloc){    unsigned *hatch = 0;    if (phdr->p_type==PT_LOAD && phdr->p_flags & PF_X) {        // The format of the 'if' is        //  if ( ( (hatch = loc1), test_loc1 )        //  ||   ( (hatch = loc2), test_loc2 ) ) {        //      action        //  }        // which uses the comma to save bytes when test_locj involves locj        // and the action is the same when either test succeeds.        // Try page fragmentation just beyond .text .        if ( ( (hatch = (void *)(phdr->p_memsz + phdr->p_vaddr + reloc)),                ( phdr->p_memsz==phdr->p_filesz  // don't pollute potential .bss                &&  4<=(~PAGE_MASK & -(int)hatch) ) ) // space left on page        // Try Elf32_Ehdr.e_ident[12..15] .  warning: 'const' cast away        ||   ( (hatch = (void *)(&((Elf32_Ehdr *)phdr->p_vaddr + reloc)->e_ident[12])),                (phdr->p_offset==0) ) ) {            // Omitting 'const' saves repeated literal in gcc.            unsigned /*const*/ escape = 0xc3c980cd;  // "int $0x80; leave; ret"            // Don't store into read-only page if value is already there.            if (* (volatile unsigned*) hatch != escape) {                * hatch  = escape;            }        }    }    return hatch;}#elif defined(__arm__)  /*}{*/static void *make_hatch_arm(Elf32_Phdr const *const phdr, unsigned const reloc){

⌨️ 快捷键说明

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