📄 linux.h
字号:
/* linux.h -- common stuff for the Linux stub loaders This file is part of the UPX executable compressor. Copyright (C) 1996-2007 Markus Franz Xaver Johannes Oberhumer Copyright (C) 1996-2007 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 <mfx@users.sourceforge.net> <ml1050@users.sourceforge.net> */// 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)/*************************************************************************//**************************************************************************/// <stddef.h>typedef long ptrdiff_t;typedef long ssize_t;typedef unsigned long size_t;// <stdint.h>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;#elsetypedef long long int64_t;typedef unsigned long long uint64_t;#endiftypedef size_t uintptr_t;// <sys/types.h>typedef long off_t;//typedef int64_t off64_t;//typedef size_t caddr_t;typedef void* caddr_t;typedef unsigned pid_t;struct rusage;struct timex;struct timeval { unsigned tv_sec; unsigned tv_usec;};struct timespec { unsigned tv_sec; long tv_nsec;};// misc constants#if defined(__amd64__) || defined(__powerpc64__)#define PAGE_MASK (~0ul<<12) // discards the offset, keeps the page#define PAGE_SIZE ( 1ul<<12)#elif defined(__i386__) || defined(__powerpc__) || defined(__arm__)#define PAGE_MASK (~0ul<<12) // discards the offset, keeps the page#define PAGE_SIZE ( 1ul<<12)#elif defined(__mips__)#define PAGE_MASK (~0ul<<16) // discards the offset, keeps the page#define PAGE_SIZE ( 1ul<<16)#endif#define SEEK_SET 0#define SEEK_CUR 1#define O_RDONLY 00#define O_WRONLY 01#define O_RDWR 02#define O_CREAT 0100#define O_EXCL 0200#define R_OK 4#define W_OK 2#define X_OK 1#define F_OK 0#define F_GETFD 1#define F_SETFD 2#define FD_CLOEXEC 1// <errno.h>#define ENOENT 2#define EINTR 4// <sys/mman.h>#define PROT_READ 0x1#define PROT_WRITE 0x2#define PROT_EXEC 0x4#define PROT_NONE 0x0#define MAP_SHARED 0x01#define MAP_PRIVATE 0x02#define MAP_FIXED 0x10#define MAP_ANONYMOUS 0x20#define MAP_DENYWRITE 0x0800 /* ETXTBSY *//*************************************************************************// i386 syscalls//// Because of different <asm/unistd.h> versions and subtle bugs// in both gcc and egcs we define all syscalls manually.//// Also, errno conversion is not necessary in our case, and we// use optimized assembly statements to further decrease the size.**************************************************************************/#if defined(__i386__) /*{*/// <asm/unistd.h>#define __NR_exit 1#define __NR_fork 2#define __NR_read 3#define __NR_write 4#define __NR_open 5#define __NR_close 6#define __NR_waitpid 7#define __NR_link 9#define __NR_unlink 10#define __NR_execve 11#define __NR_lseek 19#define __NR_getpid 20#define __NR_access 33#define __NR_brk 45#define __NR_fcntl 55#define __NR_gettimeofday 78#define __NR_mmap 90#define __NR_munmap 91#define __NR_ftruncate 93#define __NR_adjtimex 124#define __NR_mprotect 125#define __NR_nanosleep 162#undef _syscall0#undef _syscall1#undef _syscall2#undef _syscall3#ifndef __NR__exit# define __NR__exit __NR_exit#endif#define Z0(x) (__builtin_constant_p(x) && (long)(x) == 0)#define Z1(x) (__builtin_constant_p(x) && (long)(x) >= -128 && (long)(x) <= 127)#define _syscall0(type,name) \type name(void) \{ \ long __res; \ if (Z1(__NR_##name)) { \ __asm__ __volatile__ ("push %[sysN]; popl %0; int $0x80" \ : "=a" (__res) \ : [sysN] "g" (__NR_##name)); \ } else { \ __asm__ __volatile__ ("int $0x80" \ : "=a" (__res) \ : [sysN] "a" (__NR_##name)); \ } \ return (type) __res; \}#define _syscall1(type,name,type1,arg1) \type name(type1 arg1) \{ \ long __res, junk; \ if (Z1(__NR_##name)) { \ if (Z0(arg1)) { \ __asm__ __volatile__ ("xorl %%ebx,%%ebx; push %[sysN]; popl %0; int $0x80" \ : "=a" (__res) \ : [sysN] "g" (__NR_##name) \ : "ebx"); \ } else if (Z1(arg1)) { \ __asm__ __volatile__ ("push %[a1]; popl %%ebx; push %[sysN]; popl %0; int $0x80" \ : "=a" (__res) \ : [sysN] "g" (__NR_##name), [a1] "g" ((long)(arg1)) \ : "ebx"); \ } else { \ __asm__ __volatile__ ("push %[sysN]; popl %0; int $0x80" \ : "=a" (__res), "=b" (junk) \ : [sysN] "g" (__NR_##name),"b" ((long)(arg1))); \ } \ } else { \ __asm__ __volatile__ ("int $0x80" \ : "=a" (__res), "=b" (junk) \ : "a" (__NR_##name),"b" ((long)(arg1))); \ } \ return (type) __res; \}#define _syscall1noreturn(name,type1,arg1) \void __attribute__((__noreturn__,__nothrow__)) name(type1 arg1) \{ \ if (Z1(__NR_##name)) { \ if (Z0(arg1)) { \ __asm__ __volatile__ ("xorl %%ebx,%%ebx; push %0; popl %%eax; int $0x80" \ : : "g" (__NR_##name) ); \ } else if (Z1(arg1)) { \ __asm__ __volatile__ ("push %[a1]; popl %%ebx; push %[sysN]; popl %%eax; int $0x80" \ : : [sysN] "g" (__NR_##name), [a1] "g" ((long)(arg1)) ); \ } else { \ __asm__ __volatile__ ("push %0; popl %%eax; int $0x80" \ : : "g" (__NR_##name),"b" ((long)(arg1))); \ } \ } else { \ __asm__ __volatile__ ("int $0x80" \ : : "a" (__NR_##name),"b" ((long)(arg1))); \ } \ for(;;) ; \}#define _syscall2(type,name,type1,arg1,type2,arg2) \type name(type1 arg1,type2 arg2) \{ \ long __res, junkb, junkc; \ if (Z1(__NR_##name)) { \ if (Z0(arg1) && Z0(arg2)) { \ __asm__ __volatile__ ("xorl %%ecx,%%ecx; xorl %%ebx,%%ebx; push %[sysN]; popl %0; int $0x80" \ : "=a" (__res) \ : [sysN] "g" (__NR_##name) \ : "ebx", "ecx"); \ } else if (Z0(arg1) && Z1(arg2)) { \ __asm__ __volatile__ ("push %[a2]; popl %%ecx; xorl %%ebx,%%ebx; push %[sysN]; popl %0; int $0x80" \ : "=a" (__res) \ : [sysN] "g" (__NR_##name), [a2] "g" ((long)(arg2)) \ : "ebx", "ecx"); \ } else if (Z1(arg1) && Z0(arg2)) { \ __asm__ __volatile__ ("xorl %%ecx,%%ecx; push %[a1]; popl %%ebx; push %[sysN]; popl %0; int $0x80" \ : "=a" (__res) \ : [sysN] "g" (__NR_##name), [a1] "g" ((long)(arg1)) \ : "ebx", "ecx"); \ } else if (Z1(arg1) && Z1(arg2)) { \ __asm__ __volatile__ ("push %[a2]; popl %%ecx; push %[a1]; popl %%ebx; push %[sysN]; popl %0; int $0x80" \ : "=a" (__res) \ : [sysN] "g" (__NR_##name), [a1] "g" ((long)(arg1)), [a2] "g" ((long)(arg2)) \ : "ebx", "ecx"); \ } else if (Z0(arg1)) { \ __asm__ __volatile__ ("xorl %%ebx,%%ebx; push %[sysN]; popl %0; int $0x80" \ : "=a" (__res), "=c" (junkc) \ : [sysN] "g" (__NR_##name),"c" ((long)(arg2)) \ : "ebx"); \ } else if (Z0(arg2)) { \ __asm__ __volatile__ ("push %[sysN]; popl %0; xorl %%ecx,%%ecx; int $0x80" \ : "=a" (__res), "=b" (junkb) \ : [sysN] "g" (__NR_##name),"b" ((long)(arg1)) \ : "ecx"); \ } else if (Z1(arg1)) { \ __asm__ __volatile__ ("push %[sysN]; popl %0; push %[a1]; popl %%ebx; int $0x80" \ : "=a" (__res), "=c" (junkc) \ : [sysN] "g" (__NR_##name), [a1] "g" ((long)(arg1)),"c" ((long)(arg2)) \ : "ebx"); \ } else if (Z1(arg2)) { \ __asm__ __volatile__ ("push %[sysN]; popl %0; push %[a2]; popl %%ecx; int $0x80" \ : "=a" (__res), "=b" (junkb) \ : [sysN] "g" (__NR_##name),"b" ((long)(arg1)), [a2] "g" ((long)(arg2)) \ : "ecx"); \ } else { \ __asm__ __volatile__ ("push %[sysN]; popl %0; int $0x80" \ : "=a" (__res), "=b" (junkb), "=c" (junkc) \ : [sysN] "g" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \ } \ } else { \ __asm__ __volatile__ ("int $0x80" \ : "=a" (__res), "=b" (junkb), "=c" (junkc) \ : [sysN] "a" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \ } \ return (type) __res; \}#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \type name(type1 arg1,type2 arg2,type3 arg3) \{ \ long __res, junkb, junkc, junkd; \ if (Z1(__NR_##name)) { \ __asm__ __volatile__ ("push %[sysN]; popl %0; int $0x80" \ : "=a" (__res), "=b" (junkb), "=c" (junkc), "=d" (junkd) \ : [sysN] "g" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ "d" ((long)(arg3))); \ } else { \ __asm__ __volatile__ ("int $0x80" \ : "=a" (__res), "=b" (junkb), "=c" (junkc), "=d" (junkd) \ : [sysN] "a" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \ "d" ((long)(arg3))); \ } \ return (type) __res; \}#define _exit syscall_exit#define exit syscall_exitstatic inline _syscall2(int,access,const char *,file,int,mode)static inline _syscall1(int,adjtimex,struct timex *,ntx)static inline _syscall1(void *,brk,void *,high)static inline _syscall1(int,close,int,fd)static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)static inline _syscall1noreturn(_exit,int,exitcode)static inline _syscall3(int,fcntl,int,fd,int,cmd,long,arg)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)static inline _syscall3(int,mprotect,void *,addr,size_t,len,int,prot)static inline _syscall2(int,munmap,void *,start,size_t,length)static inline _syscall2(int,nanosleep,const struct timespec *,rqtp,struct timespec *,rmtp)static inline _syscall3(int,open,const char *,file,int,flag,int,mode)static inline _syscall3(ssize_t,read,int,fd,void *,buf,size_t,count)static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)static inline _syscall3(ssize_t,write,int,fd,const void *,buf,size_t,count)static inline _syscall1(int,unlink,const char *,file)static inline _syscall2(int,link,const char *,src, const char *,dst)#undef Z0#undef Z1#elif defined(__mips__) /*}{*/#undef MAP_ANONYMOUS#define MAP_ANONYMOUS 0x800/* Cannot write an inline assembler constraint for a specific register. http://gcc.gnu.org/ml/gcc-help/2007-02/msg00068.html Workaround: const register int num asm("v0") = 4; const register char *const str asm("a0") = string; asm volatile("syscall" : : "r"(num), "r"(str));*/static void *mmap( void *addr, size_t len, int prot, int flags, int fd, off_t offset){#define __NR_mmap (90+ 4000) register void * const a0 asm("a0") = addr; register size_t const a1 asm("a1") = len; register int const a2 asm("a2") = prot; register int a3 asm("a3") = flags;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -