直接在user32.dll中调用函数时出错

时间:2018-11-24 19:02:47

标签: winapi assembly x86 nasm

我前段时间读过一个家伙的文章,他演示了如何通过其内存地址直接在程序集(NASM)中的user32.dll中调用函数。我没有该文章了,但我正在尝试重现该实验。

我要执行的功能是user32.dll中的MessageBoxA,在我的计算机上,该功能应位于地址0x76cd75c0。

功能如下:

int MessageBoxA(
     HWND hWnd,              # NULL
     LPCSTR IpText,          # text
     LPCSTR IpCaption,       # title
     UINT uType              # style
);

这是程序:

global _main                        

section .data                       
msgText:    db 'Hello World', 0
msgCaption: db 'Title', 0       

section .text                   
_main:                          
    push 0
    push msgCaption
    push msgText
    push 0
    call 0x76cd75c0

    add esp, 4
    ret 0x10

对于编译程序,我使用:

nasm –f win32 message_box.asm

但是,我收到此错误消息:

error: Win32 COFF does not correctly support relative references to absolute 
addresses

使用普通地址还是相对地址都没有关系,无论如何我都会收到相同的错误消息。

知道什么问题的人吗?

1 个答案:

答案 0 :(得分:2)

问题在于它不存在直接的call(地址直接作为操作数给出),附近(无段)和绝对值。
参见here

call XXX靠近且直达,因此它不是绝对的。
其实是相对的。
NASM tries to create a relocation用于相对调用(请注意OUT_REL4ADR类型),但是0x76cd75c0在源中定义的任何节之外,并且显然不支持。

使用绝对地址调用函数的唯一方法是使用FAR调用,但这需要立即段值。
这很少会在保护模式下很好地结束,并且在注释中指出了a,这也会推cs。 (否则,您可以像call 0x23:0x76cd75c0中那样使用0x23 selector that Windows sets for 32-bit applications)。

您可以使用间接调用:

mov ebx, 0x76cd75c0
call ebx

请注意,add esp, 4在这里看起来很错误,Win API遵循stdcall调用对流(它们自己清除栈)。