Basic file operations with NASM
anomit | April 17, 2008This is meant for NASM running on a linux machine. First things first: everything in UNIX is a file. A device is a file, a network socket is a file and everything else you can imagine is a file. Each file has a file descriptor attached to it. Some standard file descriptors are 0 for STDIN (standard input), 1 for STDOUT (standard output) and 2 for STDERR (standard error output). Since everything is a file, you can read() and write() on them provided you have the file descriptor.
read(), write() and open() are some of the very important syscalls in linux that would allow you to manipulate any file (that is, provided you have the permissions). There are some 150+ of them if you are really interested to find out. For syscalls, you need to pass the necessary parameters in the ebx, ecx, edx registers and so on, depending upon the number of parameters. You can also call libc functions by declaring them as extern printf for example and pushing the necessary parameters on the stack, the last parameter to be pushed first. To understand what kind of parameters need to be passed for the syscalls, read the developer man pages. Like man 2 write for write(). Use this for any other syscall like read() or open() and also keep the list of syscalls mentioned earlier in this post handy.
Regarding passing arguments to the program, they are stored in the stack as
-
argc
argv[0]
argv[1]
argv[2]
and so on…
argv[0] is the program name itself, so we can pop and discard it safely.
The following is a small program in NASM that takes a filename as an argument and reads 8kB from the file and displays it on the screen.
section .data buf times 8 db 0 bufsize db 8192 section .text global _start _start: pop ebx pop ebx pop ebx mov eax,5 mov ecx,2 ;the read mode int 80h test eax,eax jns file_read mov ebx,eax mov eax,1 int 80h ret file_read: mov ebx,eax ;move the file descriptor mov eax,3 ;3 for read() mov ecx,buf ;the buffer mov edx,bufsize ;the buffer size int 80h mov edx,eax ;move the number of bytes read from the previous syscall to edx mov eax,4 ;4 for write() mov ebx,1 ;1, the STDOUT file descriptor int 80h mov eax,1 mov ebx,0 int 80h ;exit with error code 0 ret
To assemble: nasm -f elf filename.asm
To link: ld -s -o executable-name filename.o
To know more about the read and write modes, the file descriptors and some increased masochistic behavior, start with reading the /usr/include/unistd.h and /usr/include/fcntl.h files. Poke around that directory for some more knowledge.






