MASM Mov从/到即时内存地址

时间:2016-03-09 23:41:56

标签: visual-studio-2012 x86 masm inline-assembly

最近,我一直在为游戏模式编写一些x86汇编注入,但由于我的大部分工作流程都涉及手工编写和组装自定义例程,所以我一直在寻求更强大的解决方案

微软的内联汇编程序似乎是一个不错的选择,但我遇到了它似乎有的限制。

每当我写一条涉及直接内存地址的指令(游戏使用固定的地址空间布局)时,汇编器会默默地将其转换为立即值。

例如,在MASM中:

mov ecx, 0xCCCCCCCC    => B9 CC CC CC CC
mov ecx, [0xCCCCCCCC]  => B9 CC CC CC CC*

* Should be: 8B 0D CC CC CC CC

在这种情况下,两个汇编的指令都在加载具有立即值0xCCCCCCCC的ecx,尽管第二个指令应该从立即地址 0xCCCCCCCC

中获取值。

请注意,可以这种方式使用命名变量:

mov ecx, [myInt]

将汇编为8B 0D内存提取指令,但它也会将操作数添加到模块的重定位表中,并且不允许指定任意地址。

试图用类似

的东西欺骗汇编程序
mov ecx, [myInt-myInt+0xCCCCCCCC]

同时导致地址被视为立即值。

可以选择:

mov ecx, 0xCCCCCCCC
mov ecx, [ecx]

哪个会正确组装并显示正确的行为,但现在我的注射大小增加了2个不必要的字节。因为我在一些相当严格的空间限制下工作,这是不可接受的,我宁愿不使用我不需要的代码洞。

有趣的是C中的某些内容:

register int x;
x = *(int*)(0xCCCCCCCC)

快乐地编译到

mov ecx, [0xCCCCCCCC]  => 8B 0D CC CC CC CC

看到较低级别的语言比较高级别的语言有更多限制,这有点奇怪。我正在尝试做的事情对我来说似乎很合理,所以有人知道MASM在从内存中读取时是否有一些隐藏的方式使用固定的直接内存地址?

2 个答案:

答案 0 :(得分:1)

我不确定这是否可以在平面内存模型之外工作,但我发现MASM区分了直接地址和立即值,如下所示:

b

前2条指令使用立即值0xCCCCCCCC加载ecx。最后一条指令使用地址0xCCCCCCCC的值加载ecx。

答案 1 :(得分:1)

在NASM语法中,

    mov     ecx, 0xCCCCCCCC                  ; B9 CC CC CC CC     mov ecx, imm32
    mov     ecx, [0xCCCCCCCC]                ; 8b 0d cc cc cc cc  mov r32, [disp32]
    mov     ecx, [_start-_start + 0xCCCCCCCC]; 8b 0d cc cc cc cc  same

在我的GNU / Linux桌面上使用nasm -felfyasm -felf进行了测试。

我想知道它是否是MASM将[0xCCCCCCCC]组装成立即而不是有效地址的错误。当它是其他指令的操作数时,它是否也这样做?例如LEA是错误的吗?