Skip to content

Instantly share code, notes, and snippets.

@rahatzamancse
Created September 11, 2020 23:49
Show Gist options
  • Save rahatzamancse/7841079ae734490d260ebd7fbb1c641c to your computer and use it in GitHub Desktop.
Save rahatzamancse/7841079ae734490d260ebd7fbb1c641c to your computer and use it in GitHub Desktop.
Recast a simple C program's invocation of system calls from general glibc interface to x86_64 assembly language
global _start
section .text
_start:
mov rdi,0 ; result
mov rax,60 ; exit(2)
syscall
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
int main()
{
pid_t child_pid = fork();
pid_t return_pid = 0;
if(child_pid == 0)
{
// This is the child; it turns itself into /bin/ls via execve(2).
char *argv[] = {"/bin/pwd",NULL};
char *envp[] = {NULL};
execve(argv[0],argv,envp); // There is no return from successful execve(2)...
fprintf(stderr,"Oops, could not start /bin/ls!\n");
}
else
{
// This is the parent; it will wait for the child.
fprintf(stderr,"Waiting for process\n");
return_pid = wait(NULL);
}
printf("child_pid = %d, return_pid = %d\n",child_pid,return_pid);
// Exit the parent; /bin/ls takes care of the exit for the child process.
exit(0);
}
section .data
messages:
.1: db "Inside child process", 0xA, 0xD
.2: db "child_pid = "
.3: db ", return_pid = "
.4: db "\n",0
.1.length: equ messages.2-messages.1
.2.length: equ messages.3-messages.2
.3.length: equ messages.4-messages.3
.4.length: equ messages.1.length-messages.4
.5: db "Waiting for process",0xA, 0xD
.5.length: equ $ - messages.5
parameters:
.argv: db "/bin/ls", 0
.NULL db 0
variables:
.child_pid: dq 0
.return_pid: dq 0
section .text
global _start
_start:
; pid_t child_pid = fork()
mov rax, 57 ; system call number for "fork"
syscall ; system call
; rax has child_pid
mov qword[variables.child_pid], rax
test rax, rax ; if(child_pid == 0)
jnz parent_process
child_process:
; fprintf(stdout, "Inside child process")
mov rsi, messages.1
mov rdx, messages.1.length
call println
; execve(argv[0], argv, envp)
mov rax, 59
lea rdi, parameters.argv ; argv
mov rsi, parameters.argv ; argv[0]
mov rdx, parameters.NULL ; envp
syscall
jmp after_process
parent_process:
; fprintf(stdout, "Waiting for process")
mov rsi, messages.5
mov rdx, messages.5.length
call println
; return_pid = wait(NULL)
mov rax, 247 ; wait(NULL)
syscall ; rax has return_pid
mov qword[variables.return_pid], rax
after_process:
; exit(0)
mov rdi,0 ; result
mov rax,60 ; exit(2)
syscall
; Functions
println:
; This is basically printf function
; Prints the data from rsi with size rdx
; ssize_t write(int fd, const void *buf, size_t count)
mov rdi,1 ; fd
mov rax,1 ; write(2)
syscall
ret
fork:
build:
nasm -o fork_exec_wait_exit.o -f elf64 fork_exec_wait_exit.nasm
ld -e _start --stats -o fork_exec_wait_exit fork_exec_wait_exit.o
run: build
./fork_exec_wait_exit
clean:
rm -rf *.o fork_exec_wait_exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment