windows - 调用 ExitProcess 时应该如何准备堆栈?
问题描述
我正在尝试学习如何在程序集中调用操作系统函数,并得到了一个示例,该示例将创建然后关闭一个文件(在关闭时删除它)。在研究我的用法时,ExitProcess
我遇到了一些清理堆栈的示例,而有些则没有;更令人困惑的是,无论有没有清理步骤,事情似乎都可以工作......
在这种情况下处理堆栈的正确方法是什么?
extern CloseHandle : proc
extern CreateFileA : proc
extern ExitProcess : proc
include FileAccess.inc
include FileDisposition.inc
include FileFlag.inc
include FileShare.inc
.data
filePath byte "C:\Temp\test123.txt",0
.code
Main PROC
sub rsp, 48h ; align with 16 while simultaneously making room on the stack for the "home space" and any parameters
lea rcx, filePath ; put address of file name into parameter slot 0
mov rdx, FILE_ACCESS_READ ; put access mode into parameter slot 1
mov r8, FILE_SHARE_READ ; put share mode into parameter slot 2
xor r9, r9 ; put security attributes into parameter slot 3
mov qword ptr [((rsp + 48h) - 28h)], FILE_DISPOSITION_CREATE ; put disposition into parameter slot 4
mov qword ptr [((rsp + 48h) - 20h)], FILE_FLAG_DELETE_ON_CLOSE ; put flags into parameter slot 5
mov qword ptr [((rsp + 48h) - 18h)], 0 ; put template handle into parameter slot 6
call CreateFileA ; create file handle
mov rcx, rax ; move file handle into parameter slot 0
call CloseHandle ; close file handle
add rsp, 48h ; free all space that was reserved on the stack
xor ecx, ecx ; set return value to zero
call ExitProcess
Main ENDP
END
解决方案
通常的ExitProcess
函数(windows api),必须使用 x64 的通用调用约定进行调用。特别是堆栈必须保持 16 字节对齐
,因此可以ExitProcess
像任何其他 api 一样调用。之前的add rsp, 48h
指令call ExitProcess
是错误的
还有一些一般注意事项:导入的 api 总是称为间接的 - 如果你想调用SomeApi
- 声明变量(x64 的代码)
extern __imp_SomeApi : QWORD
并打电话
call __imp_SomeApi
如果我们声明
extern SomeApi : proc
做
call SomeApi
链接器创建存根
SomeApi:
jmp qword ptr __imp_SomeApi
所以更好的直接使用__imp_SomeApi
形式。
也总是更好地使用W而不是A api 形式。所以所有代码看起来都像
FILE_FLAG_DELETE_ON_CLOSE = 04000000h
CREATE_ALWAYS = 2
FILE_SHARE_READ = 1
GENERIC_READ = 080000000h
INVALID_HANDLE_VALUE = -1
extern __imp_ExitProcess : QWORD
extern __imp_CreateFileW : QWORD
extern __imp_CloseHandle : QWORD
WSTRING macro text
FORC arg, text
DW '&arg'
ENDM
DW 0
endm
.const
ALIGN 2
filePath: WSTRING <C:\Temp\test123.txt>
.code
Main proc
sub rsp, 48h
mov qword ptr [rsp + 30h], 0
mov qword ptr [rsp + 28h], FILE_FLAG_DELETE_ON_CLOSE
mov qword ptr [rsp + 20h], CREATE_ALWAYS
xor r9, r9
mov r8, FILE_SHARE_READ
mov rdx, GENERIC_READ
lea rcx, filePath
call __imp_CreateFileW
cmp rax, INVALID_HANDLE_VALUE
je @@0
mov rcx, rax
call __imp_CloseHandle
@@0:
xor ecx, ecx
call __imp_ExitProcess
add rsp, 48h
ret
Main endp
end