Cleaned up the Linux C stub loaders by putting more stuff into linux.hh.

committer: mfx <mfx> 962045590 +0000
This commit is contained in:
Markus F.X.J. Oberhumer 2000-06-26 18:53:10 +00:00
parent 957ef351c4
commit 51b162f069
10 changed files with 150 additions and 116 deletions

View File

@ -1,3 +1,5 @@
*.00?
*.upx
.gdbinit
upx
upx.map

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 $@

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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
//