1. DSO,Dynamic Shared Objects
[serverate: /local/root/c/ch7 ]
>> cat lib.h
#ifndef LIB_H
#define LIB_H
void foo(int i);
#endif
[serverate: /local/root/c/ch7 ]
>> cat lib.c
#include <stdio.h>
void fun(int i)
{
printf("printing from lib.so %d\n", i);
sleep(-1);
}
>> cat p1.c
#include "lib.h"
int main()
{
fun(1);
return 0;
}
[serverate: /local/root/c/ch7 ]
>> cat p2.c
#include "lib.h"
int main()
{
fun(2);
return 0;
}
test 1:
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -shared -o lib.so lib.c
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -o p1 p1.c ./lib.so
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -o p2 p2.c ./lib.so
>> ./p1 &
[2] 24559
[serverate: /local/root/c/ch7 ]
>> cd /proc/24559
[serverate: /proc/24559 ]
>> cat maps
08048000-08049000 r-xp 00000000 08:06 21915275 /local/root/c/ch7/p1
08049000-0804a000 rw-p 00000000 08:06 21915275 /local/root/c/ch7/p1
f7dca000-f7dcb000 rw-p f7dca000 00:00 0
f7dcb000-f7f14000 r-xp 00000000 08:01 504034 /lib32/libc-2.7.so
f7f14000-f7f15000 r--p 00149000 08:01 504034 /lib32/libc-2.7.so
f7f15000-f7f17000 rw-p 0014a000 08:01 504034 /lib32/libc-2.7.so
f7f17000-f7f1a000 rw-p f7f17000 00:00 0
f7f2a000-f7f2b000 rw-p f7f2a000 00:00 0
f7f2b000-f7f2c000 r-xp 00000000 08:06 21915273 /local/root/c/ch7/lib.so
f7f2c000-f7f2d000 rw-p 00000000 08:06 21915273 /local/root/c/ch7/lib.so
f7f2d000-f7f30000 rw-p f7f2d000 00:00 0
f7f30000-f7f4d000 r-xp 00000000 08:01 504031 /lib32/ld-2.7.so
f7f4d000-f7f4f000 rw-p 0001c000 08:01 504031 /lib32/ld-2.7.so
ffca8000-ffcbd000 rw-p 7ffffffea000 00:00 0 [stack]
ffffe000-fffff000 r-xp ffffe000 00:00 0 [vdso]
[serverate: /local/root/c/ch7 ]
>> ./p2 &
[1] 24575
[serverate: /local/root/c/ch7 ]
>> cd /proc/24575
[serverate: /proc/24575 ]
>> cat maps
08048000-08049000 r-xp 00000000 08:06 21915277 /local/root/c/ch7/p2
08049000-0804a000 rw-p 00000000 08:06 21915277 /local/root/c/ch7/p2
f7e11000-f7e12000 rw-p f7e11000 00:00 0
f7e12000-f7f5b000 r-xp 00000000 08:01 504034 /lib32/libc-2.7.so
f7f5b000-f7f5c000 r--p 00149000 08:01 504034 /lib32/libc-2.7.so
f7f5c000-f7f5e000 rw-p 0014a000 08:01 504034 /lib32/libc-2.7.so
f7f5e000-f7f61000 rw-p f7f5e000 00:00 0
f7f71000-f7f72000 rw-p f7f71000 00:00 0
f7f72000-f7f73000 r-xp 00000000 08:06 21915273 /local/root/c/ch7/lib.so
f7f73000-f7f74000 rw-p 00000000 08:06 21915273 /local/root/c/ch7/lib.so
f7f74000-f7f77000 rw-p f7f74000 00:00 0
f7f77000-f7f94000 r-xp 00000000 08:01 504031 /lib32/ld-2.7.so
f7f94000-f7f96000 rw-p 0001c000 08:01 504031 /lib32/ld-2.7.so
ffed1000-ffee6000 rw-p 7ffffffea000 00:00 0 [stack]
ffffe000-fffff000 r-xp ffffe000 00:00 0 [vdso]
test 2:
[serverate: /local/root/c/ch7 ]
>> gcc -fPIC -m32 -shared -o lib.so lib.c
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -o p1 p1.c ./lib.so
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -o p2 p2.c ./lib.so
2. PIC
>> cat pic.c
static int a;
extern int b;
extern void ext();
void bar()
{
a = 1;
b = 2;
}
void foo()
{
bar();
ext();
}
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -fPIC -shared -o pic.so pic.c
[serverate: /local/root/c/ch7 ]
>> objdump -d pic.so
pic.so: file format elf32-i386
Disassembly of section .init:
000002dc <_init>:
2dc: 55 push %ebp
2dd: 89 e5 mov %esp,%ebp
2df: 53 push %ebx
2e0: 83 ec 04 sub $0x4,%esp
2e3: e8 00 00 00 00 call 2e8 <_init+0xc>
2e8: 5b pop %ebx
2e9: 81 c3 b0 12 00 00 add $0x12b0,%ebx
2ef: 8b 93 f0 ff ff ff mov -0x10(%ebx),%edx
2f5: 85 d2 test %edx,%edx
2f7: 74 05 je 2fe <_init+0x22>
2f9: e8 2e 00 00 00 call 32c <__gmon_start__@plt>
2fe: e8 cd 00 00 00 call 3d0 <frame_dummy>
303: e8 58 01 00 00 call 460 <__do_global_ctors_aux>
308: 58 pop %eax
309: 5b pop %ebx
30a: c9 leave
30b: c3 ret
Disassembly of section .plt:
0000030c <bar@plt-0x10>:
30c: ff b3 04 00 00 00 pushl 0x4(%ebx)
312: ff a3 08 00 00 00 jmp *0x8(%ebx)
318: 00 00 add %al,(%eax)
...
0000031c <bar@plt>:
31c: ff a3 0c 00 00 00 jmp *0xc(%ebx)
322: 68 00 00 00 00 push $0x0
327: e9 e0 ff ff ff jmp 30c <_init+0x30>
0000032c <__gmon_start__@plt>:
32c: ff a3 10 00 00 00 jmp *0x10(%ebx)
332: 68 08 00 00 00 push $0x8
337: e9 d0 ff ff ff jmp 30c <_init+0x30>
0000033c <_Jv_RegisterClasses@plt>:
33c: ff a3 14 00 00 00 jmp *0x14(%ebx)
342: 68 10 00 00 00 push $0x10
347: e9 c0 ff ff ff jmp 30c <_init+0x30>
0000034c <ext@plt>:
34c: ff a3 18 00 00 00 jmp *0x18(%ebx)
352: 68 18 00 00 00 push $0x18
357: e9 b0 ff ff ff jmp 30c <_init+0x30>
0000035c <__cxa_finalize@plt>:
35c: ff a3 1c 00 00 00 jmp *0x1c(%ebx)
362: 68 20 00 00 00 push $0x20
367: e9 a0 ff ff ff jmp 30c <_init+0x30>
Disassembly of section .text:
00000370 <__do_global_dtors_aux>:
370: 55 push %ebp
371: 89 e5 mov %esp,%ebp
373: 53 push %ebx
374: e8 91 00 00 00 call 40a <__i686.get_pc_thunk.bx>
379: 81 c3 1f 12 00 00 add $0x121f,%ebx
37f: 83 ec 04 sub $0x4,%esp
382: 80 bb 28 00 00 00 00 cmpb $0x0,0x28(%ebx)
389: 75 38 jne 3c3 <__do_global_dtors_aux+0x53>
38b: 8b 83 fc ff ff ff mov -0x4(%ebx),%eax
391: 85 c0 test %eax,%eax
393: 74 1b je 3b0 <__do_global_dtors_aux+0x40>
395: 8b 83 20 00 00 00 mov 0x20(%ebx),%eax
39b: 89 04 24 mov %eax,(%esp)
39e: e8 b9 ff ff ff call 35c <__cxa_finalize@plt>
3a3: eb 0b jmp 3b0 <__do_global_dtors_aux+0x40>
3a5: 83 c0 04 add $0x4,%eax
3a8: 89 83 24 00 00 00 mov %eax,0x24(%ebx)
3ae: ff d2 call *%edx
3b0: 8b 83 24 00 00 00 mov 0x24(%ebx),%eax
3b6: 8b 10 mov (%eax),%edx
3b8: 85 d2 test %edx,%edx
3ba: 75 e9 jne 3a5 <__do_global_dtors_aux+0x35>
3bc: c6 83 28 00 00 00 01 movb $0x1,0x28(%ebx)
3c3: 83 c4 04 add $0x4,%esp
3c6: 5b pop %ebx
3c7: c9 leave
3c8: c3 ret
3c9: 8d b4 26 00 00 00 00 lea 0x0(%esi),%esi
000003d0 <frame_dummy>:
3d0: 55 push %ebp
3d1: 89 e5 mov %esp,%ebp
3d3: 53 push %ebx
3d4: e8 31 00 00 00 call 40a <__i686.get_pc_thunk.bx>
3d9: 81 c3 bf 11 00 00 add $0x11bf,%ebx
3df: 83 ec 04 sub $0x4,%esp
3e2: 8b 8b 2c ff ff ff mov -0xd4(%ebx),%ecx
3e8: 85 c9 test %ecx,%ecx
3ea: 74 18 je 404 <frame_dummy+0x34>
3ec: 8b 93 f4 ff ff ff mov -0xc(%ebx),%edx
3f2: 85 d2 test %edx,%edx
3f4: 74 0e je 404 <frame_dummy+0x34>
3f6: 8d 83 2c ff ff ff lea -0xd4(%ebx),%eax
3fc: 89 04 24 mov %eax,(%esp)
3ff: e8 38 ff ff ff call 33c <_Jv_RegisterClasses@plt>
404: 83 c4 04 add $0x4,%esp
407: 5b pop %ebx
408: c9 leave
409: c3 ret
0000040a <__i686.get_pc_thunk.bx>:
40a: 8b 1c 24 mov (%esp),%ebx
40d: c3 ret
40e: 90 nop
40f: 90 nop
00000410 <bar>:
410: 55 push %ebp
411: 89 e5 mov %esp,%ebp
413: e8 40 00 00 00 call 458 <__i686.get_pc_thunk.cx>
418: 81 c1 80 11 00 00 add $0x1180,%ecx
41e: c7 81 2c 00 00 00 01 movl $0x1,0x2c(%ecx)
425: 00 00 00
428: 8b 81 f8 ff ff ff mov -0x8(%ecx),%eax
42e: c7 00 02 00 00 00 movl $0x2,(%eax)
434: c9 leave
435: c3 ret
00000436 <foo>:
436: 55 push %ebp
437: 89 e5 mov %esp,%ebp
439: 53 push %ebx
43a: 83 ec 04 sub $0x4,%esp
43d: e8 c8 ff ff ff call 40a <__i686.get_pc_thunk.bx>
442: 81 c3 56 11 00 00 add $0x1156,%ebx
448: e8 cf fe ff ff call 31c <bar@plt>
44d: e8 fa fe ff ff call 34c <ext@plt>
452: 83 c4 04 add $0x4,%esp
455: 5b pop %ebx
456: c9 leave
457: c3 ret
00000458 <__i686.get_pc_thunk.cx>:
458: 8b 0c 24 mov (%esp),%ecx
45b: c3 ret
45c: 90 nop
45d: 90 nop
45e: 90 nop
45f: 90 nop
00000460 <__do_global_ctors_aux>:
460: 55 push %ebp
461: 89 e5 mov %esp,%ebp
463: 56 push %esi
464: 53 push %ebx
465: e8 a0 ff ff ff call 40a <__i686.get_pc_thunk.bx>
46a: 81 c3 2e 11 00 00 add $0x112e,%ebx
470: 8d 83 20 ff ff ff lea -0xe0(%ebx),%eax
476: 8d 70 fc lea -0x4(%eax),%esi
479: 8b 40 fc mov -0x4(%eax),%eax
47c: eb 09 jmp 487 <__do_global_ctors_aux+0x27>
47e: 66 90 xchg %ax,%ax
480: 83 ee 04 sub $0x4,%esi
483: ff d0 call *%eax
485: 8b 06 mov (%esi),%eax
487: 83 f8 ff cmp $0xffffffff,%eax
48a: 75 f4 jne 480 <__do_global_ctors_aux+0x20>
48c: 5b pop %ebx
48d: 5e pop %esi
48e: c9 leave
48f: 90 nop
490: c3 ret
491: 90 nop
492: 90 nop
493: 90 nop
Disassembly of section .fini:
00000494 <_fini>:
494: 55 push %ebp
495: 89 e5 mov %esp,%ebp
497: 53 push %ebx
498: 83 ec 04 sub $0x4,%esp
49b: e8 00 00 00 00 call 4a0 <_fini+0xc>
4a0: 5b pop %ebx
4a1: 81 c3 f8 10 00 00 add $0x10f8,%ebx
4a7: e8 c4 fe ff ff call 370 <__do_global_dtors_aux>
4ac: 59 pop %ecx
4ad: 5b pop %ebx
4ae: c9 leave
4af: c3 ret
2.1 模块内部调用或跳转
call 31c <bar@plt>
2.2 模块内部数据访问
2.3 模块间数据访问
GOT: Global offset table
从下面可以看出,got的位置在00001588。
>> objdump -h pic.so
pic.so: file format elf32-i386
Sections:
Idx Name Size VMA LMA File off Algn
0 .hash 00000048 000000b4 000000b4 000000b4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .dynsym 000000d0 000000fc 000000fc 000000fc 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .dynstr 0000007b 000001cc 000001cc 000001cc 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .gnu.version 0000001a 00000248 00000248 00000248 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .gnu.version_r 00000020 00000264 00000264 00000264 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .rel.dyn 00000030 00000284 00000284 00000284 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .rel.plt 00000028 000002b4 000002b4 000002b4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .init 00000030 000002dc 000002dc 000002dc 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
8 .plt 00000060 0000030c 0000030c 0000030c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
9 .text 00000124 00000370 00000370 00000370 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
10 .fini 0000001c 00000494 00000494 00000494 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .eh_frame 00000004 000004b0 000004b0 000004b0 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
12 .ctors 00000008 000014b4 000014b4 000004b4 2**2
CONTENTS, ALLOC, LOAD, DATA
13 .dtors 00000008 000014bc 000014bc 000004bc 2**2
CONTENTS, ALLOC, LOAD, DATA
14 .jcr 00000004 000014c4 000014c4 000004c4 2**2
CONTENTS, ALLOC, LOAD, DATA
15 .dynamic 000000c0 000014c8 000014c8 000004c8 2**2
CONTENTS, ALLOC, LOAD, DATA
16 .got 00000010 00001588 00001588 00000588 2**2
CONTENTS, ALLOC, LOAD, DATA
17 .got.plt 00000020 00001598 00001598 00000598 2**2
CONTENTS, ALLOC, LOAD, DATA
18 .data 00000008 000015b8 000015b8 000005b8 2**2
CONTENTS, ALLOC, LOAD, DATA
19 .bss 00000008 000015c0 000015c0 000005c0 2**2
ALLOC
20 .comment 000000d2 00000000 00000000 000005c0 2**0
CONTENTS, READONLY
21 .debug_aranges 00000050 00000000 00000000 00000698 2**3
CONTENTS, READONLY, DEBUGGING
22 .debug_info 0000011c 00000000 00000000 000006e8 2**0
CONTENTS, READONLY, DEBUGGING
23 .debug_abbrev 00000024 00000000 00000000 00000804 2**0
CONTENTS, READONLY, DEBUGGING
24 .debug_line 00000104 00000000 00000000 00000828 2**0
CONTENTS, READONLY, DEBUGGING
25 .debug_ranges 00000040 00000000 00000000 00000930 2**3
CONTENTS, READONLY, DEBUGGING
>> objdump -R pic.so
pic.so: file format elf32-i386
DYNAMIC RELOCATION RECORDS
OFFSET TYPE VALUE
000015b8 R_386_RELATIVE *ABS*
000015bc R_386_RELATIVE *ABS*
00001588 R_386_GLOB_DAT __gmon_start__
0000158c R_386_GLOB_DAT _Jv_RegisterClasses
00001590 R_386_GLOB_DAT b
00001594 R_386_GLOB_DAT __cxa_finalize
000015a4 R_386_JUMP_SLOT bar
000015a8 R_386_JUMP_SLOT __gmon_start__
000015ac R_386_JUMP_SLOT _Jv_RegisterClasses
000015b0 R_386_JUMP_SLOT ext
000015b4 R_386_JUMP_SLOT __cxa_finalize
可以看出变量b的偏移是1590。
这和代码是对应的,
428: 8b 81 f8 ff ff ff mov -0x8(%ecx),%eax
42e: c7 00 02 00 00 00 movl $0x2,(%eax)
2.4 模块间调用和跳转
如何区分一个DSO是否为PIC
[serverate: /local/root/c/ch7 ]
>> gcc -m32 -shared -o lib.so lib.c
[serverate: /local/root/c/ch7 ]
>> readelf -d lib.so |grep TEXTREL
0x00000016 (TEXTREL) 0x0
有输出,则不是PIC。PIC的DSO不会有代码段重定位表地址。
PIE: Position-Independent Executable -fPIE
3. 共享模块的全局变量问题
Question: 如果一个共享对象lib.so中定义了一个全局变量G,而进程A和B都使用了lib.so,那么当进程A改变这个全局变量G的值的时,进程B中G会受到影响么?
不会,因为当lib.so被两个进程加载时,它的数据段部分在每个进程中都有独立的副本,从这个角度看,共享对象中的全局变量实际上和定义在程序内部的全局变量没什么区别。如果是同一个进程中的2个线程,则会看到对方对全局变量的修改。