Как подготовить стек при вызове ExitProcess? - PullRequest
0 голосов
/ 03 марта 2019

Я пытаюсь узнать, как вызывать функции операционной системы в сборке, и разработал пример, который создаст, а затем закроет файл (удалив его при закрытии).Исследуя использование 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

1 Ответ

0 голосов
/ 03 марта 2019

обычная функция 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
...