首页 > 解决方案 > 有没有办法用 ptrace 找到在 RET 指令时调用的地址

问题描述

首先,对不起,标题不能不那么明确,我只是不知道怎么写,所以我在这里解释一下。

目前,我正在使用 ptrace() 用 C 语言编写一个小型调试工具。现在,程序检测到所有被跟踪进程调用的函数,并在输出中打印出它的名称和地址。

例如:“在 0xADDR 处输入函数 my_function”

现在,我需要找到一种方法来检测和打印被跟踪者何时离开函数。我成功检测到操作码 RET,但我找不到如何将其“链接”到函数。

我尝试过,当检测到 RET 时,读取所有寄存器,希望找到 CALL 调用的函数的地址。

我不知道它是否足够明确,所以这里有一个小例子:

main:
call    my_function
// rest of the program

my_function:
//do things
ret

鉴于我知道 my_function 地址,有没有办法在踩 RET 时找到 my_function 的地址?

这是跟踪循环中的一些代码:

        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); */
                }
        }

谢谢 !(我希望它足够清楚,不是我的母语:/)

标签: cassemblycallptrace

解决方案


推荐阅读