Search code examples
assemblynasmkernel32

Nasm kernel32.dll DeleteFile


Alright, I tried to use DeleteFile method from kernel32.dll (using nasm assembler), but it doesn't deletes the file, and it exits with error.

extern _GetStdHandle@4
extern _WriteConsoleA@20
extern _DeleteFileA@4
extern _ExitProcess@4

section .data
    msg: db "Could not delete the file", 10, 0
    len: equ $- msg

section .bss
    numCharsWritten resb 1

section .text
    global _start

    _start:
        mov edx, [esp+8]
        push dword [edx]            ; pushes argument.
        call _DeleteFileA@4         ; deletes file

        add esp, 8                  ; removes 2 arguments

        cmp eax, 0                  ; <cmp> = (eax == 0)
        je _error                   ; if(<cmp>) jump to _error

        push dword 0x0A             ; exit value
        call _ExitProcess@4         ; exit

    _error:
        push dword -0x0B
        call _GetStdHandle@4

        push dword 0                ; Arg4, unused
        push numCharsWritten        ; Arg3, POINTER to numCharsWritten
        push dword len              ; Arg2, length of the string
        push msg                    ; Arg1, the string
        push eax                    ; Arg0, _GetStdHandle@4
        call _WriteConsoleA@20      ; Writes the string

        push dword 0x0A             ; exit code
        call _ExitProcess@4         ; exit

It just prints Could not delete the file, and exits. Does this code has error?


Solution

  • Unless you are linking against the C Library (using gcc or something similar), Windows Programs do not have an argc or argv so trying to access the params with esp will not work. Instead, you need to use GetCommandLineW which will return a pointer to the command line string for the current process. To turn that into argc and argv, you then use CommandLineToArgvW. Yes, the Unicode versions. Here is an example, I use printf to make displaying a bit easier.

    %define     STD_OUTPUT_HANDLE -11
    
    ; Shell32.dll
    extern  CommandLineToArgvW
    
    ; Kernel32.dll
    extern ExitProcess, WriteConsoleW, LocalFree
    extern GetStdHandle, GetCommandLineW
    %define GetCommandLine GetCommandLineW
    
    ;  msvcrt.dll
    extern _printf
    
    section .bss
    stdout          resd 1
    szArglist       resd 1
    nArgs           resd 1
    
    section .data
    fmtst     db  "%ws", 13, 10, 0
    
    section .text
    global _start
    
    _start:
        push    STD_OUTPUT_HANDLE
        call    GetStdHandle
        mov     dword [stdout], eax
    
        call    GetCommandLine
    
        push    nArgs
        push    eax
        call    CommandLineToArgvW
        mov     dword [szArglist], eax
        mov     esi, eax
        xor     ebx, ebx
        sub     dword [nArgs], 1
    
    .DisplayArgs:
        push    dword [esi + 4 * ebx]
        push    fmtst
        call    _printf
        add     esp, 4 * 2
    
        inc     ebx
        cmp     ebx, dword [nArgs]
        jle     .DisplayArgs
    
        push    dword [szArglist]
        call    LocalFree
    
        push    0
        call    ExitProcess
    

    And the output:

    enter image description here