我正在尝试使用MessageBoxA Windows API,如下所示https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-messageboxa
当执行以下代码时,r15
是MessageBoxA,我成功执行了API,但没有值。
xor rcx, rcx
xor rdx, rdx
xor r8, r8
xor r9, r9
call r15
当我尝试在文本字段中分配字符串值时,它无法执行,我不知道为什么。
xor rcx, rcx
mov rdx, 0x0041414141
xor r8, r8
xor r9, r9
call r15
我可以使用在.data
部分中定义的变量,它工作得很好,但我想弄清楚如何在没有.data
部分的情况下实现它。
例如
section .data
aaaa db 'AAAA',0
...
mov rdx, aaaa
2条答案
按热度按时间7bsow1i61#
MessageBoxA
函数要求其字符串参数位于内存中,而不是寄存器中。既然你不想把它放在.data
部分,我们可以使用堆栈:字符串需要在函数调用的整个持续时间内都在堆栈上,它不能在更早的时候弹出。
它不能在影子空间中,被调用者在阅读指向的内存之前可能会覆盖它,这就是为什么我们在保留影子空间之前要
push
*。请记住,在
call
之前将RSP对齐16,因为Windows x64调用约定要求这样做。这意味着从函数入口开始,执行奇数个8字节调整,计算推压和sub rsp, constant
。如果你已经做了奇数次的push,然后你想push
一些ASCII字节,你可以sub rsp, 40
而不是sub rsp, 32
,并调整add rsp, 40
相同的数量来撤消它。在这种情况下,
push 'AAAA'
将具有与mov edx, 'AAAA'
/push rdx
相同的效果。push
只支持16位和64位的操作数大小,NASM默认为64位,除非另有说明。push imm32
将立即数符号扩展为64位,而'A'
将其符号位置零,因此我们将从符号扩展中获得一个以零结尾的字符串,就像零扩展一样。yacmzcpb2#
如果使用x86,你可以在self代码中使用下一个片段:
(or只是将其留在堆栈中,以便传递给API调用)
或者你可以使用这样的宏
和create函数,返回字符串的地址
并在代码中使用它:
这段代码也可以在x64中使用,但这里也可以简单地使用莱亚,因为它是独立的
或者直接用代码