First of all, sorry for the title which can't be less explicit, I just didn't knew how to write, so I'm gonna explain it here.
Currently, I'm writing a small debugging tool in C using ptrace(). Right now, the program detects all of the function called by the tracee process, and prints its name and address on the output.
For example: "Entering function my_function at 0xADDR"
Now, I need to find a way to detect and print when the tracee leaves the function. I successfully detect the opcode RET, but I can't find how to "link" it to a function.
I've tried, when RET is detected, reading all of the registers with hope to find the addr of the function which was called by CALL.
I don't know if it's explicit enough, so here's a small example:
main:
call my_function
// rest of the program
my_function:
//do things
ret
Given the fact that I know my_function address, is there a way, when stepping on a RET, to find the address of my_function?
Here's a bit of code, in the tracing loop:
struct user_regs_struct regs;
unsigned ins;
unsigned char prim;
int status;
printf("Entering function main at %#lx\n", get_func_addr(lsm, "main"));
while (1) {
ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
wait(&status);
if (WIFEXITED(status))
break;
ptrace(PTRACE_GETREGS, child, NULL, ®s);
ins = ptrace(PTRACE_PEEKTEXT, child, regs.rip, NULL);
prim = (unsigned)0xFF & ins;
if (prim == 0xE8) // call found, find_relative_call will check the address called an\
d retreive the name of the function called
find_relative_call(child, lsm);
else if (prim == 0xC3) { // ret found, stuck here
long f_rip = ptrace(PTRACE_PEEKTEXT, child, regs.rsp, 0);
printf("ret %#lx\n", f_rip);
/* printf("rip %#llx\n", regs.rip); */
/* find_relative_ret(child, lsm); */
}
}
Thanks ! (I hope it was clear enough, not my native language :/)