俄版MASM64 SDK中CreateFileA/CreateFileW调用失败问题排查
俄版MASM64 SDK调用CreateFile失败的排查要点
调用CreateFileA/W出现参数错误,大概率是调用约定不匹配、字符串格式错误、SDK定义偏差或栈对齐问题导致,以下是具体排查方向:
1. x64调用约定不匹配
Windows x64平台强制使用fastcall调用约定:前4个参数依次放入RCX、RDX、R8、R9,剩余参数按从右到左顺序压栈;且调用API前RSP必须保持16字节对齐。
部分第三方MASM64 SDK(包括你用的俄版)可能自定义了invoke宏,若宏的参数映射逻辑错误(比如沿用32位栈传所有参数、寄存器顺序颠倒),会直接导致参数传递混乱,触发系统参数错误。
2. 字符串格式不匹配
- CreateFileA要求传入ANSI格式字符串(单字节字符,末尾带单字节
0终止符),若你定义的是Unicode双字节字符串,或遗漏终止符,API会读取到非法路径。 - CreateFileW要求传入UTF-16LE格式字符串(双字节字符,末尾带双字节
0x0000终止符),若误用ANSI字符串,或仅用单字节0作为终止符,同样会触发参数错误。
3. SDK常量/宏定义错误
俄版SDK可能自行重定义了Windows API的常量或宏:
- 比如
GENERIC_READ、OPEN_EXISTING、FILE_ATTRIBUTE_NORMAL等常量的值,若与Windows官方定义不符,会导致传入的权限、打开方式等参数非法。 - 部分SDK的
CreateFileA/W宏可能错误调整了参数顺序,直接导致参数错位。
4. 栈对齐问题
x64 Windows要求调用任何API前,RSP必须是16字节的整数倍。若你的代码在调用前未调整RSP到对齐边界(比如手动压栈后未修正偏移),会触发系统参数错误甚至崩溃。
验证与修复步骤
- 跳过SDK宏,手动按标准约定传参:
不用SDK的invoke宏,直接按寄存器规则传递参数,示例如下(CreateFileA):; 确保RSP对齐16字节(若之前有压栈,需调整RSP,比如sub rsp, 8 或 add rsp, 8) mov rcx, offset fileNameA ; 参数1:文件名(ANSI字符串,db "test.txt",0) mov rdx, 80000000h ; 参数2:GENERIC_READ(官方值) mov r8, 00000001h ; 参数3:FILE_SHARE_READ(官方值) mov r9, 0 ; 参数4:安全属性NULL push 3 ; 参数5:OPEN_EXISTING(官方值) push 80h ; 参数6:FILE_ATTRIBUTE_NORMAL(官方值) push 0 ; 参数7:模板文件NULL call CreateFileA - 检查字符串定义:
- ANSI字符串:
fileNameA db "test.txt", 0 - Unicode字符串:
fileNameW dw 't','e','s','t','.', 't','x','t', 0
- ANSI字符串:
- 替换为官方常量值:
直接使用Windows官方定义的常量数值(可查MSDN文档),替换SDK中可能错误的定义。 - 用微软官方ml64.exe编译测试:
若用官方MASM编译后能正常运行,说明问题出在俄版SDK的调用约定或宏定义上。
内容的提问来源于stack exchange,提问作者OSPFv3
相关产品推荐
相关产品推荐

