CTF权威指南 笔记 -第二章二进制文件- 2.3 -静态链接

目录

地址空间分配

两个链接的方式

 按序叠加

相似节合并

静态链接的详细过程

虚拟内存

重定位文件

静态链接库


地址空间分配

我们把之前的两函数分为两个文件

main.c

extern int shared
extern vooid fun(int *a,int *b);
int main(){
	int a=100;
	func(&a,&shared);
	return 0;
}

func.c

int shared =1;
int tmp=0;
void func(int *a,int *b){
	tmp = *a;
	*a=*b;
	*b=tmp;
}
gcc -static -fno-stack-protector main.c func.c -save-temps --verbose -o func.ELF

两个链接的方式

这里我们先给出

 按序叠加

 我们如果要把main.o 和func.o 链接成一个可执行文件 最简单就是按序叠加

但是这种弊端 就是如果链接的目标文件过多 可执行文件就会巨大

而且一个不足一页的代码节或数据节 也要占一页的空间 这样就造成了浪费

相似节合并

把不同目标文件相同属性的节合并为一个节

main func的text 合并为一个新的text节

这种方式被现在的编译器所采用

先对各个节的长度 属性 和偏移进行分析 
然后输入目标文件中的符号表的符号定义和符号引用统一成一个全局符号表
最后 读取输入文件的各类信息对符号进行解析 重定位等操作


相似节合并就出现在重定位当中


完成后 程序的每条指令和全局变量都有了运行的时候唯一的内存地址

静态链接的详细过程

为了构造可执行文件

编译器必须经过两个过程

符号解析 
把每一个符号 (函数,全局变量,静态变量)的引用和其定义关联
重定位
把每一个符号定义和一个内存地址进行关联 然后修改这些符号的引用 让他指向地址

我们下面进行对比 可执行文件 func.ELF 和 中间产物 main.o的对比

我们重点关注 .text .bss .data

objdump -h func.ELF-main.o

main.o的

 func.ELF的

objdump -h func.ELF

 我们这里关注 VMA 和 LMA

VMA :虚拟地址
LMA :加载地址


这两个一般情况下是相同的

我们能发现 main.o的VMA和LMA是0 因为还没有进行链接

而func.ELF 有实际地址  因为相似节合并了 并且完成了虚拟内存的分配

虚拟内存

虚拟内存 就是 程序执行 是把代码RAM载入内存 如果一个代码很多 内存就饱满了

所以虚拟内存的作用就是 让机器认为还有很多内存 但是实际上 代码只是部分进入了内存中

还有一些在外存上 机器要使用外存代码了 就自动载入


百度百科:虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。

接着我们使用objdump查看main.o的反汇编

objdump -d -M intel --section=.text func.ELF-main.o

 只对text段进行反汇编

 这里我们进行分析

main函数从 地址0开始 
call函数的操作码是e8 
后面是调取的函数地址 偏移量 但是没有进行重定位 所以0x000000000
函数的地址是在便宜处 0x2e的地方
我们可以通过下一条返回地址进行计算函数地址

mov的地址为2e 
函数偏移量为 0x0

0x2e+0x0 = 0x2e 这只是一个临时地址

shared的地址在rip+0x0
其实编译器还根本不知道地址在哪 所以使用00000000代替

接着我们看看func.ELF的文件

objdump -d -M intel --section=.text func.ELF |grep -A 16 "<main>"


16 "<main>"找到main函数 并且打印前面的地址

main函数从 0x401745开始 
call函数在 40176e的位置 
mov为 401773 + 0x07 =0x4177A 这个就是func函数的地址

同时 rip+0xc398d 为 shared的地址

重定位文件

重定位文件中最重要的就是要包含重定位表 用于告诉链接器如何修改节的内容

例如

.rela.text 的节保存 .text的重定位表 
.rela.text包含两个重定位入口 
shared的类型为 R_X86_64_32 用于绝对寻址 cpu 直接把 指令编码中32位值作为有效地址 
func的类型为R_X86_64_PC32 用于相对寻址 cpu 把指令编码中的32位值加上 PC的值得到下一条地址
objdump -r func.ELF-main.o

静态链接库

后缀名为.a 的为静态链接库文件 libc.a 
 

一个静态链接库可以视为一组目标文件经过压缩打包的文件集合

执行各种编译任务的时候 需要有不同的目标文件

比如输入输出 printf.o scanf.o等

我们使用ar对目标文件进行压缩 编号 引用 这就形成了 libc.a
ar -t libc.a

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值