Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct constant for the exit system call?

I am trying to learn x86_64 assembly, and am using GCC as my assembler. The exact command I'm using is:

gcc -nostdlib tapydn.S -D__ASSEMBLY__

I'm mainly using gcc for its preprocessor. Here is tapydn.S:

.global _start

#include <asm-generic/unistd.h>

syscall=0x80

.text
_start:
    movl $__NR_exit, %eax
    movl $0x00, %ebx
    int  $syscall

This results in a segmentation fault. I believe the problem is with the following line:

 movl $__NR_exit, %eax

I used __NR_exit because it was more descriptive than some magic number. However, it appears that my usage of it is incorrect. I believe this to be the case because when I change the line in question to the following, it runs fine:

movl $0x01, %eax

Further backing up this trail of thought is the contents of usr/include/asm-generic/unistd.h:

#define __NR_exit 93
__SYSCALL(__NR_exit, sys_exit)

I expected the value of __NR_exit to be 1, not 93! Clearly I am misunderstanding its purpose and consequently its usage. For all I know, I'm getting lucky with the $0x01 case working (much like undefined behaviour in C++), so I kept digging...

Next, I looked for the definition of sys_exit. I couldn't find it. I tried using it anyway as follows (with and without the preceeding $):

movl $sys_exit, %eax

This wouldn't link:

/tmp/cc7tEUtC.o: In function `_start':
(.text+0x1): undefined reference to `sys_exit'
collect2: error: ld returned 1 exit status

My guess is that it's a symbol in one of the system libraries and I'm not linking it due to my passing -nostdlib to GCC. I'd like to avoid linking such a large library for just one symbol if possible.

In response to Jester's comment about mixing 32 and 64 bit constants, I tried using the value 0x3C as suggested:

movq $0x3C, %eax
movq $0x00, %ebx

This also resulting a segmentation fault. I also tried swapping out eax and ebx for rax and rbx:

movq $0x3C, %rax
movq $0x00, %rbx

The segmentation fault remained.

Jester then commented stating that I should be using syscall rather than int $0x80:

.global _start

#include <asm-generic/unistd.h>

.text
_start:
    movq $0x3C, %rax
    movq $0x00, %rbx
    syscall

This works, but I was later informed that I should be using rdi instead of rbx as per the System V AMD64 ABI:

movq $0x00, %rdi

This also works fine, but still ends up using the magic number 0x3C for the system call number.

Wrapping up, my questions are as follows:

  • What is the correct usage of __NR_exit?
  • What should I be using instead of a magic number for the exit system call?
like image 705
OMGtechy Avatar asked Jan 28 '17 21:01

OMGtechy


People also ask

What is exit () system call?

On many computer operating systems, a computer process terminates its execution by making an exit system call. More generally, an exit in a multithreading environment means that a thread of execution has stopped running. For resource management, the operating system reclaims resources (memory, files, etc.)

What is system call number?

A system call number is a unique integer (i.e., whole number), from one to around 256, that is assigned to each system call in a Unix-like operating system.

What is syscall int 0x80?

int 0x80 is the assembly language instruction that is used to invoke system calls in Linux on x86 (i.e., Intel-compatible) processors. An assembly language is a human-readable notation for the machine language that a specific type of processor (also called a central processing unit or CPU) uses.

What is the system call number for the exit system call on Kali 64 bit Linux?

The exit syscall is number 60 .


1 Answers

The correct header file to get the system call numbers is sys/syscall.h. The constants are called SYS_### where ### is the name of the system call you are interested in. The __NR_### macros are implementation details and should not be used. As a rule of thumb, if an identifier begins with an underscore it should not be used, if it begins with two it should definitely not be used. The arguments go into rdi, rsi, rdx, r10, r8, and r9. Here is a sample program for Linux:

#include <sys/syscall.h>

    .globl _start
_start:
    mov $SYS_exit,%eax
    xor %edi,%edi
    syscall

These conventions are mostly portable to other UNIX-like operating systems.

like image 145
fuz Avatar answered Oct 22 '22 00:10

fuz