2009-09-17 44 views
1

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

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

回答

1

没有简单的方法来做到这一点,我知道。

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

另一个令人讨厌的方式可能是获取类似Bochs(一个开放源代码的x86模拟器)的源代码,并对其进行更改,以便在执行您感兴趣的指令时执行所需操作。

2

一般要做到这一点的任意x86代码和捕获所有角落情况下,唯一的办法就是要么:

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

第一种方法可能会更好。因为它不会捕获像自修改代码或跳到另一条指令中间那样的情况,所以试图反编译除了单步执行时间以外的操作码是行不通的。

为了实现单步方法,每个被跟踪进程停止的时候,你会用PTRACE_GETREGS让孩子的寄存器,然后用孩子的%eip寄存器的值作为地址传递给PTRACE_PEEKTEXT,让下一个单词是执行。检查该单词以查看它是否是CPUID指令 - 如果是,则通过调整子单元的寄存器集(包括通过CPUID指令前进%eip)来模拟指令。然后致电PTRACE_SINGLESTEP让该过程继续。

相关问题