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:
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, ®s);
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.
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, ®s);
printf("\n EIP @ 0x %#lx\n",regs.eip);
regs.eip += ???;
ptrace(PTRACE_SETREGS, child, NULL, ®s);
ptrace(PTRACE_CONT, child, NULL, NULL);
Yes, it is completely platform-specific. I read a lot of materials which described ptrace syscall and how we can use it to capture the EIP of the next instruction that is going to execute after the ptrace send some request (like PTRACE_CONT) to the suspended tracee. I always see that the EIP value is something like this :
80484a6:
80484a7:
80484ac:
80484b2:
80484b4:
80484b6:
80484b8:
I test a simple code (just print the value of EIP and the corresponding executed instruction). but the result was as you shown below:
EIP: b773cbe0 Instruction executed: c3595a5d
EIP: b773cbe1 Instruction executed: ccc3595a
EIP: b773cbe0 Instruction executed: c3595a5d
hello world 5
EIP: b773cbe0 Instruction executed: c3595a5d
EIP: b773cbe1 Instruction executed: ccc3595a
EIP: b773cbe0 Instruction executed: c3595a5d
hello world 6
EIP: b773cbe0 Instruction executed: c3595a5d
EIP: b773cbe1 Instruction executed: ccc3595a
EIP: b773cbe0 Instruction executed: c3595a5d
what is this (b773cbe0) ??!!! I moved to gdb and viewed the dump file using this command line (objdump -d a.out) the result is something different with previous results
8048864: 8b 6c 24 20 mov 0x20(%esp),%ebp
8048868: 8d b3 0c ff ff ff lea -0xf4(%ebx),%esi
804886e: e8 41 fb ff ff call 80483b4 <_init>
8048873: 8d 83 08 ff ff ff lea -0xf8(%ebx),%eax
8048879: 29 c6 sub %eax,%esi
804887b: c1 fe 02 sar $0x2,%esi
804887e: 85 f6 test %esi,%esi
8048880: 74 23 je 80488a5 <__libc_csu_init+0x55>
8048882: 8d b6 00 00 00 00 lea 0x0(%esi),%esi
8048888: 83 ec 04 sub $0x4,%esp
804888b: ff 74 24 2c pushl 0x2c(%esp)
804888f: ff 74 24 2c pushl 0x2c(%esp)
8048893: 55 push %ebp
8048894: ff 94 bb 08 ff ff ff call *-0xf8(%ebx,%edi,4)
804889b: 83 c7 01 add $0x1,%edi
804889e: 83 c4 10 add $0x10,%esp
80488a1: 39 f7 cmp %esi,%edi
80488a3: 75 e3 jne 8048888 <__libc_csu_init+0x38>
80488a5: 83 c4 0c add $0xc,%esp
80488a8: 5b pop %ebx
80488a9: 5e pop %esi
80488aa: 5f pop %edi
80488ab: 5d pop %ebp
80488ac: c3 ret
80488ad: 8d 76 00 lea 0x0(%esi),%esi
I'm really confused about this.
来源:https://stackoverflow.com/questions/38796282/how-to-modify-eips-tracee-forked-procee