husin alhaj ahmade husin alhaj ahmade - 3 months ago 20
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<sys/user.h>
#include<sys/reg.h>
#include<stdlib.h>
#include<stdio.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) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);

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");

exit(EXIT_SUCCESS);
}
else {

wait(NULL);
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

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

      wait(NULL);
      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);
Comments