2009年9月9日 星期三

How to get some information about dynamic linking using gdb

寫一個範例程式hello-loop.c該程式執行一個while-loop, loop內printf ""Hello World...\n"在用以下的方式觀察該程式的一些information:

(1) 用gdb 去attach hello-loop的process
(2) 在gdb模式下disassemble main, 可看到hello-loop 的printf 是執行PLT (procedure linkage table) (.plt section)中的"puts" code (call 0x80482d4 ), "objdump -D hello-loop | grep puts@plt -A3"可以看到該code :

080482d4 :
80482d4: ff 25 a0 95 04 08 jmp *0x80495a0
80482da: 68 10 00 00 00 push $0x10
80482df: e9 c0 ff ff ff jmp 80482a4 <_init+0x30>

在gdb模式下可以用下面方式看到:

(gdb) disassemble 0x80482d4
Dump of assembler code for function puts@plt:
0x080482d4 : jmp *0x80495a0
0x080482da : push $0x10
0x080482df : jmp 0x80482a4 <_init+48>
End of assembler dump.

之後他會jump到GOT (global offset table)的地方,當hello-loop在執行時會由dynamic linker (ld-linux.so)在0x80495a0 of GOT位置填入puts 的entry point 位置,GOT每一個entry代表一個位置(value of symbol),所以gdb反組entry為指令,該指令是沒有意義的。所以用"print/x *0x80495a0"來取得puts的process space中的位置(0xb7eaa5e0) ,我們再"disassemble 0xb7eaa5e0"就可以看到puts的code

(gdb) disassemble 0x80495a0
Dump of assembler code for function _GLOBAL_OFFSET_TABLE_:
0x0804958c <_global_offset_table_+0>: mov $0x68080494,%eax
0x08049591 <_global_offset_table_+5>: push %ss
0x08049592 <_global_offset_table_+6>: (bad)
0x08049593 <_global_offset_table_+7>: mov $0xd0,%bh
0x08049595 <_global_offset_table_+9>: xchg %eax,%edx
0x08049596 <_global_offset_table_+10>: std
0x08049597 <_global_offset_table_+11>: mov $0xba,%bh
0x08049599 <_global_offset_table_+13>: (bad)
0x0804959a <_global_offset_table_+14>: add $0x8,%al
0x0804959c <_global_offset_table_+16>: jo 0x80495a1 <_global_offset_table_+21>
0x0804959e <_global_offset_table_+18>: out %al,$0xb7
0x080495a0 <_global_offset_table_+20>: loopne 0x8049547 <_dynamic+143>
0x080495a2 <_global_offset_table_+22>: ljmp $0x0,$0xb7
End of assembler dump.
(gdb) print/x *0x80495a0
$2 = 0xb7eaa5e0
(gdb) disa
disable disassemble
(gdb) disassemble 0xb7eaa5e0
Dump of assembler code for function puts:
0xb7eaa5e0 : push %ebp
0xb7eaa5e1 : mov %esp,%ebp
0xb7eaa5e3 : sub $0x2c,%esp
0xb7eaa5e6 : mov %ebx,-0xc(%ebp)
.....


(3)Linux上user process的address space layout:

kernel virtual memory(code, data, heap, stack):0xc000_0000~0xffff_ffff
user stack(created at runtime):0xbfff_ffff~ (Runtime stack 8 Mb limit , 由高位置往低位置長)
run-time heap of shared libraries:[end address of shared libraries loaded into memory]+1~[注意不要與user stack overlay ]
memory mapped region for shared libraries:0x4000_0000~[end address of shared libraries loaded into memory]
run-time heap(managed by malloc, brk area, 由低位置往高位置長):[end address of executable file loaded into memory]+1~0x3fff_ffff
executable file loaded into memory:0x0804_8000~[end address of executable file loaded into memory]

executable file loaded into memory=read-only segment(.init, .text, .rodata)+read/write segment(.data, .bss)

