From 51b162f069c7e461a1d66fa6a99088ec9d73a257 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Mon, 26 Jun 2000 18:53:10 +0000 Subject: [PATCH] Cleaned up the Linux C stub loaders by putting more stuff into linux.hh. committer: mfx 962045590 +0000 --- src/.cvsignore | 2 + src/p_lx_elf.cpp | 2 + src/p_lx_sh.cpp | 2 + src/p_unix.cpp | 2 + src/stub/Makefile | 18 ++---- src/stub/l_lx_elf.c | 17 ++--- src/stub/l_lx_exec.c | 143 ++++++++++++++++++++++++++++++------------- src/stub/l_lx_sep.c | 43 +++---------- src/stub/l_lx_sh.c | 18 ++---- src/stub/linux.hh | 19 +++++- 10 files changed, 150 insertions(+), 116 deletions(-) diff --git a/src/.cvsignore b/src/.cvsignore index 4afe33d3..0c1f365b 100644 --- a/src/.cvsignore +++ b/src/.cvsignore @@ -1,3 +1,5 @@ +*.00? *.upx +.gdbinit upx upx.map diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 6d201e91..7d0696e9 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -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 diff --git a/src/p_lx_sh.cpp b/src/p_lx_sh.cpp index 043e1c63..9015af8a 100644 --- a/src/p_lx_sh.cpp +++ b/src/p_lx_sh.cpp @@ -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 diff --git a/src/p_unix.cpp b/src/p_unix.cpp index 79756ac0..4ba22b4e 100644 --- a/src/p_unix.cpp +++ b/src/p_unix.cpp @@ -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 diff --git a/src/stub/Makefile b/src/stub/Makefile index 0517bb23..e80d73f3 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -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 $@ diff --git a/src/stub/l_lx_elf.c b/src/stub/l_lx_elf.c index 5fc0a7ff..6622be7e 100644 --- a/src/stub/l_lx_elf.c +++ b/src/stub/l_lx_elf.c @@ -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); diff --git a/src/stub/l_lx_exec.c b/src/stub/l_lx_exec.c index 424dd065..aa561d55 100644 --- a/src/stub/l_lx_exec.c +++ b/src/stub/l_lx_exec.c @@ -25,18 +25,17 @@ */ -#if !defined(__linux__) || !defined(__i386__) -# error "this stub must be compiled under linux/i386" -#endif - #include "linux.hh" -#include /************************************************************************* // 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/ ----- @@ -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 diff --git a/src/stub/l_lx_sep.c b/src/stub/l_lx_sep.c index f73ec4ce..c2202904 100644 --- a/src/stub/l_lx_sep.c +++ b/src/stub/l_lx_sep.c @@ -7,7 +7,6 @@ Integration of virtual exec() with decompression is Copyright (C) 2000 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 @@ -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 -#include -#include -#include -#include - #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 - // 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); diff --git a/src/stub/l_lx_sh.c b/src/stub/l_lx_sh.c index ae6aca96..9f82b27b 100644 --- a/src/stub/l_lx_sh.c +++ b/src/stub/l_lx_sh.c @@ -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; } diff --git a/src/stub/linux.hh b/src/stub/linux.hh index c5d4c36a..142e14fe 100644 --- a/src/stub/linux.hh +++ b/src/stub/linux.hh @@ -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 //