调用immediate与调用dword near [dword addr]



所以最近我一直想从汇编中调用一些win32调用,并且我一直使用NASM作为我的外部汇编器。我在代码中以以下方式调用SendMessage:

call __imp__SendMessageW@16

这被组装成一个相对跳转(0xE8操作码),结果是访问冲突。在调试器中,计算的跳跃偏移量似乎是正确的(因为__imp__SendMessageW@16似乎确实存在于那里),但它仍然不起作用。当我从c++调用函数时,检查Visual Studio产生的程序集,我注意到它不是使用相对直接的跳转,而是(在MASM的语言中)call dword ptr [__imp__SendMessageW@16],对应于0xFF15操作码。经过一番摸索后,我发现NASM语法将此编码为call dword near [dword __imp__SendMessageW@16],并使更改我的代码突然工作了。

我的问题是,为什么一个工作,而不是另一个?是否有一些代码的重定位导致相对直接调用跳转到不友好的地方?我从来都不是一个汇编程序员,但我的印象总是两个调用应该做同样的事情,主要区别在于一个是位置独立的,另一个不是(假设他们将IP移动到相同的地方)。考虑到这一点,重新定位代码理论是有意义的,但是您如何解释调试器显示正确的地址呢?

还有:这个调用中[]语法背后的逻辑是什么?偏移量仍然是直接的(只是在0xFF15之后编码的小端序),这里除了指令获取之外没有内存访问(我倾向于将[]视为lea上下文之外的解引用)。

call dword[__imp__SendMessageW@16]

_imp_SendMessageW@16是导入部分的地址,其中包含API函数的地址。使用方括号来区分(调用这个地址存储的地址)

最新更新