为什么“MOV DWORD PTR ds:0xdeadbeef”指令取消引用 0xdeadbeef 地址?

逆向工程 拆卸 部件
2021-06-16 10:21:42

我正在对二进制文件进行逆向工程,但我很困惑,因为我的理论知识目前与实际发生的事情发生冲突。

我认为这条指令将值 0xdeadbeef 写入 edx:

mov edx, DWORD PTR ds:0xdeadbeef

我认为这条指令取消引用地址 0xdeadbeef 并将存储在该地址的任何 DWORD 值写入 edx:

mov edx, DWORD PTR ds:[0xdeadbeef]

但是,实际上,运行此指令:

mov edx, DWORD PTR ds:0x804bdf4

结果 edx 的值为:

edx = 0xb73fc115

0xb73fc115是存储在地址的值0x804bdf4

x 0x804bdf4
0x804bdf4 <gContents>: 0xb73fc115

所以这意味着地址被取消引用,即使程序集不包含任何方括号。我认为方括号表示取消引用操作。我误解了什么?

我正在使用 GDB


更新:我刚刚在radare2上对其进行了测试,它以我期望的格式显示了指令

mov edx, dword [obj.gContents]

我也用objdump测试过,结果和用GDB一样。我认为这是我目前不理解的某种语法?

2个回答

当取消引用明确时,IDA(基于MASM使用的默认汇编器语法不使用方括号。在您的情况下,第二个操作数显然是从中读取值的内存地址,而 DWORD PTR 是另一个暗示正在取消引用的提示。如果您希望始终看到方括号,您可以在Options > General..., Analysis 中切换到 TASM 汇编器

国际开发协会选项

如果操作数有方括号,
如果运算符前面是 Size PTR 段,则取消引用:
如果源操作数的大小与目标不同,则取消引用,则移动将需要特定的扩展
,零扩展或符号扩展

在某些情况下(主要是 IDA)将显示

.text:00404EB1                 movzx   eax, ds:byte_40523D[eax] 

这相当于

0F B6 80 3D 52 40 00    movzx eax, byte ptr [eax + 0x40523d]

在这种情况下,eax 将保存一个 switch case 并且常量是一个跳转表

对于直接写入操作,它将是

mov reg , const 

喜欢

mov edx,0xdeadbeef with no other decorations added

您可以访问此站点对以下代码段进行组装和拆卸测试

mov edx, dword ptr ds:[0xdeadbeef]
movzx edx, word ptr ds:[0xdeadbeef]
movzx edx, byte ptr ds:[0xdeadbeef]
movsx edx, word ptr ds:[0xdeadbeef]
movsx edx, byte ptr ds:[0xdeadbeef]

nop
nop

mov edx, dword ptr ds:0xdeadbeef
movzx edx, word ptr ds:0xdeadbeef
movzx edx, byte ptr ds:0xdeadbeef
movsx edx, word ptr ds:0xdeadbeef
movsx edx, byte ptr ds:0xdeadbeef