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: