All pastes #1510801 Raw Edit

cryopid 25 JUL 2009

public diff v1 · immutable
#1510801 ·published 2009-07-29 06:44 UTC
rendered paste body
diff -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;