博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
binary hacks读数笔记(ld 链接讲解 一)
阅读量:4551 次
发布时间:2019-06-08

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

首先我们先看两段代码:

a.c

extern int shared; int main(){       int a=100;        swap(&a,&shared);}

b.c

int shared=1;void swap(int* a,int* b){     *a^=*b^=*a^=*b;}

 

gcc  -c a.c b.c 得到a.o 与b.o

1、查看a.o:

[root@tlinux misc]# objdump -h a.oa.o:     file format elf64-x86-64Sections:Idx Name          Size      VMA               LMA               File off  Algn  0 .text         00000027  0000000000000000  0000000000000000  00000040  2**0                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE  1 .data         00000000  0000000000000000  0000000000000000  00000067  2**0                  CONTENTS, ALLOC, LOAD, DATA  2 .bss          00000000  0000000000000000  0000000000000000  00000067  2**0                  ALLOC  3 .comment      0000002e  0000000000000000  0000000000000000  00000067  2**0                  CONTENTS, READONLY  4 .note.GNU-stack 00000000  0000000000000000  0000000000000000  00000095  2**0                  CONTENTS, READONLY  5 .eh_frame     00000038  0000000000000000  0000000000000000  00000098  2**3                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

2、查看b.o:

[root@tlinux misc]# objdump -h b.ob.o:     file format elf64-x86-64Sections:Idx Name          Size      VMA               LMA               File off  Algn  0 .text         0000004a  0000000000000000  0000000000000000  00000040  2**0                  CONTENTS, ALLOC, LOAD, READONLY, CODE  1 .data         00000004  0000000000000000  0000000000000000  0000008c  2**2                  CONTENTS, ALLOC, LOAD, DATA  2 .bss          00000000  0000000000000000  0000000000000000  00000090  2**0                  ALLOC  3 .comment      0000002e  0000000000000000  0000000000000000  00000090  2**0                  CONTENTS, READONLY  4 .note.GNU-stack 00000000  0000000000000000  0000000000000000  000000be  2**0                  CONTENTS, READONLY  5 .eh_frame     00000038  0000000000000000  0000000000000000  000000c0  2**3                  CONTENTS, ALLOC, LOAD, RELOC, READONLY, DATA

3、链接之前,VMA与LMA都是0,即目标文件的虚拟空间地址与装载地址都无效。经过链接ld过程,才会给链接文件分配虚拟地址空间。

ld a.o b.o -e main -o ab

链接过程,合并了a.o与b.o的代码段、数据段,具体的位置与大小如下所示:

具体信息如下所示

[root@tlinux misc]# objdump -h abab:     file format elf64-x86-64Sections:Idx Name          Size      VMA               LMA               File off  Algn  0 .text         00000071  00000000004000e8  00000000004000e8  000000e8  2**0                  CONTENTS, ALLOC, LOAD, READONLY, CODE  1 .eh_frame     00000058  0000000000400160  0000000000400160  00000160  2**3                  CONTENTS, ALLOC, LOAD, READONLY, DATA  2 .data         00000004  0000000000601000  0000000000601000  00001000  2**2                  CONTENTS, ALLOC, LOAD, DATA  3 .comment      0000002d  0000000000000000  0000000000000000  00001004  2**0                  CONTENTS, READONLY

 同时,我们可以看一下,链接后,各个源文件的符号表也合成一张全局符号表,且符号表中表明各个符号的虚拟空间位置:

readelf -s ab

Symbol table '.symtab' contains 13 entries:   Num:    Value          Size Type    Bind   Vis      Ndx Name     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND      1: 00000000004000e8     0 SECTION LOCAL  DEFAULT    1      2: 0000000000400160     0 SECTION LOCAL  DEFAULT    2      3: 0000000000601000     0 SECTION LOCAL  DEFAULT    3      4: 0000000000000000     0 SECTION LOCAL  DEFAULT    4      5: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS a.c     6: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS b.c     7: 000000000040010f    74 FUNC    GLOBAL DEFAULT    1 swap     8: 0000000000601000     4 OBJECT  GLOBAL DEFAULT    3 shared     9: 0000000000601004     0 NOTYPE  GLOBAL DEFAULT    3 __bss_start    10: 00000000004000e8    39 FUNC    GLOBAL DEFAULT    1 main    11: 0000000000601004     0 NOTYPE  GLOBAL DEFAULT    3 _edata    12: 0000000000601008     0 NOTYPE  GLOBAL DEFAULT    3 _end

 

4、接下来介绍一下符号的解析与重定位:

首先查看一下未重定位之前,a.o中是怎么处理shared变量与swap函数的:

利用 objdump -d a.o查看一下,a.o的反汇编代码

[root@tlinux misc]# objdump -d a.oa.o:     file format elf64-x86-64Disassembly of section .text:0000000000000000 
: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 48 83 ec 10 sub $0x10,%rsp 8: c7 45 fc 64 00 00 00 movl $0x64,-0x4(%rbp) f: 48 8d 45 fc lea -0x4(%rbp),%rax 13: be 00 00 00 00 mov $0x0,%esi //00 00 00 00 shared 未给地址 18: 48 89 c7 mov %rax,%rdi 1b: b8 00 00 00 00 mov $0x0,%eax 20: e8 00 00 00 00 callq 25
//swap函数也未给地址 25: c9 leaveq 26: c3 retq

