注意:我通常会涉足反汇编(即助记符),并且只在无法避免的情况下查看原始操作码。
我有以下由 IDA Pro 7.1.180227 创建的 Windows x64 内核模式驱动程序的反汇编行:
xor edx, edx
现在我知道一个事实,这是准备通过rdx
. 我也知道该代码的目的是将所述指针参数设置为NULL
.
操作码是33 D2
. 和交叉引用与参考或看着它在官方发展援助得到相同的与IDA: xor edx, edx
。
现在,这个反汇编让我感到不妥的是rdx
,作为 的超集edx
,在该确切代码路径上的其他地方使用来存储其他指针。所以理论上,上面的双字rdx
可能是“脏”。
根据这是 x64 代码的事实,我希望它能够读取xor rdx, rdx
. 为什么这不是它在反汇编中的呈现方式?
现在我明白了,根据英特尔 SDM (05/2018) 的第 3.6.1 节(表 3-4),操作码的 REX.W 前缀会影响操作数大小。
对于此操作码,既不存在操作数大小 (66h) 也不存在地址大小 (67h) 前缀。
因此,通过英特尔 SDM(“XOR-Logical Exclusive OR”部分),我确实应该处理操作码33 /r
或指令XOR r32, r/m32
,确认操作码的 IDA 翻译。参考英特尔 SDM 的第 2.1.5 节(“ModR/M 和 SIB 字节的寻址模式编码”)为我们提供了有关操作数 ( D2
)如何编码的线索,因此从表 2-2(“带有 ModR/M 字节的 32 位寻址形式"):EDX/DX/DL/MM2/XMM2
作为操作数。
数据。
然而,这意味着“脏”的高位双字 inrdx
不会被清零,因此最终会传递一个乱码/截断的指针。鉴于这是内核模式代码,后果应该很清楚。
我简直不敢相信编译器会犯这样的错误。那么我错过了什么?