它可以完美工作并在读取内存后为我提供下一条指令。
我正在使用BeaEngine在
EIP
上反汇编指令。我需要找出前一条已执行的指令,该指令实际上是访问有问题的内存的指令(例如,像作弊引擎一样)。
如何我做到了吗?
#1 楼
这是一个棘手的问题。在x86平台上,一条指令的最大长度为15个字节。
您可以从当前EIP向后读取15个字节,并将其传递给BeaEngine的
Disasm
函数。这将返回反汇编指令的长度。如果等于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
设置了读取时的硬件断点。在这种情况下,当EIP
位于address
时,hwbp将达到。如果使用上述算法,则先前执行的指令将变成pop eax
,这是不正确的。 在这种情况下,可以使用指令跟踪或内存断点(1、2、3)。
评论
很有道理,非常感谢您的解释!
– fred26
16 Mar 26 '16 at 12:09
即使执行顺序是线性的,您也可能找不到期望的结果。考虑32位反汇编8B 8B 05 78 56 3412。然后考虑8B 05 78 56 34 12.根据寄存器值,它们中的任何一个都是正确的。消除歧义实际上是不可能的。
–彼得·弗里
16 Mar 28 '16 at 16:08