内存读取访问断点问题

逆向工程 拆卸 断点
2021-07-04 03:08:24

我在 C 代码中实现了内存读取访问硬件断点。它工作完美,并在读取内存后为我提供下一条指令。

我正在使用 BeaEngine 反汇编EIP.

我需要找出先前执行的指令,该指令实际上是访问相关内存的指令(例如,像 Cheat Engine 那样)。

我怎样才能做到这一点?

1个回答

这是一个棘手的问题。

在 x86 平台上,指令的最大长度为 15 个字节。

您可以从当前 EIP 向后读取 15 个字节并将其传递给DisasmBeaEngine 的函数。这将返回反汇编指令的长度。如果这等于 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会打EIPaddress如果你使用上面的算法,之前执行的指令就会被证明pop eax是错误的。对于这种情况,您可以使用指令跟踪或内存断点(123)。