我在 C 代码中实现了内存读取访问硬件断点。它工作完美,并在读取内存后为我提供下一条指令。
我正在使用 BeaEngine 反汇编EIP
.
我需要找出先前执行的指令,该指令实际上是访问相关内存的指令(例如,像 Cheat Engine 那样)。
我怎样才能做到这一点?
我在 C 代码中实现了内存读取访问硬件断点。它工作完美,并在读取内存后为我提供下一条指令。
我正在使用 BeaEngine 反汇编EIP
.
我需要找出先前执行的指令,该指令实际上是访问相关内存的指令(例如,像 Cheat Engine 那样)。
我怎样才能做到这一点?
这是一个棘手的问题。
在 x86 平台上,指令的最大长度为 15 个字节。
您可以从当前 EIP 向后读取 15 个字节并将其传递给Disasm
BeaEngine 的函数。这将返回反汇编指令的长度。如果这等于 15,则您已找到上一条指令。如果小于15,则少传递1个字节(即14个字节),依此类推,直到传递给BeaEngine的缓冲区长度等于反汇编指令的长度。
这可以用伪代码表示
eip = 0xDEADCODE
length = 15
while(length > 0)
{
buffer = ReadProcessMemory(start=eip-length, length)
lenDisasm = Disasm(buffer)
if (lenDisasm == length)
{
prevIns = eip-length
break;
}
else length--;
}
请注意,上述算法本质上不是通用的,即您不能使用它来查找给定当前eip
. 这只适用于执行序列是线性的,中间没有任何跳转。在访问时出现硬件断点的情况下,执行顺序保证是线性的,并且上述算法是适用的。
编辑:
即使在访问时出现硬件断点的情况下,执行顺序也可能不是线性的,如下例所示
format PE
entry start
section '.text' code readable executable
start:
nop
nop
jmp dword [here]
mov eax, 1
push eax
pop eax
address:
xor eax, eax
ret
section '.data' readable writable
here: ; <<<<<<<< HWBP on read
dd address
读取时的硬件断点设置在 上here
。在这种情况下,当hwbp会打EIP
在address
。如果你使用上面的算法,之前执行的指令就会被证明pop eax
是错误的。对于这种情况,您可以使用指令跟踪或内存断点(1、2、3)。