mov al, 1
,假设 x86-32,您要使用的指令变为b0 01
(您可以在此处查看)。即2 Bytes。
您正在修补 ( mov byte ptr ds:[ecx+0x72], al
)的指令是88 41 72
,因此占用3 字节。已经看到问题了吗?
这意味着您只修补指令的前两个字节,并且需要用单字节 NOP(无操作,即90
)填充它,以便所有后续指令都正确。
否则处理器将开始解码<patched-instruction>+2
并假设它是正确的。它可能不是。
不确定所有这些屏幕截图应该是关于什么的。它们似乎与您说要修补的说明无关...
既然您已经发布了补丁站点的屏幕截图,我们甚至可以告诉您 CPU 试图执行的内容。
补丁之前的补丁站点直接位于函数的返回处:
88 41 72 mov BYTE PTR [ecx+0x72],al
c2 04 00 ret 0x4
; ------ end of function
90 nop
90 nop
90 nop
90 nop
90 nop
90 nop
打完补丁后,它看起来像这样:
b0 01 mov al,0x1
72 c2 jb 0xffffffc6
04 00 add al,0x0
; ------ end of function
90 nop
90 nop
90 nop
90 nop
90 nop
90 nop
总体上仍然是 12 个字节(在您正在修补的函数中是 6 个字节),但含义完全不同。我们可以猜测,要么是跳转指令被执行并导致了访问冲突的位置,要么条件 (of jb
) 没有评估为真,CPU 执行了add
6x 之后nop
,然后以完全不同的方式结束函数(至少这看起来像一个函数序言)但是从调用到前一个函数的堆栈仍然在原位等等......