Introduction
"Hello, World!" is one of the simplest computer program, it outputs "Hello, World!" on a display device. It is traditionally used to introduce beginners to a programming language.
During the last years the 32-bit architectures almost disappeared on modern CPUs, it has been replaced by 64-bit ones.
An assembly languages is often used for the optimization of size or performance, it is also necessary to understand it for software reverse engineering.
With a bigger register set, new instructions and a different calling convention, it has become harder to practice manual debugging or reverse engineering on complex x86-64 applications.
The Flat Assembler
The assembly language code in this article is specific to Fasm a language compiler for x86 and x86-64 processor.
You can download this software on the official Fasm website.
Hello world 64-bit
Today we present a simple Windows x64 standalone assembly program that pops up a MessageBox.
The Windows MessageBox
Windows function takes four arguments.MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
In x64 assembly, RCX
, RDX
, R8
, R9
are used for integer and pointer arguments in that order left to right. For an other function, additional arguments would be pushed on the stack.
The following program will use each of the registers seen previously to comply with the MessageBoxA
function.
format PE64 GUI
entry start
section '.text' code readable executable
start:
push rbp
mov rbp, rsp
xor rcx, rcx
lea rdx, [szText]
lea r8, [szCaption]
xor r9d, r9d
call [MessageBoxA]
xor rax, rax
leave
ret
section '.idata' import data readable
dd 0, 0, 0, RVA user32, RVA user_table
dd 0, 0, 0, 0, 0
user_table:
MessageBoxA dq RVA _MessageBoxA
dq 0
user32 db 'USER32.DLL', 0
_MessageBoxA dw 0
db 'MessageBoxA', 0
section '.rdata' data readable
szText db 0x77, 0x69, 0x72, 0x65, 0x6d, 0x61, 0x73, 0x6b, 0x00
szCaption db 'Hello, World!', 0
Hello world 32-bit
The "Hello World" program below can run on the 32-bit versions of Windows only.
format PE GUI
entry start
section '.text' code readable executable
start:
push ebp
mov ebp, esp
push 0
push szCaption
push szText
push 0
call [MessageBoxA]
xor eax, eax
leave
ret
section '.idata' import data readable
dd 0, 0, 0, RVA user32, RVA user_table
dd 0, 0, 0, 0, 0
user_table:
MessageBoxA dd RVA _MessageBoxA
dd 0
user32 db 'USER32.DLL', 0
_MessageBoxA dw 0
db 'MessageBoxA', 0
section '.rdata' data readable
szCaption db 0x77, 0x69, 0x72, 0x65, 0x6d, 0x61, 0x73, 0x6b, 0x00
szText db 'Hello, World!', 0