> cat /proc/`pgrep hello-loop`/maps
08048000-08049000 r-xp 00000000 08:06 132930 /home/qustion/Samsung/hello/hello-loop
08049000-0804a000 rw-p 00000000 08:06 132930 /home/qustion/Samsung/hello/hello-loop
b7e49000-b7e4a000 rw-p b7e49000 00:00 0
b7e4a000-b7f9f000 r-xp 00000000 08:01 372164 /lib/i686/cmov/libc-2.7.so
b7f9f000-b7fa0000 r--p 00155000 08:01 372164 /lib/i686/cmov/libc-2.7.so
b7fa0000-b7fa2000 rw-p 00156000 08:01 372164 /lib/i686/cmov/libc-2.7.so
b7fa2000-b7fa5000 rw-p b7fa2000 00:00 0
b7fc2000-b7fc5000 rw-p b7fc2000 00:00 0
b7fc5000-b7fc6000 r-xp b7fc5000 00:00 0 [vdso]
b7fc6000-b7fe0000 r-xp 00000000 08:01 811869 /lib/ld-2.7.so
b7fe0000-b7fe2000 rw-p 0001a000 08:01 811869 /lib/ld-2.7.so
bfdcc000-bfde1000 rw-p bffeb000 00:00 0 [stack]


(4)
利用bt(backtrace)來列出calling flow, 我們可以看到0xb7fc5424(__kernel_vsyscall)是vdso(Virtual DSO,virtual system call, linux-gate.so.1)的entry point address:

(gdb)bt
#0 0xb7fc5424 in __kernel_vsyscall ()
#1 0xb7f1a263 in write () from /lib/i686/cmov/libc.so.6
#2 0xb7eb3d6c in _IO_file_write () from /lib/i686/cmov/libc.so.6
#3 0xb7eb4ee7 in _IO_do_write () from /lib/i686/cmov/libc.so.6
#4 0xb7eb4895 in _IO_file_overflow () from /lib/i686/cmov/libc.so.6
#5 0xb7eb7713 in __overflow () from /lib/i686/cmov/libc.so.6
#6 0xb7eaa746 in puts () from /lib/i686/cmov/libc.so.6
#7 0x080483c1 in main () at hello-loop.c:8

> cat /proc/`pgrep hello-loop`/maps
08048000-08049000 r-xp 00000000 08:06 132930 /home/qustion/Samsung/hello/hello-loop
08049000-0804a000 rw-p 00000000 08:06 132930 /home/qustion/Samsung/hello/hello-loop
b7e49000-b7e4a000 rw-p b7e49000 00:00 0
b7e4a000-b7f9f000 r-xp 00000000 08:01 372164 /lib/i686/cmov/libc-2.7.so
b7f9f000-b7fa0000 r--p 00155000 08:01 372164 /lib/i686/cmov/libc-2.7.so
b7fa0000-b7fa2000 rw-p 00156000 08:01 372164 /lib/i686/cmov/libc-2.7.so
b7fa2000-b7fa5000 rw-p b7fa2000 00:00 0
b7fc2000-b7fc5000 rw-p b7fc2000 00:00 0
b7fc5000-b7fc6000 r-xp b7fc5000 00:00 0 [vdso]
b7fc6000-b7fe0000 r-xp 00000000 08:01 811869 /lib/ld-2.7.so
b7fe0000-b7fe2000 rw-p 0001a000 08:01 811869 /lib/ld-2.7.so
bfdcc000-bfde1000 rw-p bffeb000 00:00 0 [stack]


>sudo ldd ./hello-loop
linux-gate.so.1 => (0xb7fd6000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7e5b000)
/lib/ld-linux.so.2 (0xb7fd7000)



(5)也可以利用gdb先產生program的process core dump file,再利用該core dump file做debug動作
(gdb) attach 31293
(gdb) generate-core-file
Saved corefile core.31293
(gdb)quit
gdb ./hello-loop core.31293




(6)詳細執行步驟:

>cat hello-loop.c
#include
#include
int main(int argc, char **argv)
{

while (1) {

printf("Hello World...\n");
}
return 0;
}
>gcc -v -Wall -g -o hello-loop hello-loop.c
>sudo ldd ./hello-loop
>./hello-loop

open another console

