Kittoes0124
Kittoes0124

Reputation: 5080

How should one prepare the stack when calling ExitProcess?

I'm trying to learn how to invoke operating system functions in assembly and have gotten an example worked out that will create and then close a file (deleting it file on close). While researching the usage of ExitProcess I came across some example that clean up the stack and some that don't; even more confusing is that things seem to work with or without a clean up step...

What is the proper way to handle the stack in this situation?

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

Upvotes: 2

Views: 1389

Answers (1)

RbMm
RbMm

Reputation: 33804

the ExitProcess usual function (windows api) and must be called with common calling convention for x64. in particular stack must be maintained 16-byte aligned so call ExitProcess like any other api. the add rsp, 48h instruction before call ExitProcess is wrong

also some general notes: the imported api always called indirect - if you want call SomeApi - declare variable (code for x64)

extern __imp_SomeApi : QWORD

and call

call __imp_SomeApi

if we declare

extern SomeApi : proc

and do

call SomeApi

the linker create stub

SomeApi:
jmp  qword ptr __imp_SomeApi

so better direct use __imp_SomeApi form.

also always much better use W instead A api form. so all code can look like

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

Upvotes: 4

Related Questions