Question

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?

Was it helpful?

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top