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