我正在尝试使用函数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会包含我刚刚跳转到的函数的地址吗?根据我的测试似乎没有,但我认为它应该。
答案 0 :(得分:0)
尝试:
printf("call : 0x%lx\n", regs.rip + (long) (int) (dest & (unsigned long) UINT_MAX);
dest
是64位值,但偏移量在此处以32位进行编码。对于这种代码,以十六进制打印要好得多。