5、经过ld链接之后,在最后文件ab中,shared 与 swap都知道了地址。因为链接过程会分配虚拟地址,那么根据前面第三点链接过后的信息,可以知道各个段的虚拟地址,那么

其中各个符号的地址也会知道。那么,经过连接之后,ab中的代码反汇编结果如何,如下所示:

 

[root@tlinux misc]# objdump -d abab:     file format elf64-x86-64Disassembly of section .text:00000000004000e8 
: 4000e8: 55 push %rbp 4000e9: 48 89 e5 mov %rsp,%rbp 4000ec: 48 83 ec 10 sub $0x10,%rsp 4000f0: c7 45 fc 64 00 00 00 movl $0x64,-0x4(%rbp) 4000f7: 48 8d 45 fc lea -0x4(%rbp),%rax 4000fb: be 00 10 60 00 mov $0x601000,%esi //00 60 10 00 详见ab文件的数据段 400100: 48 89 c7 mov %rax,%rdi 400103: b8 00 00 00 00 mov $0x0,%eax 400108: e8 02 00 00 00(相对下一行命令偏移 02) callq 40010f
// 由下面swap在 40010f处可知,a.o b.o链接到一起后,swap的函数虚拟地址可知 call 命令: 40010d+00000002 40010d: c9 leaveq 40010e: c3 retq 000000000040010f
: 40010f: 55 push %rbp 400110: 48 89 e5 mov %rsp,%rbp 400113: 48 89 7d f8 mov %rdi,-0x8(%rbp) 400117: 48 89 75 f0 mov %rsi,-0x10(%rbp) 40011b: 48 8b 45 f8 mov -0x8(%rbp),%rax 40011f: 8b 10 mov (%rax),%edx 400121: 48 8b 45 f0 mov -0x10(%rbp),%rax 400125: 8b 08 mov (%rax),%ecx 400127: 48 8b 45 f8 mov -0x8(%rbp),%rax 40012b: 8b 30 mov (%rax),%esi 40012d: 48 8b 45 f0 mov -0x10(%rbp),%rax 400131: 8b 00 mov (%rax),%eax 400133: 31 c6 xor %eax,%esi 400135: 48 8b 45 f8 mov -0x8(%rbp),%rax 400139: 89 30 mov %esi,(%rax) 40013b: 48 8b 45 f8 mov -0x8(%rbp),%rax 40013f: 8b 00 mov (%rax),%eax 400141: 31 c1 xor %eax,%ecx 400143: 48 8b 45 f0 mov -0x10(%rbp),%rax 400147: 89 08 mov %ecx,(%rax) 400149: 48 8b 45 f0 mov -0x10(%rbp),%rax 40014d: 8b 00 mov (%rax),%eax 40014f: 31 c2 xor %eax,%edx 400151: 48 8b 45 f8 mov -0x8(%rbp),%rax 400155: 89 10 mov %edx,(%rax) 400157: 5d pop %rbp 400158: c3 retq

 6、重定位表信息:

对于可重定位文件,必须包含重定位表,用来描述如何修改相应的段。可以利用objdump  -r  a.o查看重定位表

[root@tlinux misc]# objdump -r a.oa.o:     file format elf64-x86-64RELOCATION RECORDS FOR [.text]:OFFSET           TYPE              VALUE 0000000000000014 R_X86_64_32       shared0000000000000021 R_X86_64_PC32     swap-0x0000000000000004
OFFSET指的是需要被重定位的内容在可重定位文件中的位置,看第4点的反汇编内容可知,0x14位置和0x21位置分别为shared 与 swap.需要被重定位

转载于:https://www.cnblogs.com/wsw-seu/p/10622736.html

你可能感兴趣的文章
在Nginx容器安装Keepalived后端项目双机热备
查看>>
Docker打包部署前端项目与负载均衡
查看>>
一款阿里开源的 Java 诊断工具
查看>>
阿里云云盾安全事件提醒:挖矿程序
查看>>
redis安装(linux)
查看>>
mysql自定义函数多表更新:update_order_relation()
查看>>
UUID与时间戳
查看>>
SimpleDateFormat 线程安全的解决方案--DateTimeFormatter
查看>>
mysql不常用查询
查看>>
win下PowerShell的簡單使用
查看>>
windows下安装redis
查看>>
redis簡單命令
查看>>
git问题记录
查看>>
如何将jar包打包到本地maven仓库
查看>>
idea修改maven项目名
查看>>
idea远程调试tomcat部署项目(windows环境)
查看>>
@Slf4j注解
查看>>
maven仓库镜像、私服与jdk版本配置
查看>>
关于JDBC、JdbcTemplate使用遇到的坑
查看>>
java代码实现数据源切换(连接池简单粗暴)
查看>>