3

我正在寻找一种巧妙的方法来捕获和摆弄 Linux 进程的 CPUID 指令。玩弄 ptrace() 并修补由进程创建的所有可执行 mmap'ed 区域中的所有 cpuid 操作码,用 int3 替换它们。由于 CPUID 操作码字节经常作为其他较长操作码的一部分出现,因此效果不佳。

所以基本上我正在寻找一种方法,允许我不在特定的内存地址上设置断点,而是在每次调用操作码时设置断点。任何人都知道如何做到这一点?

4

2 回答 2

2

通常,在任意 x86 代码上执行此操作并捕获所有极端情况的唯一方法是:

  • 在执行之前单步检查每条指令(PTRACE_SINGLESTEP见下文);或者
  • 完全模拟 x86 指令集。

第一种方法可能更好。

(尝试反编译操作码,而不是使用单步执行即时反编译是行不通的,因为它不会捕获诸如自我修改代码或跳转到另一条指令中间的情况)。

要实现单步法,每次被跟踪的进程停止时,您将使用PTRACE_GETREGS获取孩子的寄存器,然后将孩子的%eip寄存器值作为地址传递给PTRACE_PEEKTEXT,获取下一个要执行的单词。检查该词以查看它是否是 CPUID 指令 - 如果是,则通过调整孩子的寄存器集(包括%eip超越 CPUID 指令)来模拟该指令。然后打电话PTRACE_SINGLESTEP让这个过程继续。

于 2009-09-18T01:27:14.517 回答
1

我知道没有简单的好方法。

一个讨厌的方法可能是使用 GDB 的 python 脚本 API 来自动单步执行程序,在执行之前检查每条指令。

另一种讨厌的方法可能是获取诸如Bochs之类的源代码,一个开源 x86 仿真器,并对其进行更改,以便在执行您感兴趣的指令时执行您想要的操作。

于 2009-09-17T18:41:11.213 回答