如何在无.data段的Win API调用中传入字符串?以MessageBoxA为例
调用MessageBoxA无显示/直接传十六进制值失败的问题解析
问题原因
- 空内容的原因:你第一段代码中
xor rdx, rdx将第二个参数lpText设为NULL,MessageBoxA接收NULL时会显示空对话框,因此能执行但看不到内容。 - 直接传十六进制值失败的原因:MessageBoxA的
lpText参数要求的是字符串的内存地址,而非字符串内容本身。mov rdx, 0x0041414141是把这个十六进制值当成内存地址去访问,而0x41414141这类低地址通常属于未分配的无效内存,触发内存访问错误,导致执行失败。
无需.data段的实现方法
方法1:将字符串嵌入代码段(.text)
代码段默认是可读可执行的,可以直接把字符串放在指令流后面,通过相对寻址获取其地址:
xor rcx, rcx ; hWnd = NULL lea rdx, [rel msg] ; 取代码段中字符串的相对地址 xor r8, r8 ; lpCaption = NULL xor r9, r9 ; uType = MB_OK call r15 msg: db 'AAAA', 0 ; 字符串直接嵌入代码段,末尾加终止符0
注:rel用于生成位置无关的相对地址,适配x86-64下的PE文件加载机制,避免绝对地址带来的问题。
方法2:利用栈存储字符串
通过在栈上构造字符串,直接使用栈地址作为参数:
xor rcx, rcx ; hWnd = NULL sub rsp, 16 ; 分配16字节栈空间,保证call前栈16字节对齐 mov qword [rsp], 0x0041414141 ; 栈上写入'AAAA' + 终止符0(低4字节为'AAAA',高4字节为0) lea rdx, [rsp] ; lpText = 栈上字符串的地址 xor r8, r8 ; lpCaption = NULL xor r9, r9 ; uType = MB_OK call r15 add rsp, 16 ; 平衡栈,释放分配的空间
注:x86-64调用约定要求调用函数前栈必须是16字节对齐,因此用sub rsp,16调整栈空间,调用完成后用add rsp,16恢复。
内容的提问来源于stack exchange,提问作者jord
相关产品推荐
相关产品推荐

