博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux 链接详解----静态链接实例分析
阅读量:6820 次
发布时间:2019-06-26

本文共 3834 字,大约阅读时间需要 12 分钟。

由中我们简单的分析了静态库的引用解析和重定位的内容, 下面我们结合实例来看一下静态链接重定位过程。

/**     a.c  */int a = 1000;void add(int c);int main(){    int c = 123;    add(c);    return 0;}/** b.c*/extern int a;void add(int c){    a += c;}

实例中使用了如上代码, 在a.c 中是我们的入口函数main 和定义的全局变量a,其中引用了函数add 它的定义在b.c中。在b.c中又引用了a.c中a的定义。我们先将其分别编译为目标文件反汇编可以看到如下:

0000000000000000 
: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 83 ec 10 sub $0x10,%rsp 8: c7 45 fc 7b 00 00 00 movl $0x7b,-0x4(%rbp) f: 8b 45 fc mov -0x4(%rbp),%eax 12: 89 c7 mov %eax,%edi 14: e8 00 00 00 00 callq 19
19: b8 00 00 00 00 mov $0x0,%eax 1e: c9 leaveq 1f: c3 retq Disassembly of section .data:0000000000000000
: 0: e8 .byte 0xe8 1: 03 00 add (%rax),%eax# 以上是a.o 的反编译main 和data段的结果。 # # 下面是b.c中add的反编译结果 0000000000000000
: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 89 7d fc mov %edi,-0x4(%rbp) 7: 8b 15 00 00 00 00 mov 0x0(%rip),%edx # d
d: 8b 45 fc mov -0x4(%rbp),%eax 10: 01 d0 add %edx,%eax 12: 89 05 00 00 00 00 mov %eax,0x0(%rip) # 18
18: 5d pop %rbp 19: c3 retq

我们先分析一下函数的引用重定位: 首先这里可以看到a.c中add的引用,在模块a.o中 e8 00 00 00 00 callq 19 <main+0x19>   这条call指令就是调用add函数, call指令就是把下一条指令地址(CS:IP)压入栈,然后执行跳转指令,在解析引用之前是找不到add的定义入口处的 所以这里的偏移量是0. 这就是需要重定位信息的原因。a.o中add 重定位信息如下:

重定位节 '.rela.text' 位于偏移量 0x548 含有 1 个条目:

  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000015  000a00000002 R_X86_64_PC32     0000000000000000 add - 4

这里的0x15就是代码段中需要重定位的位置   即 14: e8 00 00 00 00 callq 19 <main+0x19> 00 00 00 00 的首地址正是0x15. 

我们再来看一下全局变量的引用:在模块b.o中 引用了a.o中的全局变量a, 我们可以看到b.o中add的反汇编程序 7: 8b 15 00 00 00 00 mov 0x0(%rip),%edx # d <add+0xd> rip寄存器存放的是下一条指令的地址 这条指令的意思也就是说 取出rip+0x0地址的数据并将其放入edx寄存器,也就是找到全局变量a的值将它放到edx中。再看b.o的重定位信息

重定位节 '.rela.text' 位于偏移量 0x528 含有 2 个条目:

  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000009  000900000002 R_X86_64_PC32     0000000000000000 a - 4

这里可以看到需要重定位的地方位于代码段的0x9 ,正是上面的偏移量的地址。

到此有了重定位信息再经过符号解析------由引用找到定义,各个段合并

 

最后我们看一下可执行文件a的反汇编程序:

 

00000000004004f0 
: 4004f0: 55 push %rbp 4004f1: 48 89 e5 mov %rsp,%rbp 4004f4: 48 83 ec 10 sub $0x10,%rsp 4004f8: c7 45 fc 7b 00 00 00 movl $0x7b,-0x4(%rbp) 4004ff: 8b 45 fc mov -0x4(%rbp),%eax 400502: 89 c7 mov %eax,%edi 400504: e8 07 00 00 00 callq 400510
  #400509 + 7  = 400510 跳转到此地址add执行 400509: b8 00 00 00 00 mov $0x0,%eax 40050e: c9 leaveq 40050f: c3 retq 0000000000400510
: 400510: 55 push %rbp 400511: 48 89 e5 mov %rsp,%rbp 400514: 89 7d fc mov %edi,-0x4(%rbp) 400517: 8b 15 0f 0b 20 00 mov 0x200b0f(%rip),%edx # 60102c
  40051d + 0x200b0f = 60102c a变量的地址  取出放到edx寄存器中 40051d: 8b 45 fc mov -0x4(%rbp),%eax 400520: 01 d0 add %edx,%eax 400522: 89 05 04 0b 20 00 mov %eax,0x200b04(%rip) # 60102c
400528: 5d pop %rbp 400529: c3 retq 40052a: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)

 

我们可以看到之前代码段中call 及mov后的偏移地址已经变为了实际可用的地址

 

转载于:https://www.cnblogs.com/MaAce/p/7986348.html

你可能感兴趣的文章
easyui的 getSelections 与 getSelected 对比区别
查看>>
算法:街区最短路径问题
查看>>
Linux下Samba的配置
查看>>
如何取消IE“已限制此网页运行可以访问计算机的脚本或ActiveX控件”
查看>>
Android 所遇问题(一)
查看>>
2014年移动媒体趋势报告:中国网络媒体的未来
查看>>
设计模式(15)-Facade Pattern
查看>>
How to get URL parameters with Javascript?
查看>>
【转】易用性测试
查看>>
[翻译svg教程]svg中的circle元素
查看>>
分布系统概念与设计---系统模型
查看>>
核心基础以及Fragment与Activity传递数据完整示例
查看>>
【趣事】一根网线发起的攻击
查看>>
如何判断CapsLock键是否按下
查看>>
微软职位内部推荐-Software Development Engineer II
查看>>
在Ubuntu 14 上安装 Nginx-RTMP 流媒体服务器
查看>>
[LeetCode] Longest Common Prefix 最长共同前缀
查看>>
Python-文件修改器
查看>>
JavaScript把客户端时间转换为北京时间
查看>>
[C++] zlatlcv: ATL字符串转换辅助库。能很方便的将UTF-8字符串转为TCHAR等字符串
查看>>