mirror of https://github.com/upx/upx.git
Cleaned up the Linux C stub loaders by putting more stuff into linux.hh.
committer: mfx <mfx> 962045590 +0000
This commit is contained in:
parent
957ef351c4
commit
51b162f069
|
@ -1,3 +1,5 @@
|
|||
*.00?
|
||||
*.upx
|
||||
.gdbinit
|
||||
upx
|
||||
upx.map
|
||||
|
|
|
@ -120,6 +120,8 @@ void PackLinuxI386elf::patchLoader()
|
|||
|
||||
// stub/scripts/setfold.pl puts address of 'fold_begin' in phdr[1].p_offset
|
||||
off_t const fold_begin = phdr[1].p_offset;
|
||||
assert(fold_begin > 0);
|
||||
assert(fold_begin < (off_t)lsize);
|
||||
MemBuffer cprLoader(lsize);
|
||||
|
||||
// compress compiled C-code portion of loader
|
||||
|
|
|
@ -101,6 +101,8 @@ void PackLinuxI386sh::patchLoader()
|
|||
|
||||
// stub/scripts/setfold.pl puts address of 'fold_begin' in phdr[1].p_offset
|
||||
off_t const fold_begin = phdri[1].p_offset;
|
||||
assert(fold_begin > 0);
|
||||
assert(fold_begin < (off_t)lsize);
|
||||
MemBuffer cprLoader(lsize);
|
||||
|
||||
// compress compiled C-code portion of loader
|
||||
|
|
|
@ -425,6 +425,8 @@ void PackLinuxI386::patchLoader()
|
|||
|
||||
// stub/scripts/setfold.pl puts address of 'fold_begin' in phdr[1].p_offset
|
||||
off_t const fold_begin = phdr[1].p_offset;
|
||||
assert(fold_begin > 0);
|
||||
assert(fold_begin < (off_t)lsize);
|
||||
MemBuffer cprLoader(lsize);
|
||||
|
||||
// compress compiled C-code portion of loader
|
||||
|
|
|
@ -188,24 +188,21 @@ l_w32pe.h: l_w32pe.asx
|
|||
|
||||
l_lx_n2b.h: l_lx_exec.c l_xe_n2b.o l_lx_exec86.lds Makefile
|
||||
$(CC_LINUX) -DNRV2B -o $T.o -c $<
|
||||
ld -T l_lx_exec86.lds -Map $T.map -o $T.bin \
|
||||
l_xe_n2b.o $T.o
|
||||
ld -T l_lx_exec86.lds -Map $T.map -o $T.bin l_xe_n2b.o $T.o
|
||||
$(SETFOLD) $T.bin
|
||||
$(BRANDELF) $T.bin
|
||||
$(BIN2H) $T.bin linux_i386exec_nrv2b_loader $@
|
||||
|
||||
l_le_n2b.h: l_lx_elf.c l_6e_n2b.o l_lx_elf86.lds
|
||||
$(CC_LINUX) -DNRV2B -o $T.o -c $<
|
||||
ld -T l_lx_elf86.lds -Map $T.map -o $T.bin \
|
||||
l_6e_n2b.o $T.o
|
||||
ld -T l_lx_elf86.lds -Map $T.map -o $T.bin l_6e_n2b.o $T.o
|
||||
$(SETFOLD) $T.bin
|
||||
$(BRANDELF) $T.bin
|
||||
$(BIN2H) $T.bin linux_i386elf_nrv2b_loader $@
|
||||
|
||||
l_sh_n2b.h: l_lx_sh.c l_6h_n2b.o l_lx_sh86.lds
|
||||
$(CC_LINUX) -DNRV2B -o $T.o -c $<
|
||||
ld -T l_lx_sh86.lds -Map $T.map -o $T.bin \
|
||||
l_6h_n2b.o $T.o
|
||||
ld -T l_lx_sh86.lds -Map $T.map -o $T.bin l_6h_n2b.o $T.o
|
||||
$(SETFOLD) $T.bin
|
||||
$(BRANDELF) $T.bin
|
||||
$(BIN2H) $T.bin linux_i386sh_nrv2b_loader $@
|
||||
|
@ -222,24 +219,21 @@ l_6h_n2b.o: l_lx_sh86.asm
|
|||
|
||||
l_lx_n2d.h: l_lx_exec.c l_xe_n2d.o l_lx_exec86.lds
|
||||
$(CC_LINUX) -DNRV2D -o $T.o -c $<
|
||||
ld -T l_lx_exec86.lds -Map $T.map -o $T.bin \
|
||||
l_xe_n2d.o $T.o
|
||||
ld -T l_lx_exec86.lds -Map $T.map -o $T.bin l_xe_n2d.o $T.o
|
||||
$(SETFOLD) $T.bin
|
||||
$(BRANDELF) $T.bin
|
||||
$(BIN2H) $T.bin linux_i386exec_nrv2d_loader $@
|
||||
|
||||
l_le_n2d.h: l_lx_elf.c l_6e_n2d.o l_lx_elf86.lds
|
||||
$(CC_LINUX) -DNRV2D -o $T.o -c $<
|
||||
ld -T l_lx_elf86.lds -Map $T.map -o $T.bin \
|
||||
l_6e_n2d.o $T.o
|
||||
ld -T l_lx_elf86.lds -Map $T.map -o $T.bin l_6e_n2d.o $T.o
|
||||
$(SETFOLD) $T.bin
|
||||
$(BRANDELF) $T.bin
|
||||
$(BIN2H) $T.bin linux_i386elf_nrv2d_loader $@
|
||||
|
||||
l_sh_n2d.h: l_lx_sh.c l_6h_n2d.o l_lx_sh86.lds
|
||||
$(CC_LINUX) -DNRV2D -o $T.o -c $<
|
||||
ld -T l_lx_sh86.lds -Map $T.map -o $T.bin \
|
||||
l_6h_n2d.o $T.o
|
||||
ld -T l_lx_sh86.lds -Map $T.map -o $T.bin l_6h_n2d.o $T.o
|
||||
$(SETFOLD) $T.bin
|
||||
$(BRANDELF) $T.bin
|
||||
$(BIN2H) $T.bin linux_i386sh_nrv2d_loader $@
|
||||
|
|
|
@ -31,10 +31,6 @@
|
|||
*/
|
||||
|
||||
|
||||
#if !defined(__linux__) || !defined(__i386__)
|
||||
# error "this stub must be compiled under linux/i386"
|
||||
#endif
|
||||
|
||||
#include "linux.hh"
|
||||
|
||||
|
||||
|
@ -46,9 +42,6 @@
|
|||
// it at an address different from it load address: there must be no
|
||||
// static data, and no string constants.
|
||||
|
||||
|
||||
#define PAGEMASK (~0u<<12) // discards the offset, keeps the page
|
||||
#define PAGESIZE ( 1u<<12)
|
||||
#define MAX_ELF_HDR 512 // Elf32_Ehdr + n*Elf32_Phdr must fit in this
|
||||
|
||||
|
||||
|
@ -188,7 +181,7 @@ make_hatch(Elf32_Phdr const *const phdr)
|
|||
// Try page fragmentation just beyond .text .
|
||||
if ( ( (hatch = (void *)(phdr->p_memsz + phdr->p_vaddr)),
|
||||
( phdr->p_memsz==phdr->p_filesz // don't pollute potential .bss
|
||||
&& 4<=(~PAGEMASK & -(int)hatch) ) ) // space left on page
|
||||
&& 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)->e_ident[12])),
|
||||
(phdr->p_offset==0) ) ) {
|
||||
|
@ -230,7 +223,7 @@ do_xmap(int const fdi, Elf32_Ehdr const *const ehdr, struct Extent *const xi,
|
|||
size_t mlen = xo.size = phdr->p_filesz;
|
||||
char *addr = xo.buf = (char *)phdr->p_vaddr;
|
||||
char *haddr = phdr->p_memsz + (char *)phdr->p_vaddr;
|
||||
size_t frag = (int)addr &~ PAGEMASK;
|
||||
size_t frag = (int)addr &~ PAGE_MASK;
|
||||
mlen += frag;
|
||||
addr -= frag;
|
||||
if (ET_DYN==ehdr->e_type) {
|
||||
|
@ -255,7 +248,7 @@ do_xmap(int const fdi, Elf32_Ehdr const *const ehdr, struct Extent *const xi,
|
|||
unpackExtent(xi, &xo, (f_expand *)fdi);
|
||||
}
|
||||
bzero(addr, frag); // fragment at lo end
|
||||
frag = (-mlen) &~ PAGEMASK; // distance to next page boundary
|
||||
frag = (-mlen) &~ PAGE_MASK; // distance to next page boundary
|
||||
bzero(mlen+addr, frag); // fragment at hi end
|
||||
if (xi) {
|
||||
make_hatch(phdr);
|
||||
|
@ -284,7 +277,7 @@ ERR_LAB
|
|||
if (xi) { // cleanup if decompressor overrun crosses page boundary
|
||||
mlen += 3;
|
||||
addr += mlen;
|
||||
mlen &= ~PAGEMASK;
|
||||
mlen &= ~PAGE_MASK;
|
||||
if (mlen<=3) { // page fragment was overrun buffer only
|
||||
munmap(addr - mlen, mlen);
|
||||
}
|
||||
|
@ -354,7 +347,7 @@ void *upx_main(
|
|||
av[0].a_type = AT_PHDR; // av[0].a_un.a_val is set by do_xmap
|
||||
av[1].a_type = AT_PHENT; av[1].a_un.a_val = ehdr->e_phentsize;
|
||||
av[2].a_type = AT_PHNUM; av[2].a_un.a_val = ehdr->e_phnum;
|
||||
av[3].a_type = AT_PAGESZ; av[3].a_un.a_val = PAGESIZE;
|
||||
av[3].a_type = AT_PAGESZ; av[3].a_un.a_val = PAGE_SIZE;
|
||||
av[4].a_type = AT_ENTRY; av[4].a_un.a_val = ehdr->e_entry;
|
||||
av[5].a_type = AT_NULL;
|
||||
entry = do_xmap((int)f_decompress, ehdr, &xi, av);
|
||||
|
|
|
@ -25,18 +25,17 @@
|
|||
*/
|
||||
|
||||
|
||||
#if !defined(__linux__) || !defined(__i386__)
|
||||
# error "this stub must be compiled under linux/i386"
|
||||
#endif
|
||||
|
||||
#include "linux.hh"
|
||||
#include <elf.h>
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// configuration section
|
||||
**************************************************************************/
|
||||
|
||||
// mmap() the temporary output file
|
||||
#define USE_MMAP_FO
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// file util
|
||||
**************************************************************************/
|
||||
|
@ -46,6 +45,29 @@ struct Extent {
|
|||
char *buf;
|
||||
};
|
||||
|
||||
|
||||
#if !defined(USE_MMAP_FO)
|
||||
#if 1
|
||||
static __inline__ int xwrite(int fd, const void *buf, int count)
|
||||
{
|
||||
// note: we can assert(count > 0);
|
||||
do {
|
||||
int n = write(fd, buf, count);
|
||||
if (n == -EINTR)
|
||||
continue;
|
||||
if (n <= 0)
|
||||
break;
|
||||
buf += n; // gcc extension: add to void *
|
||||
count -= n;
|
||||
} while (count > 0);
|
||||
return count;
|
||||
}
|
||||
#else
|
||||
#define xwrite(fd,buf,count) ((count) - write(fd,buf,count))
|
||||
#endif
|
||||
#endif /* !USE_MMAP_FO */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// util
|
||||
**************************************************************************/
|
||||
|
@ -72,15 +94,16 @@ static char *upx_itoa(char *buf, unsigned long v)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static uint32_t ascii5(uint32_t r, unsigned k, char *p)
|
||||
|
||||
static uint32_t ascii5(char *p, uint32_t v, unsigned n)
|
||||
{
|
||||
do {
|
||||
unsigned char d = r % 32;
|
||||
unsigned char d = v % 32;
|
||||
if (d >= 26) d += '0' - 'Z' - 1;
|
||||
*--p += d;
|
||||
r /= 32;
|
||||
} while (--k > 0);
|
||||
return r;
|
||||
v /= 32;
|
||||
} while (--n > 0);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,17 +128,11 @@ static uint32_t ascii5(uint32_t r, unsigned k, char *p)
|
|||
// UPX & NRV stuff
|
||||
**************************************************************************/
|
||||
|
||||
// patch constants for our loader (le32 format)
|
||||
#define UPX1 0x31585055 // "UPX1"
|
||||
#define UPX2 0x32585055 // "UPX2"
|
||||
#define UPX3 0x33585055 // "UPX4"
|
||||
#define UPX4 0x34585055 // "UPX4"
|
||||
#define UPX5 0x35585055 // "UPX5"
|
||||
|
||||
typedef int f_expand(
|
||||
const nrv_byte *src, nrv_uint src_len,
|
||||
nrv_byte *dst, nrv_uint *dst_len );
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// upx_main - called by our entry code
|
||||
//
|
||||
|
@ -135,7 +152,6 @@ void upx_main(
|
|||
f_expand *const f_decompress
|
||||
)
|
||||
{
|
||||
#define PAGE_MASK (~0<<12)
|
||||
// file descriptors
|
||||
int fdi, fdo;
|
||||
Elf32_Phdr const *const phdr = (Elf32_Phdr const *)
|
||||
|
@ -150,7 +166,10 @@ void upx_main(
|
|||
// temporary file name (max 14 chars)
|
||||
static char tmpname_buf[] = "/tmp/upxAAAAAAAAAAA";
|
||||
char *tmpname = tmpname_buf;
|
||||
char procself_buf[24]; // /proc/PPPPP/fd/XX
|
||||
// 17 chars for "/proc/PPPPP/fd/XX" should be enough, but we
|
||||
// play safe in case there will be 32-bit pid_t at some time.
|
||||
//char procself_buf[17+1];
|
||||
char procself_buf[31+1];
|
||||
char *procself;
|
||||
|
||||
// decompression buffer
|
||||
|
@ -163,12 +182,18 @@ void upx_main(
|
|||
int ma_fd;
|
||||
off_t ma_offset;
|
||||
} malloc_args = {
|
||||
#if defined(USE_MMAP_FO)
|
||||
0, 0, PROT_READ | PROT_WRITE, MAP_SHARED, 0, 0
|
||||
#else
|
||||
0, 0, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0
|
||||
#endif
|
||||
};
|
||||
#if defined(USE_MMAP_FO)
|
||||
static struct MallocArgs scratch_page = {
|
||||
0, -PAGE_MASK, PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// ----- Step 0: set /proc/self using /proc/<pid> -----
|
||||
|
@ -188,11 +213,11 @@ void upx_main(
|
|||
|
||||
// Read header.
|
||||
{
|
||||
register char *__d0, *__d1;
|
||||
__asm__ __volatile__( "movsl; movsl; movsl"
|
||||
: "=&D" (__d0), "=&S" (__d1)
|
||||
: "0" (&header), "1" (xi.buf)
|
||||
: "memory");
|
||||
register char *__d0, *__d1;
|
||||
__asm__ __volatile__( "movsl; movsl; movsl"
|
||||
: "=&D" (__d0), "=&S" (__d1)
|
||||
: "0" (&header), "1" (xi.buf)
|
||||
: "memory");
|
||||
xi.buf = __d1;
|
||||
xi.size -= sizeof(header);
|
||||
}
|
||||
|
@ -214,7 +239,7 @@ void upx_main(
|
|||
char *p = tmpname_buf + sizeof(tmpname_buf) - 1;
|
||||
|
||||
// Compute the last 4 characters (20 bits) from getpid().
|
||||
uint32_t r = ascii5((uint32_t)pid, 4, p); p-=4;
|
||||
uint32_t r = ascii5(p, (uint32_t)pid, 4); p-=4;
|
||||
|
||||
// Provide 4 random bytes from our program id.
|
||||
r ^= header.p_progid;
|
||||
|
@ -236,7 +261,7 @@ void upx_main(
|
|||
#endif
|
||||
}
|
||||
// Compute 7 more characters from the 32 random bits.
|
||||
ascii5(r, 7, p);
|
||||
ascii5(p, r, 7);
|
||||
}
|
||||
|
||||
// Just in case, remove the file.
|
||||
|
@ -247,7 +272,11 @@ void upx_main(
|
|||
}
|
||||
|
||||
// Create the temporary output file.
|
||||
#if defined(USE_MMAP_FO)
|
||||
fdo = open(tmpname, O_RDWR | O_CREAT | O_EXCL, 0700);
|
||||
#else
|
||||
fdo = open(tmpname, O_WRONLY | O_CREAT | O_EXCL, 0700);
|
||||
#endif
|
||||
#if 0
|
||||
// Save some bytes of code - the ftruncate() below will fail anyway.
|
||||
if (fdo < 0)
|
||||
|
@ -263,8 +292,11 @@ void upx_main(
|
|||
// ----- Step 3: setup memory -----
|
||||
//
|
||||
|
||||
#if defined(USE_MMAP_FO)
|
||||
// mmap()ed output file.
|
||||
malloc_args.ma_fd = fdo;
|
||||
malloc_args.ma_length = header.p_filesize; // could packer do this?
|
||||
// FIXME: packer could set ma_length
|
||||
malloc_args.ma_length = header.p_filesize;
|
||||
buf = mmap((int *)&malloc_args);
|
||||
if ((unsigned long) buf >= (unsigned long) -4095)
|
||||
goto error;
|
||||
|
@ -273,6 +305,14 @@ void upx_main(
|
|||
// Defend against SIGSEGV by using a scratch page.
|
||||
scratch_page.ma_addr = buf + (PAGE_MASK & (header.p_filesize + ~PAGE_MASK));
|
||||
mmap((int *)&scratch_page);
|
||||
#else
|
||||
// Temporary decompression buffer.
|
||||
// FIXME: packer could set ma_length
|
||||
malloc_args.ma_length = (header.p_blocksize + OVERHEAD + ~PAGE_MASK) & PAGE_MASK;
|
||||
buf = mmap((int *)&malloc_args);
|
||||
if ((unsigned long) buf >= (unsigned long) -4095)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
//
|
||||
// ----- Step 4: decompress blocks -----
|
||||
|
@ -290,19 +330,19 @@ void upx_main(
|
|||
|
||||
// Read and check block sizes.
|
||||
{
|
||||
register char *__d0, *__d1;
|
||||
__asm__ __volatile__( "movsl; movsl"
|
||||
: "=&D" (__d0), "=&S" (__d1)
|
||||
: "0" (&h), "1" (xi.buf)
|
||||
: "memory");
|
||||
register char *__d0, *__d1;
|
||||
__asm__ __volatile__( "movsl; movsl"
|
||||
: "=&D" (__d0), "=&S" (__d1)
|
||||
: "0" (&h), "1" (xi.buf)
|
||||
: "memory");
|
||||
xi.buf = __d1;
|
||||
xi.size -= sizeof(h);
|
||||
}
|
||||
if (h.sz_unc == 0) // uncompressed size 0 -> EOF
|
||||
if (h.sz_unc == 0) // uncompressed size 0 -> EOF
|
||||
{
|
||||
if (h.sz_cpr != UPX_MAGIC_LE32) // h.sz_cpr must be h->magic
|
||||
if (h.sz_cpr != UPX_MAGIC_LE32) // h.sz_cpr must be h->magic
|
||||
goto error;
|
||||
if (header.p_filesize != 0) // all bytes must be written
|
||||
if (header.p_filesize != 0) // all bytes must be written
|
||||
goto error;
|
||||
break;
|
||||
}
|
||||
|
@ -321,16 +361,29 @@ void upx_main(
|
|||
if (i != 0 || out_len != (nrv_uint)h.sz_unc)
|
||||
goto error;
|
||||
}
|
||||
else { // Incompressible block
|
||||
else
|
||||
{
|
||||
// Incompressible block
|
||||
#if defined(USE_MMAP_FO)
|
||||
//memcpy(buf, xi.buf, h.sz_unc);
|
||||
register unsigned long int __d0, __d1, __d2;
|
||||
__asm__ __volatile__( "rep; movsb"
|
||||
: "=&c" (__d0), "=&D" (__d1), "=&S" (__d2)
|
||||
: "0" (h.sz_unc), "1" (buf), "2" (xi.buf)
|
||||
: "memory");
|
||||
register unsigned long int __d0, __d1, __d2;
|
||||
__asm__ __volatile__( "rep; movsb"
|
||||
: "=&c" (__d0), "=&D" (__d1), "=&S" (__d2)
|
||||
: "0" (h.sz_unc), "1" (buf), "2" (xi.buf)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(USE_MMAP_FO)
|
||||
// unmap part of the output
|
||||
munmap(buf, h.sz_unc);
|
||||
buf += h.sz_unc;
|
||||
#else
|
||||
// write output file
|
||||
if (xwrite(fdo, buf, h.sz_unc) != 0)
|
||||
goto error;
|
||||
#endif
|
||||
|
||||
header.p_filesize -= h.sz_unc;
|
||||
|
||||
xi.buf += h.sz_cpr;
|
||||
|
@ -358,6 +411,12 @@ void upx_main(
|
|||
// ----- Step 5: release resources -----
|
||||
//
|
||||
|
||||
|
||||
#if !defined(USE_MMAP_FO)
|
||||
// Free our temporary decompression buffer.
|
||||
munmap(buf, malloc_args.ma_length);
|
||||
#endif
|
||||
|
||||
if (close(fdo) != 0)
|
||||
goto error;
|
||||
|
||||
|
@ -390,7 +449,7 @@ void upx_main(
|
|||
fcntl(fdi, F_SETFD, FD_CLOEXEC);
|
||||
// Execute the original program via /proc/self/fd/X.
|
||||
execve(procself_buf, argv, envp);
|
||||
// If we get here we've lost.
|
||||
// NOTE: if we get here we've lost.
|
||||
}
|
||||
#undef err
|
||||
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
Integration of virtual exec() with decompression is
|
||||
Copyright (C) 2000 John F. Reiser. All rights reserved.
|
||||
<jreiser@BitWagon.com>
|
||||
|
||||
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
|
||||
|
@ -27,39 +26,20 @@
|
|||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus.oberhumer@jk.uni-linz.ac.at ml1050@cdata.tvnet.hu
|
||||
|
||||
John F. Reiser
|
||||
jreiser@BitWagon.com
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(__linux__) || !defined(__i386__)
|
||||
# error "this stub must be compiled under linux/i386"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#include "linux.hh"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// configuration section
|
||||
**************************************************************************/
|
||||
|
||||
// must be the same as in p_linux.cpp !
|
||||
#define OVERHEAD 2048
|
||||
|
||||
#define PAGEMASK (~0u<<12) // discards the offset, keeps the page
|
||||
#define PAGESIZE ( 1u<<12)
|
||||
#define MAX_ELF 512 // Elf32_Ehdr + n*Elf32_Phdr must fit in this
|
||||
|
||||
#undef int32_t
|
||||
#undef uint32_t
|
||||
#define int32_t int
|
||||
#define uint32_t unsigned int
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
|
||||
/*************************************************************************
|
||||
// file util
|
||||
|
@ -139,14 +119,11 @@ do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
|
|||
return mmap((int *)&addr);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// UPX & NRV stuff
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
// patch & magic constants for our loader (le32 format)
|
||||
#define UPX_MAGIC_LE32 0x21585055 // "UPX!"
|
||||
|
||||
typedef int f_expand(
|
||||
const nrv_byte *, nrv_uint,
|
||||
nrv_byte *, nrv_uint * );
|
||||
|
@ -217,8 +194,6 @@ ERR_LAB
|
|||
}
|
||||
}
|
||||
|
||||
#include <elf.h>
|
||||
|
||||
// Create (or find) an escape hatch to use when munmapping ourselves the stub.
|
||||
// Called by do_xmap to create it, and by assembler code to find it.
|
||||
void *
|
||||
|
@ -237,7 +212,7 @@ make_hatch(Elf32_Phdr const *const phdr)
|
|||
// Try page fragmentation just beyond .text .
|
||||
if ( ( (hatch = (void *)(phdr->p_memsz + phdr->p_vaddr)),
|
||||
( phdr->p_memsz==phdr->p_filesz // don't pollute potential .bss
|
||||
&& 4<=(~PAGEMASK & -(int)hatch) ) ) // space left on page
|
||||
&& 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)->e_ident[12])),
|
||||
(phdr->p_offset==0) ) ) {
|
||||
|
@ -278,7 +253,7 @@ do_xmap(int fdi, Elf32_Ehdr const *const ehdr, f_expand *const f_decompress,
|
|||
size_t mlen = x.size = phdr->p_filesz;
|
||||
char *addr = x.buf = (char *)phdr->p_vaddr;
|
||||
char *haddr = phdr->p_memsz + (char *)phdr->p_vaddr;
|
||||
size_t frag = (int)addr &~ PAGEMASK;
|
||||
size_t frag = (int)addr &~ PAGE_MASK;
|
||||
mlen += frag;
|
||||
addr -= frag;
|
||||
if (ET_DYN==ehdr->e_type) {
|
||||
|
@ -301,7 +276,7 @@ do_xmap(int fdi, Elf32_Ehdr const *const ehdr, f_expand *const f_decompress,
|
|||
unpackExtent(&x, fdi, f_decompress);
|
||||
}
|
||||
bzero(addr, frag); // fragment at lo end
|
||||
frag = (-mlen) &~ PAGEMASK; // distance to next page boundary
|
||||
frag = (-mlen) &~ PAGE_MASK; // distance to next page boundary
|
||||
bzero(mlen+addr, frag); // fragment at hi end
|
||||
if (f_decompress) {
|
||||
make_hatch(phdr);
|
||||
|
@ -330,7 +305,7 @@ ERR_LAB
|
|||
if (f_decompress) { // cleanup if decompressor overrun crosses page boundary
|
||||
mlen += 3;
|
||||
addr += mlen;
|
||||
mlen &= ~PAGEMASK;
|
||||
mlen &= ~PAGE_MASK;
|
||||
if (mlen<=3) { // page fragment was overrun buffer only
|
||||
munmap(addr - mlen, mlen);
|
||||
}
|
||||
|
@ -422,7 +397,7 @@ ERR_LAB
|
|||
av[0].a_type = AT_PHDR; av[0].a_un.a_val = 0; // updated by do_xmap
|
||||
av[1].a_type = AT_PHENT; av[1].a_un.a_val = ehdr->e_phentsize;
|
||||
av[2].a_type = AT_PHNUM; av[2].a_un.a_val = ehdr->e_phnum;
|
||||
av[3].a_type = AT_PAGESZ; av[3].a_un.a_val = PAGESIZE;
|
||||
av[3].a_type = AT_PAGESZ; av[3].a_un.a_val = PAGE_SIZE;
|
||||
av[4].a_type = AT_ENTRY; av[4].a_un.a_val = ehdr->e_entry;
|
||||
av[5].a_type = AT_NULL;
|
||||
entry = do_xmap(fdi, ehdr, f_decompress, av);
|
||||
|
|
|
@ -31,10 +31,6 @@
|
|||
*/
|
||||
|
||||
|
||||
#if !defined(__linux__) || !defined(__i386__)
|
||||
# error "this stub must be compiled under linux/i386"
|
||||
#endif
|
||||
|
||||
#include "linux.hh"
|
||||
|
||||
|
||||
|
@ -46,9 +42,6 @@
|
|||
// it at an address different from it load address: there must be no
|
||||
// static data, and no string constants.
|
||||
|
||||
|
||||
#define PAGEMASK (~0u<<12) // discards the offset, keeps the page
|
||||
#define PAGESIZE ( 1u<<12)
|
||||
#define MAX_ELF_HDR 512 // Elf32_Ehdr + n*Elf32_Phdr must fit in this
|
||||
|
||||
|
||||
|
@ -113,7 +106,6 @@ do_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
|
|||
// UPX & NRV stuff
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
typedef int f_expand(
|
||||
const nrv_byte *, nrv_uint,
|
||||
nrv_byte *, nrv_uint * );
|
||||
|
@ -202,7 +194,7 @@ do_xmap(int const fdi, Elf32_Ehdr const *const ehdr, Elf32_auxv_t *const a)
|
|||
size_t mlen = xo.size = phdr->p_filesz;
|
||||
char *addr = xo.buf = (char *)phdr->p_vaddr;
|
||||
char *haddr = phdr->p_memsz + (char *)phdr->p_vaddr;
|
||||
size_t frag = (int)addr &~ PAGEMASK;
|
||||
size_t frag = (int)addr &~ PAGE_MASK;
|
||||
mlen += frag;
|
||||
addr -= frag;
|
||||
if (ET_DYN==ehdr->e_type) {
|
||||
|
@ -222,7 +214,7 @@ do_xmap(int const fdi, Elf32_Ehdr const *const ehdr, Elf32_auxv_t *const a)
|
|||
base = (unsigned long)addr;
|
||||
}
|
||||
bzero(addr, frag); // fragment at lo end
|
||||
frag = (-mlen) &~ PAGEMASK; // distance to next page boundary
|
||||
frag = (-mlen) &~ PAGE_MASK; // distance to next page boundary
|
||||
bzero(mlen+addr, frag); // fragment at hi end
|
||||
if (phdr->p_memsz != phdr->p_filesz) { // .bss
|
||||
if (ET_DYN==ehdr->e_type) { // PT_INTERP whole pages of .bss?
|
||||
|
@ -322,9 +314,6 @@ void *upx_main(
|
|||
// 'fn' and 'efn' must not suffer constant-propagation by gcc
|
||||
// UPX2 = 3 + offset to name_of_shell
|
||||
// UPX3 = strlen(name_of_shell)
|
||||
// patch & magic constants for our loader (le32 format)
|
||||
#define UPX2 0x32585055 // "UPX2"
|
||||
#define UPX3 0x33585055 // "UPX3"
|
||||
char * /*const*/ volatile fn = UPX2 + uncbuf; // past "-c" and "#!"
|
||||
char * /*const*/ volatile efn = UPX3 + fn; // &terminator
|
||||
char const c = *efn; *efn = 0; // terminator
|
||||
|
@ -334,7 +323,7 @@ void *upx_main(
|
|||
av[0].a_type = AT_PHDR; // av[0].a_un.a_val is set by do_xmap
|
||||
av[1].a_type = AT_PHENT; av[1].a_un.a_val = ehdr->e_phentsize;
|
||||
av[2].a_type = AT_PHNUM; av[2].a_un.a_val = ehdr->e_phnum;
|
||||
av[3].a_type = AT_PAGESZ; av[3].a_un.a_val = PAGESIZE;
|
||||
av[3].a_type = AT_PAGESZ; av[3].a_un.a_val = PAGE_SIZE;
|
||||
av[4].a_type = AT_ENTRY; av[4].a_un.a_val = entry;
|
||||
av[5].a_type = AT_NULL;
|
||||
}
|
||||
|
@ -347,6 +336,7 @@ void *upx_main(
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (void *)entry;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,9 +55,15 @@
|
|||
// !!! must be the same as in p_unix.h !!!
|
||||
#define OVERHEAD 2048
|
||||
|
||||
|
||||
#define UPX_MAGIC_LE32 0x21585055 // "UPX!"
|
||||
|
||||
// patch constants for our loader (le32 format)
|
||||
#define UPX1 0x31585055 // "UPX1"
|
||||
#define UPX2 0x32585055 // "UPX2"
|
||||
#define UPX3 0x33585055 // "UPX4"
|
||||
#define UPX4 0x34585055 // "UPX4"
|
||||
#define UPX5 0x35585055 // "UPX5"
|
||||
|
||||
|
||||
#undef int32_t
|
||||
#undef uint32_t
|
||||
|
@ -74,13 +80,15 @@ typedef unsigned int nrv_uint32;
|
|||
|
||||
|
||||
// From ../p_unix.h
|
||||
struct l_info { // 12-byte trailer in header for loader
|
||||
struct l_info // 12-byte trailer in header for loader (offset 116)
|
||||
{
|
||||
uint32_t l_checksum;
|
||||
uint32_t l_magic;
|
||||
uint16_t l_lsize;
|
||||
uint8_t l_version;
|
||||
uint8_t l_format;
|
||||
};
|
||||
|
||||
struct p_info // 12-byte packed program header follows stub loader
|
||||
{
|
||||
uint32_t p_progid;
|
||||
|
@ -89,6 +97,13 @@ struct p_info // 12-byte packed program header follows stub loader
|
|||
};
|
||||
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
|
||||
#define PAGE_MASK (~0u<<12) // discards the offset, keeps the page
|
||||
#define PAGE_SIZE ( 1u<<12)
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// syscalls
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue