Assembly x86_64 - CLI Arguements

Assembly Code

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.

Compiling

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.