【问题标题】:Looking for a way to trap CPUID instructions寻找一种捕获 CPUID 指令的方法
【发布时间】:2009-09-17 17:41:11
【问题描述】:

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

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

【问题讨论】:

  • 为了记录(尽可能不是 OP 想要的答案),因为 IvyBridge 英特尔 CPU 实际上是 support CPUID 故障。

标签: linux debugging opcode breakpoints ptrace


【解决方案1】:

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

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

第一种方法可能更好。

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

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

【讨论】:

  • Intel's SDE 基本上为您提供了第一种方法(另一方面,它也有可能或多或少地模拟从 SSE3 开始的所有内容)。
【解决方案2】:

据我所知,没有简单的好方法。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多