我正在寻找一种巧妙的方法来捕获和处理Linux进程的CPUID指令。使用ptrace()并修补由进程创建的所有可执行mmap区域中的所有cpuid操作码,用int3替换它们。由于CPUID操作码字节经常作为其他较长操作码的一部分出现,所以效果不好。
所以基本上我正在寻找一些方法,允许我设置一个不在特定内存地址上的断点,而是每次调用一个操作码。任何人都知道如何做到这一点?
答案 0 :(得分:2)
一般来说,在任意x86代码上执行此操作以及捕获所有角落案例的唯一方法是:
PTRACE_SINGLESTEP
,见下文);或第一种方式可能更好。
(尝试使用单步执行反编译操作以外的操作码不起作用,因为它不会捕获像自修改代码或跳到另一条指令中间的情况。)
要实现单步执行方法,每次跟踪进程停止时,您将使用PTRACE_GETREGS
获取子进程的寄存器,然后使用子进程的%eip
寄存器值作为传递给{的地址{1}},获取下一个要执行的单词。检查该单词以查看它是否是CPUID指令 - 如果是,则通过调整子程序的寄存器集来模拟指令(包括超过CPUID指令前进PTRACE_PEEKTEXT
)。然后致电%eip
让流程继续。
答案 1 :(得分:1)
我不知道这样做的好方法。
一种讨厌的方式可能是使用GDB的python脚本API自动单步执行程序,在执行之前检查每条指令。
另一种令人讨厌的方法可能是获取像Bochs这样的开源x86模拟器之类的源代码,并对其进行更改,以便在执行您感兴趣的指令时执行所需的操作。