{$cluname}

科伟奇论坛 » Powerpc技术论坛 » x86 下动态链接库机制


‹‹上一主题 | 下一主题›› 查看 1389
发表一个新帖子 发表回复

标题 x86 下动态链接库机制 在百度搜索本主题 [ 搜 ] [ 打印 ] [ 推荐 ] [收藏帖子] [ 收藏到新浪VIVI] [ 订阅 ]

east (附小一年级)
楼主   [点击复制本网址] [ 字体: ] [ 编辑 ] [ 报告 ] [评分]
Rank:1
Rank:1
UID 14
帖子 5
积分 15 点
金币 26 枚
魅力 11 度
注册 2009年11月25日
x86 下动态链接库机制
考虑以下简单的程序:

int main()
{
    printf("f[0] = %d\n", 0x0);   
    printf(
"f[0] = %d\n", 0x8);   
    return 0;
}

[root@comcat]$ gdb ./test

(gdb) disass main
Dump of assembler code for function main:
0x08048374 <main+0>:    lea    0x4(%esp),%ecx
0x08048378 <main+4>:    and    $0xfffffff0,%esp
0x0804837b <main+7>:    pushl -0x4(%ecx)
0x0804837e <main+10>:   push   %ebp
0x0804837f <main+11>:   mov    %esp,%ebp
0x08048381 <main+13>:   push   %ecx
0x08048382 <main+14>:   sub    $0x14,%esp
0x08048385 <main+17>:   movl   $0x0,0x4(%esp)
0x0804838d <main+25>:   movl   $0x8048480,(%esp)
0x08048394 <main+32>:   call   0x80482d8 <printf@plt>
0x08048399 <main+37>:   movl   $0x8,0x4(%esp)
0x080483a1 <main+45>:   movl   $0x8048480,(%esp)
0x080483a8 <main+52>:   call   0x80482d8 <printf@plt>
0x080483ad <main+57>:   mov    $0x0,%eax
0x080483b2 <main+62>:   add    $0x14,%esp
0x080483b5 <main+65>:   pop    %ecx
0x080483b6 <main+66>:   pop    %ebp
0x080483b7 <main+67>:   lea    -0x4(%ecx),%esp
0x080483ba <main+70>:   ret   
End of assembler dump.
(gdb) x /8i 0x80482d8
0x80482d8 <printf@plt>: jmp    *0x804958c      ----> 0x804958c 处的值为 0x80482de,则其实际上跳到了下一条指令处。
0x80482de <printf@plt+6>:       push   $0x10
0x80482e3 <printf@plt+11>:      jmp    0x80482a8 <_init+48>
0x80482e8:      Cannot access memory at address 0x80482e8
(gdb) x /4x 0x804958c
0x804958c <_GLOBAL_OFFSET_TABLE_+20>:   0x080482de      0x00000000      0x00000000      0x0804949c
(gdb) b *0x0804838d
Breakpoint 1 at 0x804838d: file test.c, line 3.
(gdb) r
Starting program: /home/comcat/develop/test/dl/test

Breakpoint 1, 0x0804838d in main () at test.c:3
3               printf("f[0] = %d\n", 0);
(gdb) si
0x08048394      3               printf("f[0] = %d\n", 0);
(gdb)
0x080482d8 in printf@plt ()
(gdb)
0x080482de in printf@plt ()
(gdb)
0x080482e3 in printf@plt ()

(gdb) x /4i 0x80482a8
0x80482a8 <_init+48>:   pushl 0x804957c
0x80482ae <_init+54>:   jmp    *0x8049580
0x80482b4 <_init+60>:   add    %al,(%eax)
0x80482b6 <_init+62>:   add    %al,(%eax)
(gdb) x /4x 0x8049580
0x8049580 <_GLOBAL_OFFSET_TABLE_+8>:    0xb7fc02d0      0x080482be      0xb7e6e370      0x080482de       
                        ----> 0xb7fc02d0 处为动态链接器的解析函数 _dl_runtime_resolve()

(gdb) si
0x080482a8 in ?? ()
(gdb) si
0x080482ae in ?? ()
(gdb) si
0xb7fc02d0 in _dl_runtime_resolve () from /lib/ld-linux.so.2

(gdb) b *0x080483a1
Breakpoint 2 at 0x80483a1: file test.c, line 4.
(gdb) c
Continuing.
f[0] = 0

Breakpoint 2, 0x080483a1 in main () at test.c:4       ----> 第一次 printf 调用已经完,动态链接器已经修改 GOT 的相应项为 printf 的地址
4               printf("f[0] = %d\n", 8);

(gdb) x /8i 0x80482d8             ----> PLT 没有变化,但原 GOT 入口 0x804958c 处的值已经被改写为 printf 的地址
0x80482d8 <printf@plt>: jmp    *0x804958c
0x80482de <printf@plt+6>:       push   $0x10
0x80482e3 <printf@plt+11>:      jmp    0x80482a8 <_init+48>
0x80482e8:      add    %al,(%eax)
0x80482ea:      add    %al,(%eax)
0x80482ec:      add    %al,(%eax)
0x80482ee:      add    %al,(%eax)
0x80482f0 <printf@plt+24>:      xor    %ebp,%ebp
(gdb) x /4x 0x804958c
0x804958c <_GLOBAL_OFFSET_TABLE_+20>:   0xb7e9f170      0x00000000      0x00000000      0x0804949c
(gdb) x /4i 0xb7e9f170
0xb7e9f170 <printf>:    push   %ebp
0xb7e9f171 <printf+1>: mov    %esp,%ebp
0xb7e9f173 <printf+3>: push   %ebx
0xb7e9f174 <printf+4>: call   0xb7e6e28f <__i686.get_pc_thunk.bx>

x86 下动态链接机制,动态链接器不会更改 PLT,只会在用到相应链接函数时,才会去解析符号,然后将对应的地址更新到 GOT 的相应项,GOT 里亦没有代码,不需要执行。





此用户离线!
共计在线时长10分钟2009/11/25 23:33:24
[ 资料 ] [ 短信 ] [ 好友 ] [ 文集 ] [ 引用 ] [ 回复 ] 点击返回顶部

« 首页1 »1/共1页


查看积分策略说明快速回复你的内容
快捷回复标题 (选填) 快捷插入表情图标
验 证 码  点击获取验证码
快捷回复内容

自动复制

Powered by TEAM 2.0.5 Release - ACC © 2005 Team5 Studio All rights reserved