我在几个 Windows 程序的开头看到了这条指令。它正在将寄存器复制到自身,所以基本上,这充当nop
. 这条指令的目的是什么?
'mov edi, edi' 的目的是什么?
Raymond Chen(微软)有一篇博客文章详细讨论了这个问题:
https://devblogs.microsoft.com/oldnewthing/20110921-00/?p=9583
简而言之,这是为了支持运行时热修补而应用的编译时添加,因此该函数可以用 JMP 指令覆盖前两个字节以将执行重定向到另一段代码。
它旨在跳转到特定位置,即 mov 指令之前的 5 个字节。从那里,您有 5 个字节,打算将其修改为长跳转到 32 位内存空间中的其他位置。注意hot-patching的时候要先放那个5字节的跳转,然后再替换mov即可。反过来说,你冒着先运行被替换的 mov-jmp 的风险,然后跳转到任何碰巧在那里的 5 个字节(默认情况下都是 nops,但你永远不知道)。
[补充如下]
关于写入 5 个字节的跳转 - 还有一个问题,即只有一条指令可以让您原子地写入 4 个以上的字节 - cmpxchg8b,这不是用于此目的的理想指令。如果先写入 0xe9,然后写入 dword,则如果在放置 dword 之前执行 0xe9,则会出现竞争条件。首先写跳远的另一个原因。
亚历山大·索蒂罗夫( Alexander Sotirov)在 2006 年 BlackHat USA 上的Courtsey Hotpatching and the Rise of Third-Party Patches演讲
什么是热补丁? 热修补是一种通过在运行时修改应用程序的二进制代码来修改应用程序行为的方法。这是一种具有多种用途的常用技术:
• 调试(软件断点)
• 运行时检测
• 挂钩 Windows API 函数
• 修改执行或向闭源应用程序添加新功能
• 无需重启即可部署软件更新
• 修复安全漏洞
热补丁是由一个自动化工具生成的,该工具比较原始二进制文件和打补丁的二进制文件。已更改的功能包含在扩展名为 .hp.dll 的文件中。当正在运行的进程中加载热补丁 DLL 时,易受攻击函数的第一条指令被替换为跳转到热补丁。
的/ hotpatch编译选项确保每一个函数的所述第一指令是一个 MOV EDI,EDI 可由hotpatch安全地覆盖指令。较旧版本的 Windows 不使用此选项编译,因此无法进行热修补。