From 3f4acb33f9d2b7bf73de31a9cb0195fa01da6132 Mon Sep 17 00:00:00 2001 From: "Markus F.X.J. Oberhumer" Date: Tue, 21 Nov 2006 16:00:25 +0100 Subject: [PATCH] First step for possibly using ElfLinker with linux execve/interp/shell stubs as well. --- src/stub/Makefile | 16 ++- src/stub/src/amd64-linux.elf-main.c | 1 - src/stub/src/i386-bsd.elf.execve-main.c | 2 +- src/stub/src/i386-linux.elf-main.c | 3 +- src/stub/src/i386-linux.elf.execve-main.c | 2 +- src/stub/src/include/bsd.h | 57 ++++++----- src/stub/src/include/darwin.h | 119 ++++++++++++++++++++++ src/stub/src/include/linux.h | 24 +++-- src/stub/src/powerpc-darwin.macho-main.c | 24 +---- src/stub/src/powerpc-linux.elf-main.c | 3 +- 10 files changed, 192 insertions(+), 59 deletions(-) create mode 100644 src/stub/src/include/darwin.h diff --git a/src/stub/Makefile b/src/stub/Makefile index 2f1d39bb..acd8d356 100644 --- a/src/stub/Makefile +++ b/src/stub/Makefile @@ -234,6 +234,7 @@ tmp/amd64-linux.elf-fold.o : $(srcdir)/src/$$T.S tmp/amd64-linux.elf-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c -Os $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # /*********************************************************************** @@ -265,6 +266,7 @@ tmp/arm-linux.elf-fold.o : $(srcdir)/src/$$T.S tmp/arm-linux.elf-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c -Os $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # /*********************************************************************** @@ -294,6 +296,7 @@ tmp/armeb-linux.elf-fold.o : $(srcdir)/src/$$T.S tmp/armeb-linux.elf-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c -Os $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # /*********************************************************************** @@ -390,6 +393,7 @@ tmp/i386-bsd.syscall.o: $(srcdir)/src/$$T.S tmp/i386-bsd.elf-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # info: we use the tc settings from i386-linux.elf @@ -412,6 +416,7 @@ tmp/i386-openbsd.elf-fold.o : $(srcdir)/src/$$T.S tmp/i386-openbsd.elf-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # /*********************************************************************** @@ -440,6 +445,7 @@ tmp/i386-bsd.elf.execve-fold.o : $(srcdir)/src/$$T.S tmp/i386-bsd.elf.execve-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm tmp/i386-bsd.elf.execve-upx_itoa.o: $(srcdir)/src/$$T.S $(call tc,gcc) -c -x assembler-with-cpp $< -o $@ @@ -523,6 +529,7 @@ tmp/i386-linux.elf-fold.o : $(srcdir)/src/$$T.S tmp/i386-linux.elf-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # /*********************************************************************** @@ -550,6 +557,7 @@ tmp/i386-linux.elf.execve-fold.o : $(srcdir)/src/$$T.S tmp/i386-linux.elf.execve-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm tmp/i386-linux.elf.execve-upx_itoa.o: $(srcdir)/src/$$T.S $(call tc,gcc) -c -x assembler-with-cpp $< -o $@ @@ -581,6 +589,7 @@ tmp/i386-linux.elf.interp-fold.o : $(srcdir)/src/$$T.S tmp/i386-linux.elf.interp-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # /*********************************************************************** @@ -608,6 +617,7 @@ tmp/i386-linux.elf.shell-fold.o : $(srcdir)/src/$$T.S tmp/i386-linux.elf.shell-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # /*********************************************************************** @@ -712,6 +722,7 @@ tmp/powerpc-darwin.macho-fold.o : $(srcdir)/src/$$T.S tmp/powerpc-darwin.macho-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c -Os $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # /*********************************************************************** @@ -743,6 +754,7 @@ tmp/powerpc-linux.elf-fold.o : $(srcdir)/src/$$T.S tmp/powerpc-linux.elf-main.o : $(srcdir)/src/$$T.c $(call tc,gcc) -c -Os $< -o $@ $(call tc,f-objstrip,$@) + $(call tc,objdump) -dr $(tc_objdump_disasm_options) $@ | $(RTRIM) > $@.disasm # /*********************************************************************** @@ -751,12 +763,10 @@ tmp/powerpc-linux.elf-main.o : $(srcdir)/src/$$T.c ifneq ($(strip $(STUBS)),) # FIXME: we want a dependency-only prerequisite here -$(STUBS): tmp/.tmp-stamp $(MAKEFILE_LIST) -$(STUBS): $(top_srcdir)/src/stub/scripts/bin2h.py +$(STUBS): tmp/.tmp-stamp $(MAKEFILE_LIST) $(top_srcdir)/src/stub/scripts/bin2h.py endif -include tmp/*.d -.DELETE_ON_ERROR: %.h %.o ifneq ($(strip $(STUBS)),) .DELETE_ON_ERROR: $(STUBS) endif diff --git a/src/stub/src/amd64-linux.elf-main.c b/src/stub/src/amd64-linux.elf-main.c index 649e3387..e50ce0cd 100644 --- a/src/stub/src/amd64-linux.elf-main.c +++ b/src/stub/src/amd64-linux.elf-main.c @@ -31,7 +31,6 @@ #include "include/linux.h" -extern void exit(int); /************************************************************************* diff --git a/src/stub/src/i386-bsd.elf.execve-main.c b/src/stub/src/i386-bsd.elf.execve-main.c index 33659873..5e3d05a4 100644 --- a/src/stub/src/i386-bsd.elf.execve-main.c +++ b/src/stub/src/i386-bsd.elf.execve-main.c @@ -176,7 +176,7 @@ go_self(char const *tmpname, char *argv[], char *envp[]) // Check for working /proc/self/fd/X by accessing the // temp file again, now via temp fdi. - if (UPX2 == access(procself_buf, R_OK | X_OK)) { + if (UPX2 == (unsigned) access(procself_buf, R_OK | X_OK)) { // Now it's safe to unlink the temp file (as it is still open). unlink(tmpname); // Set the file close-on-exec. diff --git a/src/stub/src/i386-linux.elf-main.c b/src/stub/src/i386-linux.elf-main.c index 6005e973..6fc03676 100644 --- a/src/stub/src/i386-linux.elf-main.c +++ b/src/stub/src/i386-linux.elf-main.c @@ -31,6 +31,7 @@ #include "include/linux.h" +void *mmap(void *, size_t, int, int, int, off_t); /************************************************************************* @@ -184,8 +185,6 @@ do_brk(void *addr) return brk(addr); } -extern void *mmap(void *addr, size_t len, - int prot, int flags, int fd, off_t offset); /************************************************************************* // UPX & NRV stuff diff --git a/src/stub/src/i386-linux.elf.execve-main.c b/src/stub/src/i386-linux.elf.execve-main.c index 22177dcc..4d6dd604 100644 --- a/src/stub/src/i386-linux.elf.execve-main.c +++ b/src/stub/src/i386-linux.elf.execve-main.c @@ -179,7 +179,7 @@ go_self(char const *tmpname, char *argv[], char *envp[]) // Check for working /proc/self/fd/X by accessing the // temp file again, now via temp fdi. - if (UPX2 == access(procself_buf, R_OK | X_OK)) { + if (UPX2 == (unsigned) access(procself_buf, R_OK | X_OK)) { // Now it's safe to unlink the temp file (as it is still open). unlink(tmpname); // Set the file close-on-exec. diff --git a/src/stub/src/include/bsd.h b/src/stub/src/include/bsd.h index 981a2a08..17b99d1b 100644 --- a/src/stub/src/include/bsd.h +++ b/src/stub/src/include/bsd.h @@ -1,4 +1,4 @@ -/* BSD.h -- common stuff to the BSD stub loaders +/* bsd.h -- common stuff for the BSD stub loaders This file is part of the UPX executable compressor. @@ -130,7 +130,7 @@ struct timespec { #define MAP_PRIVATE 0x02 #define MAP_FIXED 0x10 #define MAP_ANONYMOUS 0x1000 /* differs from Linux */ -#define MAP_DENYWRITE 0x0 /* does not exist on BSD ? */ +#define MAP_DENYWRITE 0x0 /* does not exist on BSD ? */ /************************************************************************* @@ -143,26 +143,27 @@ struct timespec { // use optimized assembly statements to further decrease the size. **************************************************************************/ -extern void *brk(void *); -extern int close(int); -extern void *mmap(void *, size_t, int, int, int, unsigned); -extern int munmap(void *, size_t); -extern int mprotect(void const *, size_t, int); -extern int open(char const *, unsigned, unsigned); -extern ssize_t read(int, void *, size_t); -extern ssize_t write(int, char const *, size_t); -void exit(int) __attribute__((noreturn)); +int access(char const *,int); +int execve(char const *,char const *const *,char const *const *); +int fcntl(int,int,long); +int ftruncate(int,size_t); +pid_t fork(void); +pid_t getpid(void); +int gettimeofday(struct timeval *,void *); +int nanosleep(struct timespec const *,struct timespec *); +pid_t waitpid(pid_t,int *,int); +int unlink(char const *); + +void *brk(void *); +int close(int); +void exit(int) __attribute__((__noreturn__,__nothrow__)); +void *mmap(void *, size_t, int, int, int, off_t); +int munmap(void *, size_t); +int mprotect(void const *, size_t, int); +int open(char const *, unsigned, unsigned); +ssize_t read(int, void *, size_t); +ssize_t write(int, void const *, size_t); -extern int access(char const *,int); -extern int execve(char const *,char const *const *,char const *const *); -extern int fcntl(int,int,long); -extern int ftruncate(int,size_t); -extern pid_t fork(void); -extern pid_t getpid(void); -extern int gettimeofday(struct timeval *,void *); -extern int nanosleep(struct timespec const *,struct timespec *); -extern pid_t waitpid(pid_t,int *,int); -extern int unlink(char const *); /************************************************************************* // @@ -297,12 +298,22 @@ typedef struct #define UPX_MAGIC_LE32 0x21585055 // "UPX!" +#if 1 // patch constants for our loader (le32 format) -#define UPX1 0x31585055 // "UPX1" +//#define UPX1 0x31585055 // "UPX1" #define UPX2 0x32585055 // "UPX2" #define UPX3 0x33585055 // "UPX4" #define UPX4 0x34585055 // "UPX4" -#define UPX5 0x35585055 // "UPX5" +//#define UPX5 0x35585055 // "UPX5" +#else +// transform into relocations when using ElfLinker +extern const unsigned UPX2; +extern const unsigned UPX3; +extern const unsigned UPX4; +#define UPX2 ((unsigned) (const void *) &UPX2) +#define UPX3 ((unsigned) (const void *) &UPX3) +#define UPX4 ((unsigned) (const void *) &UPX4) +#endif typedef int nrv_int; diff --git a/src/stub/src/include/darwin.h b/src/stub/src/include/darwin.h new file mode 100644 index 00000000..f448b5cb --- /dev/null +++ b/src/stub/src/include/darwin.h @@ -0,0 +1,119 @@ +/* darwin.h -- common stuff for the Darwin stub loaders + + This file is part of the UPX executable compressor. + + Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer + Copyright (C) 1996-2006 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 + + */ + + +// NOTE: +// to avoid endless problems with moving libc and kernel headers, this +// section is now completely freestanding + + +#if defined(__GNUC__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define ACC_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__) +# elif defined(__GNUC_MINOR__) +# define ACC_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100) +# else +# define ACC_CC_GNUC (__GNUC__ * 0x10000L) +# endif +#endif + +#define ACC_UNUSED(var) ((void) var) + + +/************************************************************************* +// +**************************************************************************/ + +// +typedef long ptrdiff_t; +typedef long ssize_t; +typedef unsigned long size_t; +// +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef int int32_t; +typedef unsigned uint32_t; +#if (ACC_CC_GNUC >= 0x020800ul) +__extension__ typedef long long int64_t; +__extension__ typedef unsigned long long uint64_t; +#elif defined(_WIN32) +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; +#else +typedef long long int64_t; +typedef unsigned long long uint64_t; +#endif +typedef size_t uintptr_t; + + +// misc constants + +#define PAGE_MASK (~0ul<<12) +#define PAGE_SIZE (-PAGE_MASK) + +#define O_RDONLY 0 + + +/************************************************************************* +// syscalls +**************************************************************************/ + +int close(int); +void exit(int) __attribute__((__noreturn__,__nothrow__)); +int mprotect(void *, size_t, int); +int open(char const *, unsigned, unsigned); +ssize_t pread(int, void *, size_t, unsigned); + + +/************************************************************************* +// UPX stuff +**************************************************************************/ + +#define UPX_MAGIC_LE32 0x21585055 // "UPX!" + + +#define nrv_byte unsigned char +typedef unsigned int nrv_uint; + + +#define CONST_CAST(type, var) \ + ((type) ((uintptr_t) (var))) + + +#if (ACC_CC_GNUC >= 0x030300) +# define __attribute_cdecl __attribute__((__cdecl__, __used__)) +#elif (ACC_CC_GNUC >= 0x020700) +# define __attribute_cdecl __attribute__((__cdecl__)) +#else +# define __attribute_cdecl +#endif + + +/* +vi:ts=4:et:nowrap +*/ + diff --git a/src/stub/src/include/linux.h b/src/stub/src/include/linux.h index af801610..68afefd0 100644 --- a/src/stub/src/include/linux.h +++ b/src/stub/src/include/linux.h @@ -1,4 +1,4 @@ -/* linux.hh -- common stuff the the Linux stub loaders +/* linux.h -- common stuff for the Linux stub loaders This file is part of the UPX executable compressor. @@ -224,7 +224,7 @@ type name(type1 arg1) \ } #define _syscall1nr(name,type1,arg1) \ -void __attribute__((__noreturn__)) name(type1 arg1) \ +void __attribute__((__noreturn__,__nothrow__)) name(type1 arg1) \ { \ if (Z1(__NR_##name)) { \ if (Z0(arg1)) { \ @@ -331,8 +331,8 @@ static inline _syscall1(int,close,int,fd) static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) static inline _syscall1nr(_exit,int,exitcode) static inline _syscall3(int,fcntl,int,fd,int,cmd,long,arg) -static inline _syscall2(int,ftruncate,int,fd,size_t,len) static inline _syscall0(pid_t,fork) +static inline _syscall2(int,ftruncate,int,fd,size_t,len) static inline _syscall0(pid_t,getpid) static inline _syscall2(int,gettimeofday,struct timeval *,tv,void *,tz) static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,whence) @@ -352,12 +352,13 @@ static inline _syscall1(int,unlink,const char *,file) void *brk(void *); int close(int); +void exit(int) __attribute__((__noreturn__,__nothrow__)); void *mmap(void *, size_t, int, int, int, off_t); int munmap(void *, size_t); int mprotect(void const *, size_t, int); int open(char const *, unsigned, unsigned); ssize_t read(int, void *, size_t); -void exit(int) __attribute__((noreturn)); +ssize_t write(int, void const *, size_t); #endif /*}*/ @@ -471,6 +472,7 @@ typedef struct #define AT_PHENT 4 #define AT_PHNUM 5 #define AT_PAGESZ 6 +#define AT_BASE 7 #define AT_ENTRY 9 #define ET_EXEC 2 @@ -494,12 +496,22 @@ typedef struct #define UPX_MAGIC_LE32 0x21585055 // "UPX!" +#if 1 // patch constants for our loader (le32 format) -#define UPX1 0x31585055 // "UPX1" +//#define UPX1 0x31585055 // "UPX1" #define UPX2 0x32585055 // "UPX2" #define UPX3 0x33585055 // "UPX4" #define UPX4 0x34585055 // "UPX4" -#define UPX5 0x35585055 // "UPX5" +//#define UPX5 0x35585055 // "UPX5" +#else +// transform into relocations when using ElfLinker +extern const unsigned UPX2; +extern const unsigned UPX3; +extern const unsigned UPX4; +#define UPX2 ((unsigned) (const void *) &UPX2) +#define UPX3 ((unsigned) (const void *) &UPX3) +#define UPX4 ((unsigned) (const void *) &UPX4) +#endif typedef int nrv_int; diff --git a/src/stub/src/powerpc-darwin.macho-main.c b/src/stub/src/powerpc-darwin.macho-main.c index 6f09a7af..433f3a11 100644 --- a/src/stub/src/powerpc-darwin.macho-main.c +++ b/src/stub/src/powerpc-darwin.macho-main.c @@ -27,28 +27,10 @@ John F. Reiser -*/ + */ -typedef long ssize_t; -typedef unsigned long size_t; -typedef size_t uintptr_t; -__extension__ typedef unsigned long long off_t; -typedef unsigned char nrv_byte; -typedef unsigned int nrv_uint; -#define UPX_MAGIC_LE32 0x21585055 // "UPX!" -#define PAGE_MASK (~0u<<12) -#define PAGE_SIZE -PAGE_MASK -#define O_RDONLY 0 - -int close(int); -void exit(int) __attribute__((__noreturn__)); -int mprotect(void *, size_t, int); -int open(char const *, unsigned, unsigned); -ssize_t pread(int, void *, size_t, unsigned); - -#define CONST_CAST(type, var) \ - ((type) ((uintptr_t) (var))) +#include "include/darwin.h" /************************************************************************* @@ -59,6 +41,7 @@ ssize_t pread(int, void *, size_t, unsigned); // it at an address different from it load address: there must be no // static data, and no string constants. + /************************************************************************* // "file" util **************************************************************************/ @@ -102,6 +85,7 @@ err_exit(int a) } #endif //} + /************************************************************************* // UPX & NRV stuff **************************************************************************/ diff --git a/src/stub/src/powerpc-linux.elf-main.c b/src/stub/src/powerpc-linux.elf-main.c index 6d18d292..44fe2801 100644 --- a/src/stub/src/powerpc-linux.elf-main.c +++ b/src/stub/src/powerpc-linux.elf-main.c @@ -32,6 +32,7 @@ #include "include/linux.h" + /************************************************************************* // configuration section **************************************************************************/ @@ -47,8 +48,6 @@ // "file" util **************************************************************************/ -extern void exit (int __status) __attribute__ ((__nothrow__)) __attribute__ ((__noreturn__)); - typedef struct { size_t size; // must be first to match size[0] uncompressed size char *buf;