我正在尝试做一个可以使用函数 ptrace 检测调用的程序。使用 PTRACE_SINGLESTEP 我可以按指令运行程序指令,然后,当我得到寄存器 RIP 指向的 OP_CODE 0xe8 时,我使用 PTRACE_PEEKTEXT 来获取 RIP 指向的地址之后的 4 个下一个字节。然后,根据我在互联网上找到的文档,这 4 个字节包含一个偏移量,指的是要跳转的位置。似乎 PTRACE_PEEKTEXT 返回了一些奇怪的值,而且我的偏移量太大了。下面是我的代码:
instr_num = ptrace(PTRACE_PEEKTEXT, this->pid, regs.rip, 0);
dest = ptrace(PTRACE_PEEKTEXT, this->pid, regs.rip + 1, 0);
if (instr_num == 0xe8)
{
printf("call : %ld\n", regs.rip + dest);
}
这是输出:
call : -2853719444197214464
call : -2853719444197214464
call : -2853719444197214464
这是 objdump -D 的输出,你可以看到在 main 调用和函数 func 的开头之间有 15 个字节的偏移量:
00000000004004c4 <func>:
4004c4: 55 push %rbp
4004c5: 48 89 e5 mov %rsp,%rbp
4004c8: 5d pop %rbp
4004c9: c3 retq
00000000004004ca <main>:
4004ca: 55 push %rbp
4004cb: 48 89 e5 mov %rsp,%rbp
4004ce: b8 00 00 00 00 mov $0x0,%eax
4004d3: e8 ec ff ff ff callq 4004c4 <func>
4004d8: 5d pop %rbp
4004d9: c3 retq
如果在我检测到一个呼叫之后,我执行一次 ptrace(PTRACE_SINGLESTEP),我的 RIP 会包含我刚刚跳转到的函数的地址吗?根据我的测试,它似乎不是,但我认为它应该。