CS444 Finding UNIX/Linux System Calls

Using linux1.cs.umb.edu, a 64-bit Linux system

 

Script started on Sun 09 Sep 2012 01:05:21 PM EDT
eoneil@vm22:~/444$ cat hi.c

int main(void)

{

    write(1, "hi!!!\n", 6);       Our tiny test program

    return 0;

}

eoneil@vm22:~/444$ gcc -g hi.c

eoneil@vm22:~/444$ gdb a.out

GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08

Copyright (C) 2011 Free Software Foundation, Inc.

License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law.  Type "show copying"

and "show warranty" for details.

This GDB was configured as "x86_64-linux-gnu".

For bug reporting instructions, please see:

<http://bugs.launchpad.net/gdb-linaro/>...

Reading symbols from /home/eoneil/444/a.out...done.

(gdb) disas main

Dump of assembler code for function main:                 Set up arguments in

   0x00000000004004f4 <+0>:     push   %rbp                  registers edx, esi, and edi

   0x00000000004004f5 <+1>:     mov    %rsp,%rbp          (lower halves of 64-bit regs rdx, rsi, rdi)

   0x00000000004004f8 <+4>:     mov    $0x6,%edx

   0x00000000004004fd <+9>:     mov    $0x40060c,%esi

   0x0000000000400502 <+14>:    mov    $0x1,%edi

   0x0000000000400507 <+19>:    mov    $0x0,%eax              Machine code for program

   0x000000000040050c <+24>:    callq  0x4003f0 <write@plt>

   0x0000000000400511 <+29>:    mov    $0x0,%eax

   0x0000000000400516 <+34>:    pop    %rbp

   0x0000000000400517 <+35>:    retq  

End of assembler dump.

(gdb) disas write

Dump of assembler code for function write@plt:          <---initial “write” sets up

                                                            dynamic linkage to C library

   0x00000000004003f0 <+0>:     jmpq   *0x200c0a(%rip)        # 0x601000 <write@got.plt>

   0x00000000004003f6 <+6>:     pushq  $0x0

   0x00000000004003fb <+11>:    jmpq   0x4003e0

End of assembler dump.

(gdb) b main                                            ß- set breakpoint at main

Breakpoint 1 at 0x4004f8: file hi.c, line 3.

(gdb) r                                                 <---start program

Starting program: /home/eoneil/444/a.out

 

Breakpoint 1, main () at hi.c:3                         <---hit breakpoint at main

3           write(1, "hi!!!\n", 6);

(gdb) disas write

Dump of assembler code for function write:          <--now “write” is in high memory! (DLL)

   0x00007ffff7b108e0 <+0>:     cmpl   $0x0,0x2ca78d(%rip)        # 0x7ffff7ddb074

   0x00007ffff7b108e7 <+7>:     jne    0x7ffff7b108f9 <write+25>

   0x00007ffff7b108e9 <+9>:     mov    $0x1,%eax

   0x00007ffff7b108ee <+14>:    syscall                  ßsyscall instruction

   0x00007ffff7b108f0 <+16>:    cmp    $0xfffffffffffff001,%rax

   0x00007ffff7b108f6 <+22>:    jae    0x7ffff7b10929 <write+73>

   0x00007ffff7b108f8 <+24>:    retq  

   0x00007ffff7b108f9 <+25>:    sub    $0x8,%rsp

End of assembler dump.

(gdb) b write

Breakpoint 2 at 0x7ffff7b108e0

(gdb) c

Continuing.

 

Breakpoint 2, 0x00007ffff7b108e0 in write () from /lib/x86_64-linux-gnu/libc.so.6

 

(gdb) i reg

rax            0x0      0

rbx            0x0      0

rcx            0x400520 4195616

rdx            0x6      6

rsi            0x40060c 4195852           arguments to write in regs rdx, rsi, rdi

rdi            0x1      1

rbp            0x7fffffffe6e0   0x7fffffffe6e0

rsp            0x7fffffffe6d8   0x7fffffffe6d8    ß stack pointer

r15            0x0      0

rip            0x7ffff7b108e0   0x7ffff7b108e0 <write>   ß instruction pointer

eflags         0x206    [ PF IF ]

cs             0x33     51

 (gdb) x/s $rsi                       ßcheck string at address in rsi

0x40060c:        "hi!!!\n"

(gdb) si                              ßsingle instruction step

0x00007ffff7b108e7 in write () from /lib/x86_64-linux-gnu/libc.so.6

(gdb)                                 ß <cr> repeats previous command in gdb

0x00007ffff7b108e9 in write () from /lib/x86_64-linux-gnu/libc.so.6

(gdb)

0x00007ffff7b108ee in write () from /lib/x86_64-linux-gnu/libc.so.6

(gdb)

hi!!!                                 ß syscall write execution

0x00007ffff7b108f0 in write () from /lib/x86_64-linux-gnu/libc.so.6

(gdb)

0x00007ffff7b108f6 in write () from /lib/x86_64-linux-gnu/libc.so.6

How the program exits after completing main:

 The system call “exit” causes this process to shut down  

 Look at the C library routine that contains syscall exit:

(gdb) disas _exit

Dump of assembler code for function _exit:

   0x00007ffff7aea570 <+0>:     movslq %edi,%rdx

   0x00007ffff7aea573 <+3>:     mov    0x2ea89e(%rip),%r9        # 0x7ffff7dd4e18

   0x00007ffff7aea593 <+35>:    mov    %esi,%eax

   0x00007ffff7aea595 <+37>:    syscall               ßthe exit syscall instruction

   0x00007ffff7aea597 <+39>:    cmp    $0xfffffffffffff000,%rax

   0x00007ffff7aea59d <+45>:    ja     0x7ffff7aea5b8 <_exit+72>

End of assembler dump.

    

 (gdb) b _exit                 ß set breakpoint at C library routine containing syscall exit

Breakpoint 3 at 0x00007ffff7adabe0

(gdb) c

Continuing.

 

Breakpoint 3, 0x00007ffff7adabe0 in _exit () from /lib/x86_64-linux-gnu/libc.so.6

(gdb) where           ß Look at the call stack to see how the program got here

#0  0x00007ffff7adabe0 in _exit () from /lib/x86_64-linux-gnu/libc.so.6

#1  0x00007ffff7a56960 in ?? () from /lib/x86_64-linux-gnu/libc.so.6

#2  0x00007ffff7a56985 in exit () from /lib/x86_64-linux-gnu/libc.so.6

#3  0x00007ffff7a3c774 in __libc_start_main () from /lib/x86_64-linux-gnu/libc.so.6

#4  0x0000000000400439 in _start ()

End of assembler dump.

The story: the program was running “start”, called libc_start_main, which called main, and when main returned, libc_start_main called exit, which called _exit to actually destroy itself via the exit system call.

The moral: There is a “C startup routine” that calls main, and after main returns, calls the C library exit function, which calls the system call exit.

You can use si about 7 times to see the final exit report by gdb

 

 [Inferior 1 (process 8291) exited normally]   ßexecution of exit syscall

(gdb)

The program is not being run.

(gdb) q