在MASM中,我总是插入一个独立的中断指令
00007ff7`63141120 cc int 3但是,将该指令替换为MSVC DebugBreak函数将生成
KERNELBASE!DebugBreak:
00007ff8`6b159b90 6690 xchg ax,ax
00007ff8`6b159b92 cc int 3
00007ff8`6b159b93 c3 ret我很惊讶地看到了xchg指令之前的中断指令。
xchg ax,ax正如另一条S.O.所指出的:
实际上,xchg,ax正是MS反汇编“6690”的方式。66是操作数大小覆盖,因此它应该在ax上运行,而不是eax。但是,CPU仍然以nop的形式执行它。这里使用66前缀使指令大小为两个字节,通常用于对齐。
MSVC和大多数编译器一样,将函数对齐到16个字节的边界。
问题那个xchg指令的目的是什么?
发布于 2021-10-27 14:18:19
MSVC在函数开始时在任何单字节指令之前生成2字节nop (空函数中的ret除外)。我试过__halt,_enable,_disable的本质,也看到了同样的效果。
显然是用来修补的。/hotpatch选项为x86提供了相同的更改,而/hotpatch选项在x64上不被识别。根据/hotpatch文档,这是预期的行为(强调地雷):
因为在ARM体系结构中指令总是两个字节或更大,而且由于x64编译总是被视为/hotpatch已被指定为,所以在为这些目标编译时不必指定/hotpatch;
因此,对x64的热补丁支持是无条件的,其结果可以在DebugBreak实现中看到。
见此处:https://godbolt.org/z/1G737cErf
请参阅这篇关于为什么热补丁需要它的文章:为什么Windows函数都以无意义的MOV、EDI指令开始?。看起来,当前的热修补非常聪明,可以使用任意两个字节或更多的指令,而不仅仅是MOV EDI, EDI,但它仍然不能使用单字节指令,因为两字节的反向跳转可能是在指令指针指向第二条指令时编写的。
https://stackoverflow.com/questions/69663300
复制相似问题