【问题标题】:Detect call's offset with ptrace使用 ptrace 检测调用的偏移量
【发布时间】:2013-06-17 18:40:42
【问题描述】:

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

【问题讨论】:

    标签: c assembly function-calls ptrace


    【解决方案1】:

    试试:

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

    dest 是一个 64 位的值,但这里的偏移量被编码为 32 位。对于这种代码,以十六进制打印要好得多

    【讨论】:

    • 其实是有符号的偏移量。
    • @IgorSkochinsky 是的,我意识到了这一点。我只是想避免实现定义的行为并忘记了演员表。已编辑。谢谢
    猜你喜欢
    • 2016-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-19
    相关资源
    最近更新 更多