Assembly Hello World – Making SLAE Progress!

Now that I’m making progress, I wanted to share the code and descriptions for assembly Hello World.

Assembly Hello World – Introduction

I’ve taken the SecurityTube Linux Assembly Expert (SLAE) course for the past few weeks, and I’m really enjoying it.

That means that I’ll definitely have a smattering of assembly posts in the works, so stay tuned!

This post will cover the Linux x86 assembly “Hello World” program, and a bit about how it works/debugging it.

Hello World – The Code

First, I’ll start by just sharing my final application code. It is very well commented, but I’ll also explain it a bit further below.

; HelloWorld.nasm
; Author: Ray Doyle

; Global identifier - identifies that "_start" is the entry point
global _start

; Text section - where the program code lives
section .text

; The entry point of the program
	; Print "Hello World!" on the screen

	; Move the value 4 into EAX (system call for write)
	mov eax, 4

	; Move the value 1 into EBX (fd1 = STDOUT)
	mov ebx, 1

	; Move the pointer to the string into ECX via its label
	mov ecx, message

	; Move the value 12 into EDX (length of "Hello World!")
	;mov edx, 12
	mov edx, mlen

	; Send an 0x80 interrupt to invoke the system call
	int 0x80

	; Exit the program gracefully
	; Move the value 1 into EAX (system call for exit)
	mov eax, 1

	; Move the value 5 into EBX (arbitrary value for exit status)
	mov ebx, 5

	; Send an 0x80 interrupt to invoke the system call
	int 0x80

; Data section - where all the initialized data is located
section .data
	; Defining and storing the "Hello World!" string
	; Label "message" used for this string
	; db = define byte or series of bytes
	message: db "Hello World!"

	; Define an mlen value that is equal to the length of message
	; This is a shortcut that NASM understands and computes
	mlen equ $-message

While this post/blog isn’t an assembly tutorial, there are a few things that I want to cover.

First, the .text section is where the actual application lives, and the .data section is where the application stores initialized data.

Next, the main method of printing “Hello World!” is to call the sys_write followed by the sys_exit syscalls. For more information on i386 Linux system calls, you can visit the following reference.

You load the parameters for system calls into EAX, EBX, ECX, and EDX in order.

For example, the sys_write syscall takes 3 parameters: unsigned int fd, char * buf, size_t count. In this case, I’m loading 4 into EAX (the number for sys_write), 1 into EBX (fd1 is STDOUT), my message variable (the actual character buffer) into ECX, and mlen (the calculated length of my string) into EDX.

Once the program has loaded all the registers, I make a call to interrupt 0x80. This is the most common method of making a syscall.

After my sys_write is called, I follow the same steps for sys_exit, so that the program exits cleanly.

Compiling, Linking, Running, and Debugging

Once I finished my program, it was time to get it executable.

First, I used NASM to compile the application into an object file.

Next, I used ld to link the object file into an actual executable.

Finally, I ran the application and verified the exit status (which I set as 5).

As you can see, this is fairly long for a “Hello World” program. That said, I wanted to add plenty of comments as I went along, so that I was sure that I understood it.

doyler@slae:~/slae/module1-4$ nasm -f elf32 -o HelloWorld.o HelloWorld.nasm 
doyler@slae:~/slae/module1-4$ ld -o HelloWorld HelloWorld.o
doyler@slae:~/slae/module1-4$ ./HelloWorld 
Hello World!
doyler@slae:~/slae/module1-4$ echo $?
doyler@slae:~/slae/module1-4$ wc -l HelloWorld.nasm 
54 HelloWorld.asm

Now that I had a working program, it was time to do some debugging.

As with most applications on Linux, I prefer to use GDB.

First, I set a breakpoint on the _start entry point of the application.

When the program hit my breakpoint, I took a quick look at the disassembly to verify that it was the same as what I wrote in my .nasm file.

Next, I took a quick look at the registers (i r = info registers) to verify where EIP was pointing and that the CPU had loaded 0x4 into EAX.

Finally, I looked at the string representation of the memory address that the program would load into ECX. As expected, this was my “Hello World!” string.

doyler@slae:~/slae/module1-4$ gdb -q HelloWorld
Reading symbols from /home/doyler/slae/module1-4/HelloWorld...(no debugging symbols found)...done.
(gdb) break _start
Breakpoint 1 at 0x8048080
(gdb) r
Starting program: /home/doyler/slae/module1-4/HelloWorld

Breakpoint 1, 0x08048080 in _start ()
(gdb) set disassembly-flavor intel
(gdb) disass
Dump of assembler code for function _start:
=> 0x08048080 <+0>:    mov    eax,0x4
   0x08048085 <+5>:    mov    ebx,0x1
   0x0804808a <+10>:    mov    ecx,0x80490a4
   0x0804808f <+15>:    mov    edx,0xc
   0x08048094 <+20>:    int    0x80
   0x08048096 <+22>:    mov    eax,0x1
   0x0804809b <+27>:    mov    ebx,0x5
   0x080480a0 <+32>:    int    0x80
End of assembler dump.
(gdb) stepi
0x08048085 in _start ()
(gdb) i r
eax            0x4    4
ecx            0x0    0
edx            0x0    0
ebx            0x0    0
esp            0xbffff3e0    0xbffff3e0
ebp            0x0    0x0
esi            0x0    0
edi            0x0    0
eip            0x8048085    0x8048085 <_start+5>
eflags         0x202    [ IF ]
cs             0x73    115
ss             0x7b    123
ds             0x7b    123
es             0x7b    123
fs             0x0    0
gs             0x0    0
(gdb) x/s 0x80490a4
0x80490a4 <message>:     "Hello World!"

Assembly Hello World – Conclusion

While assembly is definitely something newer to me, I’m really looking forward to this course.

I definitely have a few post ideas in mind, and that is not counting the SLAE final exam.

While these skills are only partially relevant to my current role, they should help a ton with my exploit development. I’ve already completed the GXPN, but I will be starting the OSCE once this course is over!

doyler on Githubdoyler on Twitter
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he's done it all. To show for it, he has obtained an OSCP, eCPPT, eWPT, eWPTX, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!

He currently serves as a Senior Penetration Testing Consultant for Secureworks. His previous position was a Senior Penetration Tester for a major financial institution.

When he's not figuring out what cert to get next (currently GXPN) or side project to work on, he enjoys playing video games, traveling, and watching sports.

Leave a Comment

Filed under Security Not Included

Leave a Reply

Your email address will not be published. Required fields are marked *


This site uses Akismet to reduce spam. Learn how your comment data is processed.