Skip to content

Instantly share code, notes, and snippets.

@maxdeliso
Created October 12, 2012 21:43
Show Gist options
  • Save maxdeliso/3881704 to your computer and use it in GitHub Desktop.
Save maxdeliso/3881704 to your computer and use it in GitHub Desktop.
win32 console mode hello, world in assembly
probe: probe.o makefile.mvc
link /nologo /entry:probe /out:probe.exe /subsystem:console kernel32.lib probe.obj /verbose:lib
probe.o: probe.asm makefile.mvc
nasm -fwin32 -o probe.obj probe.asm
clean:
erase /f /q probe.obj probe.exe
global probe
extern _GetCurrentProcess@0
extern _GetStdHandle@4
extern _CloseHandle@4
extern _ReadConsoleA@20
extern _WriteConsoleA@20
extern _TerminateProcess@8
section .text
probe:
; create main stack frame
push ebp
mov ebp, esp
sub esp, 0x14 ; allocate space for 6 dwords
mov [ebp - 0x0c], dword 0 ; default return code
push dword STD_INPUT_HANDLE
call _GetStdHandle@4 ; acquire stdin handle
cmp eax, INVALID_HANDLE_VALUE
je .stdHandleAcquireFailure
mov [ebp - 0x04], eax ; store stdin handle
push dword STD_OUTPUT_HANDLE
call _GetStdHandle@4 ; acquire stdout handle
cmp eax, INVALID_HANDLE_VALUE
je .stdHandleAcquireFailure
mov [ebp - 0x08], eax ; store stdout handle
;; WriteConsoleA
push dword 0 ; NULL param
mov edx, ebp
sub edx, 0x10
push edx ; ebp - 0x08, local #5, #b written
push dword PROBE_STARTUP_MSGLEN ; msg length pointer
push dword PROBE_STARTUP_MSG ; msg length
mov eax, dword [ebp - 0x08] ; load stdout from main frame
push eax ; push it to the stack
call _WriteConsoleA@20 ; write the startup message
;; TODO: check return
;; ReadConsoleA
push dword 0 ; NULL param
mov edx, ebp
sub edx, 0x10
push edx ; ebp - 0x08, local #5, #b read
push dword 1 ; read just 1 byte
mov edx, ebp
sub edx, 0x14
push edx ; address of buffer to write it to
mov eax, [ebp - 0x04]
push eax ; ebp - 0x04, stdin handle
call _ReadConsoleA@20 ; read a byte from stderr
;; TODO: check return
; poke nt and request termination
.exit:
call _GetCurrentProcess@0 ; returns pseudohandle in eax
mov edx, dword [ebp - 0x10] ; retrieve return code from stack
push edx ; push return code onto stack
push eax ; push pseudohandle onto stack
call _TerminateProcess@8 ; poke
; if terminate process succeeds, hang ...
test eax, eax
jz .exit.return
.exit.hang: jmp .exit.hang ; this is needed because terminate
; process is asynchronous. MSDN
; suggests a call to wait on the
; process handle but that's overkill
; in this case
; ... clean up the stack and return
.exit.return:
add esp, 0x14
pop ebp
ret
.stdHandleAcquireFailure:
mov [esp], dword HANDLE_ACQUIRE_FAIL
jmp .exit
.stdHandleCloseFailure:
mov [esp], dword HANDLE_CLOSE_FAIL
jmp .exit
section .rodata
; windows constants
INVALID_HANDLE_VALUE equ -1
STD_INPUT_HANDLE equ -10
STD_OUTPUT_HANDLE equ -11
STD_ERROR_HANDLE equ -12
; probe constants
HANDLE_ACQUIRE_FAIL equ 1
HANDLE_CLOSE_FAIL equ 2
PROBE_STARTUP_MSG: db 'hello, world', 0
PROBE_STARTUP_MSGLEN: equ $-PROBE_STARTUP_MSG
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment