husin alhaj ahmade husin alhaj ahmade - 1 year ago 112
Linux Question

How to modify EIP's tracee forked procee?

I'm working on a Linux application incorporating ptrace to observe another process which had been created by fork() system call.

Strictly speaking: I want to implement a fault injection into forked process (chile process or "tracee").

As you can see in the figure below:

enter image description here

enter image description here

the tracer gets the regs (struct_user_regs) structure from the tracee by using PTRACE_GETREGS request. after that, tracer modifies the EIP value of the tracee (when kernel switch into tracee, order execution will be violate so-called control flow error CFE). then PTRAC E_CONT request will send to tracee to continue its execution.

Unfortunately, after modifying the EPI's tracee, the tracee doesn't continue its execution due to (segmentation fault).
How I can give an another suitable vaule to the tracee EIP?

here is the code

#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <asm/ptrace-abi.h>

int main()


pid_t child;
int status;
int sum=0;
struct user_regs_struct regs;

child = fork();
if(child == 0) {

printf("hello world 1\n");
printf("hello world 2\n");
raise (SIGINT); // just to move control to the tracer
printf("hello world 3\n");
printf("hello world 4\n");
printf("hello world 5\n");

else {

ptrace(PTRACE_GETREGS, child,NULL, &regs);
printf("\n EIP @ 0x %#lx\n",regs.eip);
//get the tracee EIP
long int new_eip=ptrace(PTRACE_PEEKTEXT, child,regs.eip,NULL);
//chabge EIP and poke it again
new_eip += ???; // make change that let to jump to another tracee instruction address (say to print hello world 5)
ptrace(PTRACE_POKETEXT, child,regs.eip,new_eip);
ptrace(PTRACE_CONT, child, NULL, NULL);


return 0;

Any thoughts?
Thank you for all your assistance.

Answer Source

You're not modifying the EIP, you're adding something to the value of the instruction at EIP, and probably resulting in a bad address reference. To change EIP, use PTRACE_SETREGS

      ptrace(PTRACE_GETREGS, child,NULL, &regs);
      printf("\n EIP @  0x %#lx\n",regs.eip);
      regs.eip += ???;
      ptrace(PTRACE_SETREGS, child, NULL, &regs);
      ptrace(PTRACE_CONT, child, NULL, NULL);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download