我前段时间读过一个家伙的文章,他演示了如何通过其内存地址直接在程序集(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
使用普通地址还是相对地址都没有关系,无论如何我都会收到相同的错误消息。
知道什么问题的人吗?
答案 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
调用对流(它们自己清除栈)。