使用ptrace检测调用的偏移量

时间:2013-06-17 18:40:43

标签: c assembly function-calls ptrace

我正在尝试使用函数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会包含我刚刚跳转到的函数的地址吗?根据我的测试似乎没有,但我认为它应该。

1 个答案:

答案 0 :(得分:0)

尝试:

printf("call : 0x%lx\n", regs.rip + (long) (int) (dest & (unsigned long) UINT_MAX);

dest是64位值,但偏移量在此处以32位进行编码。对于这种代码,以十六进制打印要好得多。