0

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, &regs);
                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 :/)

SamuelRousseaux
  • 107
  • 1
  • 1
  • 8
  • [x86's `ret`](http://felixcloutier.com/x86/RET.html) is basically `pop rip`: the return address is in memory on the stack, *pointed to* by RSP. The address will be the address right after the `call`, not the start of the calling function. – Peter Cordes May 11 '18 at 16:26
  • isn't it the address to the instruction after "call my_function" ? – SamuelRousseaux May 11 '18 at 16:29
  • Yes, that's what I said. The first byte after the end of the `call` instruction. – Peter Cordes May 11 '18 at 16:32
  • That's the problem, I'm looking for a way to find the previous address with ptrace, so I can tell that it is a ret from "my_function" for example :/ (EDIT: I can provide a screenshot if it can be clearer) – SamuelRousseaux May 11 '18 at 16:33
  • if you can detect that `ret` is going to be executed, can you catch the same way the `call` instructions? Then you can pair them. This is not perfect, as some type of code may get this construct out of sync (retpolines, exploits getting self-address, etc..), or under extra resource strain (recursive calls), but for simple machine code it may be enough. There's of course no generic bullet proof solution, as that is basically identical task to the [Halting problem](https://en.wikipedia.org/wiki/Halting_problem). – Ped7g May 11 '18 at 18:25
  • 1
    The main obstacle to pairing call/ret is tail-calls (`return foo();` compiles to `jmp foo` instead of `call foo` / `ret`). But when you do have a `ret`, then you know RIP at the location of the `ret`. That will be inside the function that's returning, if you have a symbol table that has sizes for each function. (gcc typically emits that.) – Peter Cordes May 11 '18 at 18:43
  • I'll be looking for that, thanks :) – SamuelRousseaux May 11 '18 at 18:47
  • It worked doing this way @Ped7g, thanks a lot ! – SamuelRousseaux May 11 '18 at 20:15

0 Answers0