rendered paste bodydiff -r 26423726a075 -r 083a0b9b734c src/arch-i386/Makefile--- a/src/arch-i386/Makefile Wed Jun 24 16:23:46 2009 +0200+++ b/src/arch-i386/Makefile Sat Jul 25 20:01:35 2009 +0200@@ -1,6 +1,6 @@ COMMON_OBJS = -R_CHUNK_OBJS = cp_r_regs.o cp_r_tls.o cp_r_i387.o start.o plt-resolve.o-W_CHUNK_OBJS = cp_w_regs.o cp_w_tls.o cp_w_i387.o+R_CHUNK_OBJS = cp_r_regs.o cp_r_tls.o cp_r_i387.o start.o plt-resolve.o getpid_hack_r.o+W_CHUNK_OBJS = cp_w_regs.o cp_w_tls.o cp_w_i387.o getpid_hack_w.o KERN=$(shell uname -r) diff -r 26423726a075 -r 083a0b9b734c src/arch-i386/cp_r_regs.c--- a/src/arch-i386/cp_r_regs.c Wed Jun 24 16:23:46 2009 +0200+++ b/src/arch-i386/cp_r_regs.c Sat Jul 25 20:01:35 2009 +0200@@ -12,6 +12,11 @@ extern int need_gtk; #endif +static struct user user;++struct user_regs_struct* regs(void) {+ return &user.regs;+} static void load_chunk_regs(struct user *user, int stopped) {@@ -94,6 +99,8 @@ *(unsigned long*)(cp) = r->eip; cp+= 4; asm("mov %%cs,%w0": "=q"(r->xcs)); /* ensure we use the right CS for the current kernel */ *(unsigned short*)(cp) = r->xcs; cp+= 2; /* jmp cs:foo */++ /* restoring VMA previous settings */ syscall_check( (int)mprotect((void*)TRAMPOLINE_ADDR, _getpagesize, PROT_READ|PROT_EXEC), 0, "mmap");@@ -101,7 +108,6 @@ void read_chunk_regs(void *fptr, int action) {- struct user user; int stopped; read_bit(fptr, &user, sizeof(struct user)); read_bit(fptr, &stopped, sizeof(int));@@ -112,7 +118,7 @@ user.regs.eax, user.regs.ebx, user.regs.ecx, user.regs.edx); fprintf(stderr, "\tesi: 0x%08lx edi: 0x%08lx ebp: 0x%08lx esp: 0x%08lx\n", user.regs.esi, user.regs.edi, user.regs.ebp, user.regs.esp);- fprintf(stderr, "\t ds: 0x%08x es: 0x%08x fs: 0x%08x gs: 0x%08x\n",+ fprintf(stderr, "\t ds: 0x%08lx es: 0x%08lx fs: 0x%08lx gs: 0x%08lx\n", user.regs.xds, user.regs.xes, user.regs.xfs, user.regs.xgs); fprintf(stderr, "\teip: 0x%08lx eflags: 0x%08lx", user.regs.eip, user.regs.eflags);diff -r 26423726a075 -r 083a0b9b734c src/arch-i386/cp_r_tls.c--- a/src/arch-i386/cp_r_tls.c Wed Jun 24 16:23:46 2009 +0200+++ b/src/arch-i386/cp_r_tls.c Sat Jul 25 20:01:35 2009 +0200@@ -33,7 +33,7 @@ return; if (action & ACTION_PRINT)- fprintf(stderr, "TLS entry (%d): base_addr = 0x%lx", + fprintf(stderr, "TLS entry (%d): base_addr = 0x%x", u.entry_number, u.base_addr); if (!(action & ACTION_LOAD))diff -r 26423726a075 -r 083a0b9b734c src/arch-i386/cp_w_tls.c--- a/src/arch-i386/cp_w_tls.c Wed Jun 24 16:23:46 2009 +0200+++ b/src/arch-i386/cp_w_tls.c Sat Jul 25 20:01:35 2009 +0200@@ -31,9 +30,10 @@ } u->entry_number = i; if (ptrace(PTRACE_GET_THREAD_AREA, pid, i, u) == -1) {+ debug("TLS segment #%d unfetchable", i); continue; }-+ printf("[+] TLS segment #%d fetched: base address at 0x%x\n", i, u->base_addr); chunk = xmalloc(sizeof(struct cp_chunk)); chunk->type = CP_CHUNK_TLS; chunk->tls.u = u;diff -r 26423726a075 -r 083a0b9b734c src/arch-i386/cplayout.h--- a/src/arch-i386/cplayout.h Wed Jun 24 16:23:46 2009 +0200+++ b/src/arch-i386/cplayout.h Sat Jul 25 20:01:35 2009 +0200@@ -1,7 +1,9 @@ #ifndef _CPLAYOUT_H_ #define _CPLAYOUT_H_ -#define TRAMPOLINE_ADDR 0x00800000 /* 8MB mark */+#define SIGNATURE_LENGTH 32 /* # of bytes of __getpid signature to extract */+#define TRAMPOLINE_ADDR 0x00800000 /* 8MB mark */+#define GETPID_HACK_ADDR 0x00801000 /* address for _getpid code */ #define RESUMER_START 0x00000000 /* Lowest location resumer will be at */ #define RESUMER_END 0x00800000 /* Highest location resumer will be at */diff -r 26423726a075 -r 083a0b9b734c src/arch-i386/elfwriter.c--- a/src/arch-i386/elfwriter.c Wed Jun 24 16:23:46 2009 +0200+++ b/src/arch-i386/elfwriter.c Sat Jul 25 20:01:35 2009 +0200@@ -60,14 +60,14 @@ * ie, offset = offset - round_to_page(code_len) - round_to_page(data_len) */ - e = (Elf32_Ehdr*)stub_start;+ e = (Elf32_Ehdr*)stub_start; /* pointer to our ELF header */ - assert(e->e_shoff != 0);- assert(e->e_shentsize == sizeof(Elf32_Shdr));- assert(e->e_shstrndx != SHN_UNDEF);+ assert(e->e_shoff != 0); /* check section header tables file offset */+ assert(e->e_shentsize == sizeof(Elf32_Shdr)); /* check section header entry size */+ assert(e->e_shstrndx != SHN_UNDEF); /* must exist a section name string table */ - s = (Elf32_Shdr*)(stub_start+(e->e_shoff+(e->e_shstrndx*e->e_shentsize)));- strtab = stub_start+s->sh_offset; /* string table start */+ s = (Elf32_Shdr*)(stub_start+(e->e_shoff+(e->e_shstrndx*e->e_shentsize))); /* Elf32_Shdr start for name string table */+ strtab = stub_start+s->sh_offset; /* string table start, from the beginning of the ELF */ /* Locate where this binary's brk would start */ for (i = 0; i < e->e_phnum; i++) {@@ -88,7 +88,7 @@ got_it = 0; for (i = 0; i < e->e_shnum; i++) { s = (Elf32_Shdr*)(stub_start+e->e_shoff+(i*e->e_shentsize));- /* sh_addr: this member gives the address at which the sections first byte should reside in the process image */+ /* sh_addr: address at which the sections first byte should reside in the process image */ s->sh_addr += offset; if (s->sh_type != SHT_PROGBITS || s->sh_name == 0)@@ -110,6 +110,10 @@ mmap_prot = PROT_READ | PROT_WRITE; if (p->p_flags & PF_X) mmap_prot |= PROT_EXEC; + /* + p_vaddr: virtual address at which the first byte of the segment resides in memory+ p_memsz: number of bytes in the memory image of the segment; it may be zero+ */ mmap_addr = p->p_vaddr & ~(_getpagesize - 1); mmap_len = p->p_memsz + (p->p_vaddr - mmap_addr); mmap_len = (mmap_len + (_getpagesize - 1)) & ~(_getpagesize - 1);diff -r 26423726a075 -r 083a0b9b734c src/arch-i386/getpid_hack_r.c--- /dev/null Thu Jan 01 00:00:00 1970 +0000+++ b/src/arch-i386/getpid_hack_r.c Sat Jul 25 20:01:35 2009 +0200@@ -0,0 +1,60 @@+/* module to manage host libc __getpid stored in the image (ELF) file */+#include <sys/types.h>+#include <sys/stat.h>+#include <sys/mman.h>+#include <sys/user.h>+#include <linux/unistd.h>+#include <asm/ldt.h>+#include <elf.h>+#include <unistd.h>+#include <fcntl.h>++#include "cpimage.h"+#include "cryopid.h"++extern struct user_regs_struct* regs(void);++static void libc_hack_load(char* data)+{+ char *dest = (char*)GETPID_HACK_ADDR;+ struct user_regs_struct *r = regs();++ /* Create region for __getpid refresh hack */+ syscall_check(+ (int)mmap((void*)GETPID_HACK_ADDR, _getpagesize, PROT_READ|PROT_WRITE|PROT_EXEC,+ MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0), 0, "mmap");++ /* set up gs */+ if (!emulate_tls && r->xgs != 0) {+ *dest++=0x66;*dest++=0xb8; *(short*)(dest) = r->xgs; dest+=2; /* mov foo, %eax */+ *dest++=0x8e;*dest++=0xe8; /* mov %eax, %gs */+ *dest++=0xba;*dest++=0x00;*dest++=0x00;*dest++=0x00;*dest++=0x00; /* mov $0x00, %edx */+ *dest++=0xb9;*dest++=0x00;*dest++=0x00;*dest++=0x00;*dest++=0x00; /* mov $0x00, %ecx */++ /* insert the assembly code of __getpid */+ memcpy(dest, data, SIGNATURE_LENGTH);+ }++ /* restoring VMA previous settings */+ syscall_check(+ (int)mprotect((void*)GETPID_HACK_ADDR, _getpagesize, PROT_READ|PROT_EXEC),+ 0, "mmap");+}++void read_chunk_getpid(void *fptr, int action)+{+ char* signature = (char*) xmalloc(SIGNATURE_LENGTH);+ read_bit(fptr, signature, SIGNATURE_LENGTH);+ if (action & ACTION_PRINT) {+ int i;+ /* printf out signature's bytes */+ info("__getpid hack signature:\n");+ for (i = 0; i < SIGNATURE_LENGTH; i++) {+ info("[%d] byte value: 0x%02x\t", i, (unsigned char) *(signature + i));+ if ((!(i % 4) && (i != 0)) || (i == (SIGNATURE_LENGTH-1)))+ info("\n");+ }+ }+ if (action & ACTION_LOAD)+ libc_hack_load(signature);+}diff -r 26423726a075 -r 083a0b9b734c src/arch-i386/getpid_hack_w.c--- /dev/null Thu Jan 01 00:00:00 1970 +0000+++ b/src/arch-i386/getpid_hack_w.c Sat Jul 25 20:01:35 2009 +0200@@ -0,0 +1,122 @@+/* module to manage host libc __getpid: locate, fetch and store */+#include <sys/types.h>+#include <sys/stat.h>+#include <elf.h>+#include <unistd.h>+#include <fcntl.h>++#include "cpimage.h"+#include "cryopid.h"++int libc_hack_fetch(const char* name, char** signature)+{+ Elf32_Ehdr libc_ehdr;+ Elf32_Shdr libc_shdr, libc_st;+ Elf32_Off libc_stoff, dynsym_off, dynstr_off;+ Elf32_Word dynsym_size, dynstr_size;+ Elf32_Sym libc_sym;+ int libc_fd, i;+ char *strtab = NULL, + *dynsym = NULL, + *dynstr = NULL;+ unsigned char asmbyte;++ libc_fd = open(name, O_RDONLY);+ if (libc_fd == -1)+ bail("[E] failed to open %s\n", name);+ + read(libc_fd, &libc_ehdr, sizeof(Elf32_Ehdr));++ assert(libc_ehdr.e_shoff != 0); /* check section header tables file offset */+ assert(libc_ehdr.e_shentsize == sizeof(Elf32_Shdr)); /* check section header entry size */+ assert(libc_ehdr.e_shstrndx != SHN_UNDEF); /* must exist a section name string table */++ //info("[i] section header table's offeset is: %d\n", libc_ehdr.e_shoff);+ libc_stoff = libc_ehdr.e_shoff + (libc_ehdr.e_shstrndx * libc_ehdr.e_shentsize);+ if (lseek(libc_fd, libc_stoff, SEEK_SET) == -1) /* seek to section name string table header */+ bail("[E] failed to seek to section name string table header");+ read(libc_fd, &libc_st, sizeof(Elf32_Shdr));+ assert(libc_st.sh_type == SHT_STRTAB);+ //info("[i] string table offset from file start is: %u\n", libc_st.sh_offset);++ /* fetch string table */+ strtab = (char*) xmalloc(libc_st.sh_size);+ if (lseek(libc_fd, libc_st.sh_offset, SEEK_SET) == -1) /* seek to section name string table */+ bail("[E] failed to seek to section name string table"); + if (read(libc_fd, strtab, libc_st.sh_size) != libc_st.sh_size)+ info("[W] failed to read the %u bytes of string table\n", libc_st.sh_size);++ /* search .dynsym and .dynstr sections + 1- it holds the dynamic linking symbol table+ 2- it holds strings needed for dynamic linking + */+ if (lseek(libc_fd, libc_ehdr.e_shoff, SEEK_SET) == -1) /* seek to section header table */+ bail("[E] failed to seek at %d bytes to section header table", libc_ehdr.e_shoff);+ for (i = 0; i < libc_ehdr.e_shnum; i++) {+ read(libc_fd, &libc_shdr, sizeof(Elf32_Shdr));+ if (libc_shdr.sh_type == SHT_DYNSYM) { /* libc .dynsym section */+ //info("[i] .dynsym checked as #%d section\n", i);+ dynsym_off = libc_shdr.sh_offset;+ dynsym_size = libc_shdr.sh_size;+ dynsym = (char*) xmalloc(dynsym_size);+ }+ /* libc .dynstr section */+ if ((libc_shdr.sh_type == SHT_STRTAB) && !strcmp(strtab + libc_shdr.sh_name, ".dynstr")) {+ //info("[i] .dynstr checked as #%d section\n", i);+ dynstr_off = libc_shdr.sh_offset;+ dynstr_size = libc_shdr.sh_size;+ dynstr = (char*) xmalloc(dynstr_size);+ }+ }++ /* fetch .dynsym and .dynstr sections */+ if (lseek(libc_fd, dynsym_off, SEEK_SET) == -1) /* seek to .dynsym section */+ bail("[E] failed to seek to .dynsym section"); + if (read(libc_fd, dynsym, dynsym_size) != dynsym_size)+ info("[W] failed to read the %u bytes of .dynsym section\n", dynsym_size);+ if (lseek(libc_fd, dynstr_off, SEEK_SET) == -1) /* seek to .dynstr section */+ bail("[E] failed to seek to .dynstr section"); + if (read(libc_fd, dynstr, dynstr_size) != dynstr_size)+ info("[W] failed to read the %u bytes of .dynstr section\n", dynstr_size);+ + //info("[i] dynamic symbol elements are: %d\n", dynsym_size / sizeof(Elf32_Sym));+ /* looking for __getpid symbol */+ for (i = 0; i < (dynsym_size / sizeof(Elf32_Sym)); i++) {+ memcpy(&libc_sym, dynsym + (i * sizeof(Elf32_Sym)), sizeof(Elf32_Sym));+ if ((ELF32_ST_TYPE(libc_sym.st_info) == STT_FUNC)+ && strstr(dynstr + libc_sym.st_name, "__getpid")) {+ info("[+] __getpid symbol found as #%d element at address 0x%x\n", i, libc_sym.st_value);+ break;+ }+ }+ /* now libc_sym keeps all __getpid symbol information */+ if (lseek(libc_fd, libc_sym.st_value, SEEK_SET) == -1) /* seek to .dynsym section */+ bail("[E] failed to seek to __getpid location at 0x%x", libc_sym.st_value); + while (1) {+ if (read(libc_fd, &asmbyte, 1) == -1)+ bail("[E] failde to read from __getpid");+ //info("[asmbyte] asm byte: 0x%02x\n", (unsigned char) asmbyte);+ if (asmbyte == 0xb8)+ break;+ }+ if (lseek(libc_fd, -1, SEEK_CUR) == -1) /* seek to 0xb8 */+ bail("[E] failed to seek backward to 0xb8"); + *signature = (char*) xmalloc(SIGNATURE_LENGTH);+ /* fetch the signature from libc */+ memset(*signature, 0, SIGNATURE_LENGTH);+ if (read(libc_fd, *signature, SIGNATURE_LENGTH) == -1)+ bail("[E] unable to fetch the signature");+ info("[+] __getpid signature fetched\n");+ /* free all the memory space allacated */+ free(dynsym);+ free(dynstr);+ /* close libc file */+ close(libc_fd);++ return EXIT_SUCCESS;+}++void write_chunk_getpid(void* fptr, struct cp_getpid* data)+{+ write_bit(fptr, data->asmcode, SIGNATURE_LENGTH);+}diff -r 26423726a075 -r 083a0b9b734c src/arch-i386/process.c--- a/src/arch-i386/process.c Wed Jun 24 16:23:46 2009 +0200+++ b/src/arch-i386/process.c Sat Jul 25 20:01:35 2009 +0200@@ -230,6 +230,7 @@ int success = 0; char* pagebackup; struct user_regs_struct r;+ struct cp_chunk *libcgp; start_ptrace(pid); @@ -258,6 +259,10 @@ fetch_chunks_i387_data(pid, flags, process_image); fetch_chunks_regs(pid, flags, process_image, process_was_stopped); + /* add __getpid chunk to the image list */+ fetch_chunk_libcgp(&libcgp);+ list_append(process_image, libcgp);+ success = 1; restore_page(pid, (void*)scribble_zone, pagebackup);diff -r 26423726a075 -r 083a0b9b734c src/arch-i386/stub.h--- a/src/arch-i386/stub.h Wed Jun 24 16:23:46 2009 +0200+++ b/src/arch-i386/stub.h Sat Jul 25 20:01:35 2009 +0200@@ -4,6 +4,11 @@ #include <sys/mman.h> #include "cryopid.h" +static inline void jump_to_getpid_hack()+{+ asm("call *%%eax\n" : : "a"(GETPID_HACK_ADDR));+}+ static inline void jump_to_trampoline() { asm("jmp *%%eax\n" : : "a"(TRAMPOLINE_ADDR));@@ -38,8 +43,9 @@ 0, "mmap(newstack)"); memset(top_of_new_stack - size_of_new_stack, 0, size_of_new_stack); memcpy(top_of_new_stack - size_of_new_stack,- top_of_old_stack - size_of_new_stack, /* FIX ME */+ top_of_old_stack - size_of_new_stack, /* FIXME */ size_of_new_stack);+ /* relocate %esp and %ebp value in confirmation of the new stack */ __asm__ ("addl %0, %%esp" : : "a"(top_of_new_stack - top_of_old_stack)); __asm__ ("addl %0, %%ebp" : : "a"(top_of_new_stack - top_of_old_stack)); diff -r 26423726a075 -r 083a0b9b734c src/cp_w_vma.c--- a/src/cp_w_vma.c Wed Jun 24 16:23:46 2009 +0200+++ b/src/cp_w_vma.c Sat Jul 25 20:01:35 2009 +0200@@ -9,6 +9,10 @@ #include "cpimage.h" #include "process.h" #include "cryopid.h"+#ifdef __i386__+#include "getpid_hack.h"+static struct cp_chunk *gp_chunk = NULL;+#endif unsigned long scribble_zone = 0; /* somewhere to scribble on in child */ unsigned long syscall_loc = 0; /* address of a syscall instruction */@@ -32,6 +36,13 @@ write_bit(fptr, data->data, data->length); } +#ifdef __i386__+void fetch_chunk_libcgp(struct cp_chunk** ptr)+{+ *ptr = gp_chunk;+}+#endif+ static int get_one_vma(pid_t pid, char* line, struct cp_vma *vma, int get_library_data, int vma_no, long *bin_offset) {@@ -256,7 +267,7 @@ unsigned int c; static char buf[4096]; - keep_vma_data = 1; /* Assume guiltly until proven innocent */+ keep_vma_data = 1; /* Assume guilty until proven innocent */ if ((lfd = open(vma->filename, O_RDONLY)) == -1) goto out;@@ -357,6 +368,15 @@ i = work_list.head; continue; }+ #ifdef __i386__+ if (chunk->vma.filename != NULL)+ if ((strstr(chunk->vma.filename, "libc") != NULL) && !gp_chunk) {+ info("[+] libc mapping found: %s\n", chunk->vma.filename);+ gp_chunk = xmalloc(sizeof(struct cp_chunk));+ gp_chunk->type = CP_CHUNK_GETPID;+ libc_hack_fetch(chunk->vma.filename, &gp_chunk->signature.asmcode);+ }+ #endif vma_no++; list_append(l, chunk); chunk = NULL;diff -r 26423726a075 -r 083a0b9b734c src/cpimage.h--- a/src/cpimage.h Wed Jun 24 16:23:46 2009 +0200+++ b/src/cpimage.h Sat Jul 25 20:01:35 2009 +0200@@ -30,7 +30,8 @@ #define CP_CHUNK_FD 0x06 #define CP_CHUNK_VMA 0x07 #define CP_CHUNK_SIGHAND 0x08-#define CP_CHUNK_FINAL 0x09+#define CP_CHUNK_FINAL 0x0a+#define CP_CHUNK_GETPID 0x09 #define CP_CHUNK_MAGIC 0xC0DE @@ -58,14 +59,18 @@ }; struct cp_regs {- struct user32 *user_data;+ struct user *user_data; void *opaque; /* For arch-specific data */ int stopped; }; #ifdef __i386__+struct cp_getpid {+ char* asmcode;+};+ struct cp_i387_data {- struct user_i387_ia32_struct* i387_data;+ struct user_fpregs_struct* i387_data; }; struct cp_tls {@@ -158,6 +163,7 @@ #ifdef __i386__ struct cp_i387_data i387_data; struct cp_tls tls;+ struct cp_getpid signature; #endif }; };@@ -245,6 +251,9 @@ void write_chunk_fd_socket(void *fptr, struct cp_socket *socket); /* cp_vma.c */+#ifdef __i386__+void fetch_chunk_libcgp(struct cp_chunk** ptr);+#endif void fetch_chunks_vma(pid_t pid, int flags, struct list *l, long *bin_offset); void read_chunk_vma(void *fptr, int action); void write_chunk_vma(void *fptr, struct cp_vma *data);diff -r 26423726a075 -r 083a0b9b734c src/cpimage_r.c--- a/src/cpimage_r.c Wed Jun 24 16:23:46 2009 +0200+++ b/src/cpimage_r.c Sat Jul 25 20:01:35 2009 +0200@@ -5,6 +5,9 @@ #include "cpimage.h" #include "cryopid.h" #include "list.h"+#ifdef __i386__+#include "getpid_hack.h"+#endif void read_bit(void *fptr, void *buf, int len)@@ -101,6 +104,9 @@ case CP_CHUNK_TLS: read_chunk_tls(fptr, action); break;+ case CP_CHUNK_GETPID:+ read_chunk_getpid(fptr, action);+ break; #endif case CP_CHUNK_FINAL: if (action & ACTION_PRINT)diff -r 26423726a075 -r 083a0b9b734c src/cpimage_w.c--- a/src/cpimage_w.c Wed Jun 24 16:23:46 2009 +0200+++ b/src/cpimage_w.c Sat Jul 25 20:01:35 2009 +0200@@ -5,6 +5,9 @@ #include "cpimage.h" #include "cryopid.h" #include "list.h"+#ifdef __i386__+#include "getpid_hack.h"+#endif void write_bit(void *fptr, void *buf, int len)@@ -69,6 +72,9 @@ case CP_CHUNK_TLS: write_chunk_tls(fptr, &chunk->tls); break;+ case CP_CHUNK_GETPID:+ write_chunk_getpid(fptr, &chunk->signature);+ break; #endif default: bail("Unknown chunk type to write (0x%x)", chunk->type)diff -r 26423726a075 -r 083a0b9b734c src/getpid_hack.h--- /dev/null Thu Jan 01 00:00:00 1970 +0000+++ b/src/getpid_hack.h Sat Jul 25 20:01:35 2009 +0200@@ -0,0 +1,11 @@+#ifndef _GETPID_HACK_+#define _GETPID_HACK_++/* getpid_hack_w */+extern int libc_hack_fetch(const char* name, char** signature);+extern void write_chunk_getpid(void* fptr, struct cp_getpid* data);++/* getpid_hack_r */+extern void read_chunk_getpid(void *fptr, int action);++#endif /* _GETPID_HACK_ */diff -r 26423726a075 -r 083a0b9b734c src/stub_common.c--- a/src/stub_common.c Wed Jun 24 16:23:46 2009 +0200+++ b/src/stub_common.c Sat Jul 25 20:01:35 2009 +0200@@ -57,6 +57,9 @@ if (do_pause) sleep(2); + #ifdef __i386__+ jump_to_getpid_hack();+ #endif jump_to_trampoline(); } @@ -137,7 +140,7 @@ long_options, &option_index); if (c == -1) break;- switch(c) {+ switch (c) { case 'd': action &= ~ACTION_LOAD; action |= ACTION_PRINT;