> pidof hello-loop
5621
>gdb
(gdb) attach 5621
Attaching to process 5621
Reading symbols from /home/qustion/Samsung/hello/hello-loop...done.
Reading symbols from /lib/i686/cmov/libc.so.6...done.
Loaded symbols for /lib/i686/cmov/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
0xb7fc5424 in __kernel_vsyscall ()
(gdb)bt
#0 0xb7fc5424 in __kernel_vsyscall ()
#1 0xb7f1a263 in write () from /lib/i686/cmov/libc.so.6
#2 0xb7eb3d6c in _IO_file_write () from /lib/i686/cmov/libc.so.6
#3 0xb7eb4ee7 in _IO_do_write () from /lib/i686/cmov/libc.so.6
#4 0xb7eb4895 in _IO_file_overflow () from /lib/i686/cmov/libc.so.6
#5 0xb7eb7713 in __overflow () from /lib/i686/cmov/libc.so.6
#6 0xb7eaa746 in puts () from /lib/i686/cmov/libc.so.6
#7 0x080483c1 in main () at hello-loop.c:8
(gdb) disassemble main
Dump of assembler code for function main:
0x080483a4 : lea 0x4(%esp),%ecx
0x080483a8 : and $0xfffffff0,%esp
0x080483ab : pushl -0x4(%ecx)
0x080483ae : push %ebp
0x080483af : mov %esp,%ebp
0x080483b1 : push %ecx
0x080483b2 : sub $0x4,%esp
0x080483b5 : movl $0x8048490,(%esp)
0x080483bc : call 0x80482d4
0x080483c1 : jmp 0x80483b5
End of assembler dump.
(gdb) disassemble 0x80482d4
Dump of assembler code for function puts@plt:
0x080482d4 : jmp *0x80495a0
0x080482da : push $0x10
0x080482df : jmp 0x80482a4 <_init+48>
End of assembler dump.
(gdb) disassemble 0x80495a0
Dump of assembler code for function _GLOBAL_OFFSET_TABLE_:
0x0804958c <_global_offset_table_+0>: mov $0x68080494,%eax
0x08049591 <_global_offset_table_+5>: push %ss
0x08049592 <_global_offset_table_+6>: (bad)
0x08049593 <_global_offset_table_+7>: mov $0xd0,%bh
0x08049595 <_global_offset_table_+9>: xchg %eax,%edx
0x08049596 <_global_offset_table_+10>: std
0x08049597 <_global_offset_table_+11>: mov $0xba,%bh
0x08049599 <_global_offset_table_+13>: (bad)
0x0804959a <_global_offset_table_+14>: add $0x8,%al
0x0804959c <_global_offset_table_+16>: jo 0x80495a1 <_global_offset_table_+21>
0x0804959e <_global_offset_table_+18>: out %al,$0xb7
0x080495a0 <_global_offset_table_+20>: loopne 0x8049547 <_dynamic+143>
0x080495a2 <_global_offset_table_+22>: ljmp $0x0,$0xb7
End of assembler dump.
(gdb) disassemble 0xb7eaa5e0
Dump of assembler code for function puts:
0xb7eaa5e0 : push %ebp
0xb7eaa5e1 : mov %esp,%ebp
0xb7eaa5e3 : sub $0x2c,%esp
0xb7eaa5e6 : mov %ebx,-0xc(%ebp)
0xb7eaa5e9 : mov 0x8(%ebp),%eax
0xb7eaa5ec : call 0xb7e6028f <_unwind_find_fde@plt+119>
0xb7eaa5f1 : add $0xf6a03,%ebx
0xb7eaa5f7 : mov %esi,-0x8(%ebp)
0xb7eaa5fa : mov %edi,-0x4(%ebp)
0xb7eaa5fd : mov %eax,(%esp)
0xb7eaa600 : call 0xb7ec0380
0xb7eaa605 : mov 0x86c(%ebx),%edx
0xb7eaa60b : cmpw $0x0,(%edx)
0xb7eaa60f : mov %edx,-0x10(%ebp)
0xb7eaa612 : mov %eax,-0x14(%ebp)
0xb7eaa615 : js 0xb7eaa66a
0xb7eaa617 : mov 0x48(%edx),%ecx
0xb7eaa61a : mov %gs:0x8,%edi
0xb7eaa621 : cmp %edi,0x8(%ecx)
0xb7eaa624 : mov %ecx,-0x18(%ebp)
0xb7eaa627 : je 0xb7eaa663
0xb7eaa629 : mov %ecx,%esi
---Type to continue, or q to quit---
0xb7eaa62b : xor %eax,%eax
0xb7eaa62d : movl $0x0,-0x20(%ebp)
0xb7eaa634 : mov $0x1,%ecx
0xb7eaa639 : movl $0x1,-0x1c(%ebp)
0xb7eaa640 : cmpl $0x0,%gs:0xc
0xb7eaa648 : je 0xb7eaa64b
0xb7eaa64a : lock cmpxchg %ecx,(%esi)
0xb7eaa64e : jne 0xb7eaa7ac
0xb7eaa654 : mov 0x48(%edx),%eax
0xb7eaa657 : mov 0x86c(%ebx),%edx
0xb7eaa65d : mov %edi,0x8(%eax)
0xb7eaa660 : mov %eax,-0x18(%ebp)
0xb7eaa663 : mov -0x18(%ebp),%eax
0xb7eaa666 : addl $0x1,0x4(%eax)
0xb7eaa66a : cmpb $0x0,0x46(%edx)
0xb7eaa66e : je 0xb7eaa708
0xb7eaa674 : movsbl 0x46(%edx),%eax
0xb7eaa678 : mov -0x14(%ebp),%ecx
0xb7eaa67b : mov 0x8(%ebp),%esi
0xb7eaa67e : mov 0x94(%edx,%eax,1),%eax
0xb7eaa685 : mov %ecx,0x8(%esp)
0xb7eaa689 : mov %esi,0x4(%esp)
0xb7eaa68d : mov %edx,(%esp)
---Type to continue, or q to quit---
0xb7eaa690 : call *0x1c(%eax)
0xb7eaa693 : cmp -0x14(%ebp),%eax
0xb7eaa696 : mov %eax,%esi
0xb7eaa698 : je 0xb7eaa6e8
0xb7eaa69a : mov $0xffffffff,%ecx
0xb7eaa69f : mov -0x10(%ebp),%esi
0xb7eaa6a2 : cmpw $0x0,(%esi)
0xb7eaa6a6 : js 0xb7eaa6d8
0xb7eaa6a8 : mov 0x48(%esi),%edx
0xb7eaa6ab : mov 0x4(%edx),%eax
0xb7eaa6ae : sub $0x1,%eax
0xb7eaa6b1 : test %eax,%eax
0xb7eaa6b3 : mov %eax,0x4(%edx)
0xb7eaa6b6 : jne 0xb7eaa6d8
0xb7eaa6b8 : movl $0x0,0x8(%edx)
0xb7eaa6bf : cmpl $0x0,%gs:0xc
0xb7eaa6c7 : je 0xb7eaa6ca
0xb7eaa6c9 : lock subl $0x1,(%edx)
0xb7eaa6cd : jne 0xb7eaa7b8
0xb7eaa6d3 : nop
0xb7eaa6d4 : lea 0x0(%esi,%eiz,1),%esi
0xb7eaa6d8 : mov -0xc(%ebp),%ebx
0xb7eaa6db : mov %ecx,%eax
---Type to continue, or q to quit---
0xb7eaa6dd : mov -0x8(%ebp),%esi
0xb7eaa6e0 : mov -0x4(%ebp),%edi
0xb7eaa6e3 : mov %ebp,%esp
0xb7eaa6e5 : pop %ebp
0xb7eaa6e6 : ret
0xb7eaa6e7 : nop
0xb7eaa6e8 : mov 0x86c(%ebx),%edx
0xb7eaa6ee : mov 0x14(%edx),%eax
0xb7eaa6f1 : cmp 0x18(%edx),%eax
0xb7eaa6f4 : jae 0xb7eaa736
0xb7eaa6f6 : movb $0xa,(%eax)
0xb7eaa6f9 : add $0x1,%eax
0xb7eaa6fc : mov %eax,0x14(%edx)
0xb7eaa6ff : lea 0x1(%esi),%ecx
0xb7eaa702 : jmp 0xb7eaa69f
0xb7eaa704 : lea 0x0(%esi,%eiz,1),%esi
0xb7eaa708 : mov -0xf0(%ebx),%eax
0xb7eaa70e : test %eax,%eax
0xb7eaa710 : jne 0xb7eaa758
0xb7eaa712 : movl $0xffffffff,0x4(%esp)
0xb7eaa71a : mov %edx,(%esp)
0xb7eaa71d : call 0xb7eafb10
0xb7eaa722 : add $0x1,%eax
---Type to continue, or q to quit---
0xb7eaa725 : jne 0xb7eaa69a
0xb7eaa72b : mov 0x86c(%ebx),%edx
0xb7eaa731 : jmp 0xb7eaa674
0xb7eaa736 : movl $0xa,0x4(%esp)
0xb7eaa73e : mov %edx,(%esp)
0xb7eaa741 : call 0xb7eb76c0 <__overflow>
0xb7eaa746 : add $0x1,%eax
0xb7eaa749 : je 0xb7eaa69a
0xb7eaa74f : jmp 0xb7eaa6ff
0xb7eaa751 : lea 0x0(%esi,%eiz,1),%esi
0xb7eaa758 : mov 0x68(%edx),%eax
0xb7eaa75b : test %eax,%eax
0xb7eaa75d : lea 0x0(%esi),%esi
0xb7eaa760 : jne 0xb7eaa722
0xb7eaa762 : movl $0xffffffff,0x68(%edx)
0xb7eaa769 : lea 0x0(%esi,%eiz,1),%esi
0xb7eaa770 : jmp 0xb7eaa72b
0xb7eaa772 : mov %eax,%ecx
0xb7eaa774 : mov -0x10(%ebp),%eax
0xb7eaa777 : cmpw $0x0,(%eax)
0xb7eaa77b : js 0xb7eaa7a4
0xb7eaa77d : mov 0x48(%eax),%edx
0xb7eaa780 : mov 0x4(%edx),%eax
---Type to continue, or q to quit---
0xb7eaa783 : sub $0x1,%eax
0xb7eaa786 : test %eax,%eax
0xb7eaa788 : mov %eax,0x4(%edx)
0xb7eaa78b : jne 0xb7eaa7a4
0xb7eaa78d : movl $0x0,0x8(%edx)
0xb7eaa794 : cmpl $0x0,%gs:0xc
0xb7eaa79c : je 0xb7eaa79f
0xb7eaa79e : lock subl $0x1,(%edx)
0xb7eaa7a2 : jne 0xb7eaa7c4
0xb7eaa7a4 : mov %ecx,(%esp)
0xb7eaa7a7 : call 0xb7e608b0
End of assembler dump.

