如何强制 NASM 将 int3 编码为 0xCC
Posted
技术标签:
【中文标题】如何强制 NASM 将 int3 编码为 0xCC【英文标题】:How to force NASM to encode int3 as 0xCC 【发布时间】:2018-03-12 07:12:22 【问题描述】:我正在尝试使用 NASM 组装以下代码
section .text
global _start
_start:
mov eax, 1
int 3
Objdump -D 产生:
test: file format elf64-x86-64
Disassembly of section .text:
0000000000400080 <_start>:
400080: b8 01 00 00 00 mov $0x1,%eax
400085: cd 03 int $0x3
有趣的是,当用 GAS 组装时,int 3 被编码为 0xCC 而不是 cd 03,这是为什么呢?
【问题讨论】:
请注意one of the reasons MS chose to fill uninitialized memory with 0xCC to aid debugging is because of theint 3
【参考方案1】:
使用int3
助记符进行特殊的单字节编码。
nasm -l /dev/stdout /tmp/foo.asm
1 00000000 CD03 int 3
2 00000002 CC int3
来自Intel's insn set manual entry for int
:
INTO
或INT3
(CC) 生成的中断与INT n
生成的中断在以下方面有所不同:在虚拟 8086 模式下不会发生正常的 IOPL 检查。使用任何 IOPL 值进行中断(无故障)。
虚拟 8086 模式扩展 (VME) 启用的中断重定向不会发生。中断始终由保护模式处理程序处理。
这些功能不属于 CD03,即 INT 3 的“正常”2 字节操作码
它还说:
Intel 和 Microsoft 汇编器不会从任何助记符生成 CD03 操作码
因为 2 字节编码没有任何正常/常见的用例。 NASM 保持简单,始终使用CD
操作码作为int
助记符。
当 NASM 确实将 mov rax, 1
优化为 mov eax,1
之类的东西时,它是使用相同助记符的不同操作码。 IDK 如果实施起来不方便,或者 NASM 只是决定不这样做。将int3
视为一条特殊指令,与int n
不同,这是有道理的,因为它只有1 个字节。
【讨论】:
除了向后兼容之外,使用 CD03 的意义何在? @Trey:它们在 vm86 模式下的行为不同。除此之外,可能没有理由输入int 3
而不是 int3
,但 NASM 为您提供了选择。
很遗憾他们没有使用不同的助记符(例如“break
”),因此软件中断之间的差异(受权限检查,如果这些检查失败)并且断点异常(不是软件中断并且不受权限检查)更加明显。
@Brendan:在这种情况下,“他们”是英特尔,对吧?是的,同意。
@Brendan - 也许是缺乏远见?指令集最初是在 70 年代设计的。特权级别和保护在 80 年代后期得到了支持。没有多少人期望这会持续到下一个千年。 :-)以上是关于如何强制 NASM 将 int3 编码为 0xCC的主要内容,如果未能解决你的问题,请参考以下文章