【问题标题】:number of executed bytes when debugging a PE调试 PE 时执行的字节数
【发布时间】:2018-11-08 09:48:59
【问题描述】:

我目前正在编写一个在 windows 平台上组装的小型调试器。

我打开被调试进程如下:

invoke    CreateProcess, addr buffer, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+DEBUG_ONLY_THIS_PROCESS, NULL, NULL, addr startinfo, addr pi

效果很好,我可以通过查看被调试对象的上下文来获取 EIP,这样我就可以获取将要执行的指令的第一个字节。

但是,我需要获取上一条指令中已执行的字节数。

指令不是大小独立的。有时一条指令只有 1 个字节,而另一些时候则 6 个字节或更多。

我尝试用当前 EIP 减去之前的 EIP,以获得已执行的字节数。但是如果有jmp或者call就不行了,因为地址空间已经不一样了。

我计划获取所有操作码的地图并制作一些 cmp,但这似乎是一项艰巨的工作。

如果您对获取已执行的上一条指令的字节数有任何想法(可能查看缓存或类似的东西),请告诉我。

最好的问候

【问题讨论】:

  • hack-ish 可能性:您可以在执行之前检测到jmp/jcc/loop/call/ret/int/syscall/not-sure-what-else-does-jump 并为这些设置大表,然后将newIP-oldIP 的hack 用于其他所有内容。这仍然很棘手,因为您甚至可以在那些跳跃的指令之前添加许多不同的(甚至在特定上下文中无用的)前缀。如果您的调试允许单步执行诸如rep movsb 之类的指令事务,也不确定您会得到什么,那么您是否得到0 大小? ...正确的解决方案:这很难,我宁愿使用一些库,如 keystone 或 NASM 反汇编程序。
  • (我不知道如何在运行时以动态方式直接从 CPU 获取此信息,即即使对于未来的指令/等也能获得正确的答案......会很好,但你的hack-ish 方式实际上是最健壮的,只能通过新引入的跳转指令将其丢弃)

标签: windows debugging assembly x86


【解决方案1】:

TL;DR

保持简单:单步并仅解码分支指令并使用EIP - last EIP,除非最后一条指令是分支(在这种情况下使用解码来查找长度)。
如果发现未知指令,请退出并且不提供其大小。


不可能向后解码 x86 指令流,因为 x86 编码不是对称的(w.r.t. 地址增长),看到这一点考虑mov eax, 90909090h 或类似的。

因此,您需要在单步执行程序时对每条指令进行反汇编(调试器无论如何都需要这样做)并记录其大小。
控制传输指令明显少于指令总数,因此您可以仅对其进行解码并使用EIP - EIP'(其中EIP' 是最后一条指令的EIP)技巧。

Intel 处理器支持 Last Branch Recording,但它需要操作系统支持,而且无论如何您都需要对数据进行后处理,这似乎太繁重了。
英特尔处理器跟踪技术也有类似的说法。

我想不出任何会导致指令字节数的性能计数器事件(假设您可以使用它们)。
实际上在后端,“指令”的概念已经被简化为一系列 uOP(可能有点说一个操作码是指令中的最后一个),而前端大多与架构价值解耦eip(几乎总是使用 eip 的推测值工作)所以它可能在后端之前有几条指令。
我相信每个 uOP 可能都有一个字段来记录如何在退休时更新 eip,但不是以字节为单位的指令大小。
同样在前端仅在预解码阶段记录了以字节为单位的指令长度,之后我认为它被丢弃了(我想不出它有什么用处)。

L1 指令缓存中的指令尚未解码,因此即使有办法检查它们的内容和元数据,那里也没有任何内容。

执行此操作的通常方法是进行跟踪:单步浏览程序,反汇编eip 处的指令(见下文),记录其大小,恢复程序,重复直到出现停止条件。
这会为您提供地址和指令大小的列表。
如果您发现一条指令无法解码,您要么不记录它的大小,要么尝试用一些启发式方法来估计它(它的长度必须小于 16B,理论上你可以将数据与来自 PMC 的计数相结合,如 @ 987654330@)。

It's possible to detect the size of an instruction at runtime but that's totally not feasible in this context.

【讨论】:

    猜你喜欢
    • 2017-01-12
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 2011-08-02
    相关资源
    最近更新 更多