open another console

>sudo ldd ./hello-loop
linux-gate.so.1 => (0xb7fd6000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7e5b000)
/lib/ld-linux.so.2 (0xb7fd7000)
> cat /proc/`pgrep hello-loop`/maps
08048000-08049000 r-xp 00000000 08:06 132930 /home/qustion/Samsung/hello/hello-loop
08049000-0804a000 rw-p 00000000 08:06 132930 /home/qustion/Samsung/hello/hello-loop
b7e49000-b7e4a000 rw-p b7e49000 00:00 0
b7e4a000-b7f9f000 r-xp 00000000 08:01 372164 /lib/i686/cmov/libc-2.7.so
b7f9f000-b7fa0000 r--p 00155000 08:01 372164 /lib/i686/cmov/libc-2.7.so
b7fa0000-b7fa2000 rw-p 00156000 08:01 372164 /lib/i686/cmov/libc-2.7.so
b7fa2000-b7fa5000 rw-p b7fa2000 00:00 0
b7fc2000-b7fc5000 rw-p b7fc2000 00:00 0
b7fc5000-b7fc6000 r-xp b7fc5000 00:00 0 [vdso]
b7fc6000-b7fe0000 r-xp 00000000 08:01 811869 /lib/ld-2.7.so
b7fe0000-b7fe2000 rw-p 0001a000 08:01 811869 /lib/ld-2.7.so
bfdcc000-bfde1000 rw-p bffeb000 00:00 0 [stack]

1 則留言:

匿名 提到...

[url=http://www.answerbag.com/profile/1238206]ConvertVid[/url] [url=http://blog.bakililar.az/videosealdous4/]Xe-Encoder EX[/url]
ImTOO DVD Ripper Platinum 5 RM To PSP Converter/Splitter
http://www.drawingboard.org/blogs/?u=videoseamarantha6 5Star iPod Video Converter
[url=http://www.blogportalen.no/blog/?u=videosearn0]Videozilla[/url] [url=http://www.blogportalen.no/blog/?u=videosealbert4]123 Media Max[/url]
OJOsoft Total Video Converterv1.5.3.0118 WinAVI 3GP/MP4/PSP/iPod Video Converter
http://www.drawingboard.org/blogs/?u=videoseamethyst9 DVD Profiler 3.1.0
A-one DVD Copy 5.66
my icq:858499940385