首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在DebugBreak()中中断指令int 3之前使用xchg、ax的目的是什么?

在DebugBreak()中中断指令int 3之前使用xchg、ax的目的是什么?
EN

Stack Overflow用户
提问于 2021-10-21 13:55:16
回答 1查看 194关注 0票数 1

在MASM中,我总是插入一个独立的中断指令

代码语言:javascript
复制
00007ff7`63141120 cc              int     3

但是,将该指令替换为MSVC DebugBreak函数将生成

代码语言:javascript
复制
KERNELBASE!DebugBreak:
00007ff8`6b159b90 6690            xchg    ax,ax
00007ff8`6b159b92 cc              int     3
00007ff8`6b159b93 c3              ret

我很惊讶地看到了xchg指令之前的中断指令。

代码语言:javascript
复制
xchg    ax,ax

正如另一条S.O.所指出的:

实际上,xchg,ax正是MS反汇编“6690”的方式。66是操作数大小覆盖,因此它应该在ax上运行,而不是eax。但是,CPU仍然以nop的形式执行它。这里使用66前缀使指令大小为两个字节,通常用于对齐。

MSVC和大多数编译器一样,将函数对齐到16个字节的边界。

问题那个xchg指令的目的是什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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,但它仍然不能使用单字节指令,因为两字节的反向跳转可能是在指令指针指向第二条指令时编写的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69663300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档