Nasm kernel32.dll Удалить файл

Хорошо, я попытался использовать метод DeleteFile из kernel32.dll (используя ассемблер nasm), но он не удаляет файл и завершает работу с ошибкой.

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

Он просто печатает Не удалось удалить файл и завершает работу. Есть ли в этом коде ошибка?


person user2821630    schedule 10.03.2014    source источник
comment
add esp, 8 для одного, и вы, кажется, не приводите аргумент.   -  person Jens Björnhager    schedule 10.03.2014
comment
Вы уверены, что правильно указали имя файла из командной строки? Я думаю, вам может понадобиться push [edx + 4] ... но я не работаю с Windows.   -  person Frank Kotler    schedule 10.03.2014


Ответы (1)


Если вы не связываетесь с библиотекой C (используя gcc или что-то подобное), программы Windows не имеют argc или argv, поэтому попытка доступа к параметрам с помощью esp не сработает. Вместо этого вам нужно использовать GetCommandLineW, который вернет указатель на строку командной строки для текущего процесса. Чтобы превратить это в argc и argv, вы затем используете CommandLineToArgvW. Да, версии Unicode. Вот пример, я использую printf, чтобы немного упростить отображение.

%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

И вывод:

введите здесь описание изображения

person Gunner    schedule 10.03.2014