1

code here:

void main()
{
    _exit(0);
}

By disassembling the main section:

 80483d4:   55                      push   %ebp
 80483d5:   89 e5                   mov    %esp,%ebp
 80483d7:   83 e4 f0                and    $0xfffffff0,%esp
 80483da:   83 ec 10                sub    $0x10,%esp
 80483dd:   c7 04 24 00 00 00 00    movl   $0x0,(%esp)
 80483e4:   e8 17 ff ff ff          call   8048300 <_exit@plt>

As I know, the way to make syscalls is using "int 0x80", but I can just find "call 8048300 exit@plt" here, so how can I change the gcc to let it compile syscalls in "int 0x80" way(I need my program call syscall in this way)?

Coaku
  • 977
  • 1
  • 9
  • 23
  • Why do you ask? What are you trying to achieve?? – Basile Starynkevitch Mar 27 '13 at 08:18
  • void main() is bogus on hosted implementations of C, a minor point relative to your overall question. Just nitpicking. – Randy Howard Mar 27 '13 at 08:24
  • @BasileStarynkevitch Cause I want to scan the assembly codes of my program to find where the callings to syscalls happens, so it's easier to detect when use "int $0x80". – Coaku Mar 27 '13 at 08:38
  • 1
    @Coaku If you want to see the exact system calls your program makes to the kernel via `int 0x80`, use a (binutils?) tool called `strace`. It shows you exact system calls with given parameters and return values and even interprets the errno's for you, if something goes wrong. For library calls you can use `ltrace`. – zxcdw Mar 27 '13 at 16:36
  • Why do you want to scan the assembly code of your program? If it is your program (and you have its source code) you should know when it is doing some syscalls. If it is a malicious arbitrary program, it could do syscalls thru VDSO without using `int $80` .... – Basile Starynkevitch Mar 27 '13 at 19:49

3 Answers3

3

You should compile with gcc -Wall (and also perhaps the -g flag).

This will give you more warnings, and will pin-point some easy mistakes, like the lack of appropriate #include

The exit(3) function is a library function (making atexit possible). The corresponding syscall is _exit(2), but on recent Linux exit is calling exit_group(2). So your example misses an #include <stdlib.h>

Current Linux implementations often do not use int 0x80 but go thru the VDSO or at least use SYSENTER or SYSCALL machine instructions. YMMV.

You could, as Jeremy answered, use asm ; (you might define your own headers for all the syscalls you are using, and having these syscalls be static inline functions doing some asm) beware that for other syscalls, you want to catch their failure and the errno error code.

Why are you asking?.... The libc (and its startup routines crt0.o ...) is doing complex tricks to call main...

See also this answer

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 1
    Thanks, but it's still not in "int $0x80" way by using `-Wall` and `-g`. Cause I want to scan the assembly codes of my program to find where the callings to syscalls happens. – Coaku Mar 27 '13 at 08:26
  • +1 for mentioning VDSO. @Coaku: Please read the links in this answer, they'll help you understand why you don't see `int $0x80` or `syscall` in your disassemblies. – us2012 Mar 27 '13 at 13:35
  • _exit(2) is a wrapper function. In my Debian OS, _exit() calls exit_group() = system call n. 231. Assembler code doesn't use "int 0x80" but "syscall" instruction. – Antonio Rizzo Apr 03 '15 at 21:33
2

For 32-bit

asm( "int $0x80" :: "a" (1), "b" (0) );

for 64-bit

asm( "syscall" :: "a" (60), "D" (0) );

You might also need this if you have declared your exit function with attribute noreturn.

__builtin_unreachable();
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
Jeremy
  • 304
  • 1
  • 6
  • Thanks, but how to use `__builtin_unreachable();`? – Coaku Mar 27 '13 at 08:39
  • exit() and _exit() are both declared with the "noreturn" attribute – Jeremy Mar 27 '13 at 08:52
  • __attribute__ ((noreturn)) enables certain optimizations. GCC knows nothing about the contents of asm() calls, so here you have informed it that the call does not return. Just place it after the asm call. – Jeremy Mar 27 '13 at 09:01
  • 1
    You will never normally see "int $0x80" in the GCC assembler output because all the Linux system calls are wrapped with small library calls. These library functions (read(), _exit(), close(), etc) usually (at least) choose the right call (32 or 64 bit versions perhaps), do the call, then process any errors and set errno. The library calls are of course portable and simple to use. The asm versions of _exit() above are simple only because they do not return and therefore have no error processing. Also "syscall" clobbers r11 and rcx which we also ignore for the same reason. – Jeremy Mar 27 '13 at 09:10
  • In the general case a `"memory"` clobber specification is required, this includes `_exit()` if `mmap` has been used with `MAP_SHARED`. – Timothy Baldwin Jan 20 '23 at 13:31
1

The system calls are wrapped by glibc, which should use whatever the underlying kernel uses. Linux switched away from the int 0x80 mechanism for performance a while back...

Why do you want to do system calls in an outdated way?

vonbrand
  • 11,412
  • 8
  • 32
  • 52