We're going to use vim to write our code
[ 192.168.0.18/24 ] [ /dev/pts/88 ] [~/binexp/asm]
→ vim 6.asm
section .data
msg db 'Hello, world', 0xa ; our hello world string of text
len equ $ - msg ; the length of the msg variable
filename db 'test.txt', 0 ; the name of the file : test.txt
lenfilename equ $ - filename ; the length of the filename variable
fd dq 0 ;
section .text
global _start
_start:
mov rax, 2 ; syscall id 2 to open the file
mov rdi, filename
mov rsi, 0102o ;O_CREAT, man open
mov rdx, 0666o ; RW no X for root, group and user
syscall
mov [fd], rax
mov rax, 1 ;syscall id 1 to print text
mov rdi, [fd] ;file descriptor
mov rsi, msg ;message to write
mov rdx, len ;message length
syscall ;call kernel
mov rax, 3 ;syscall id 3 to close the file
mov rdi, [fd] ; value is 0
syscall
mov rax, 60 ;system call number (sys_exit)
syscall ;call kernel
Now let's inspect what's new in this code:
_start:
mov rax, 2 ; syscall id 2 to open the file
mov rdi, filename
mov rsi, 0102o ;O_CREAT, man open
mov rdx, 0666o ; RW no X for root, group and user
syscall
First we make use of the syscall id 2 (rax register) to open a file, the name is specified in the first arguement (rdi) , then for the 2nd arguement (rsi) , we open it with the O_CREAT flag, to create the file if it doesnt exist. For the 3rd arguement (rdx) we set the permissions to RW RW RW.
mov [fd], rax
mov rax, 1 ;syscall id 1 to print text
mov rdi, [fd] ;file descriptor
mov rsi, msg ;message to write
mov rdx, len ;message length
syscall ;call kernel
the file descriptor is returned by the open syscall (id 2) we used previously, so we just put it in the [fd] label to be able to use it later. Then we use the syscall id 1 (rax), first arg (rdi) is the file descriptor because we don't want to output our text to stdout nor stderr (2) we want it in the file. Next arguement (rsi) is the message to write and then rdx is the message length.
mov rax, 3 ;syscall id 3 to close the file
mov rdi, [fd]
syscall
mov rax, 60 ;system call number (sys_exit)
syscall ;call kernel
And then lastly we use the syscall id 3 to close the file, and it's first arguement is the file we previously opened. The last syscall that we use is the exit syscall to end the binary execution.
Here we're going to use nasm to compile our assembly code and then use ld to get the binary and execute it:
[ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm]
→ nasm -f elf64 6.asm -o 6.o
[ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm]
→ ld 6.o -o 6
[ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm]
→ ./6
[ 192.168.0.18/24 ] [ /dev/pts/8 ] [~/binexp/asm]
→ cat test.txt
Hello, world
And we see that we have been able to print out the Hello World text string inside of test.txt ! In the next tutorial we will check out a minimal shellcode used to spawn a /bin/sh shell. you can click here.