elf文件查找函数的过程

要反编译的程序:hello.c
#include<stdio.h>
int main()
{
   printf("Hello World!/n");
   return 0;
}
 
1.对hello进行反汇编,并查找包含"printf"的行;
可以看到它调用了地址0x80482b0的函数;
[root@localhost src]# objdump -d hello | grep printf
080482b0 <printf@plt>:
 804838c:       e8 1f ff ff ff          call   80482b0 <printf@plt>

2.对hello的.got.plt部分进行反汇编;
[root@localhost src]# objdump -d -j .got.plt hello                                  
                                                                                    
hello:     file format elf32-i386                                                   
                                                                                    
Disassembly of section .got.plt:                                                    
                                                                                    
08049570 <_GLOBAL_OFFSET_TABLE_>:                                                   
 8049570:       a4 94 04 08 00 00 00 00 00 00 00 00 a6 82 04 08     ................
 8049580:       b6 82 04 08  

3.对hello进行反汇编,并查找包含".rel.plt"的行;
[root@localhost src]# objdump -s hello | grep .rel.plt -A3
Contents of section .rel.plt:
 8048268 7c950408 07010000 80950408 07020000  |...............
Contents of section .init:
 8048278 5589e583 ec08e861 000000e8 b4000000  U......a........

4.显示所有的Section,并查找包含.got.plt 的行;
[root@localhost src]# readelf -S hello | grep .got.plt
  [21] .got.plt          PROGBITS        08049570 000570 000014 04  WA  0   0  4

5.对hello的plt部分进行反汇编,可以看到地址0x80482b0 处的汇编代码,
jmp    *0x8049580 语句的意思是跳转到got,从第二步可以看到,它跳到了got中;
got中的内容为b6 82 04 08 ,它的小字节序是08 04 82 b6;
地址0x080482b又是plt中的push   $0x8,0x8是在重定向表中的偏移量,可以从第三步看到;
jmp    8048290 <_init+0x18>  又跳到了plt的开头;
pushl  0x8049574  0x8049574位于got中;
jmp    *0x8049578      然后调用位于0x8049578 的东西,但是该位置是零。

[root@localhost src]# objdump -d -j .plt hello                     
                                                                   
hello:     file format elf32-i386                                  
                                                                   
Disassembly of section .plt:                                       
                                                                   
08048290 <__libc_start_main@plt-0x10>:                             
 8048290:       ff 35 74 95 04 08       pushl  0x8049574           
 8048296:       ff 25 78 95 04 08       jmp    *0x8049578          
 804829c:       00 00                   add    %al,(%eax)          
        ...                                                        
                                                                   
080482a0 <__libc_start_main@plt>:                                  
 80482a0:       ff 25 7c 95 04 08       jmp    *0x804957c          
 80482a6:       68 00 00 00 00          push   $0x0                
 80482ab:       e9 e0 ff ff ff          jmp    8048290 <_init+0x18>
                                                                   
080482b0 <printf@plt>:                                             
 80482b0:       ff 25 80 95 04 08       jmp    *0x8049580          
 80482b6:       68 08 00 00 00          push   $0x8                
 80482bb:       e9 d0 ff ff ff          jmp    8048290 <_init+0x18>
                                       ....            
这个过程叫做懒惰链接,因为重定向只发生在运行并且需要时,只要链接器完成了第一次查找,
链接器将会修改got表项,使得调用plt中的函数时,直接跳到got中,再跳到真正的函数哪里,而不是像
上面那样回到plt中,将重定向表中的偏移量入栈。   

参考1:http://em386.blogspot.com/2006/10/resolving-elf-relocation-name-symbols.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值