调用ExitProcess时应该如何准备堆栈?
How should one prepare the stack when calling 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
usual function (windows api) and must be called with common calling convention for x64. in particular stack must be maintained 16-byte aligned
所以像其他 api 一样调用 ExitProcess
。 call ExitProcess
之前的 add rsp, 48h
指令是错误的
还有一些一般注意事项:
导入的 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
我正在尝试学习如何在汇编中调用操作系统函数,并且已经得到了一个示例,该示例将创建并关闭一个文件(在关闭时删除该文件)。在研究 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
usual function (windows api) and must be called with common calling convention for x64. in particular stack must be maintained 16-byte aligned
所以像其他 api 一样调用 ExitProcess
。 call ExitProcess
之前的 add rsp, 48h
指令是错误的
还有一些一般注意事项:
导入的 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