1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| 1、.text段
一般C语言编译后的执行语句都编译成机器代码,保存在.text段。
2、.data段 已经初始化的全局变量和局部静态变量(虽然默认会初始化为0,或者手动初始化为0,都没有必要在数据段分配空间,直接放在.bss段,就默认值为0了)都保存在.data段。 大体来说,该section包含了在内存中的程序的初始化数据;data段包含三个部分:heap(堆)、stack(栈)和静态数据区。即.data还会存放其他类型的数据,比如局部变量。 数据段只是存放数据,变量名存放在字符串表中。
3、.bss段 未初始化的全局变量和局部静态变量都保存在.bss段。 大体来说该section包含了在内存中的程序的未初始化的数据。 由于程序加载(一般是指main之前)时,bss会被操作系统清零,所以未赋初值或初值为0的全局变量都在bss。.bss段只是为未初始化的全局变量和局部静态变量预留位置而已,它并没有内容,所以它在文件中也不占据空间,这样可减少目标文件体积。 但程序运行时需为变量分配内存空间,故目标文件必须记录所有未初始化的静态分配变量大小总和(通过start_bss和end_bss地址写入机器代码)。当加载器(loader)加载程序时,将为BSS段分配的内存初始化为0。
4、.rodata段 存放只读数据,一般是程序里面的只读变量(如const修饰的变量),以及字符串常量(不一定,也可能放在.data中)。
5、.got段
GOT(Global Offset Table)表中每一项都是本运行模块要引用的一个全局变量或函数的地址。可以用GOT表来间接引用全局变量、函数,也可以把GOT表的首地址作为一个基 准,用相对于该基准的偏移量来引用静态变量、静态函数。由于加载器不会把运行模块加载到固定地址,在不同进程的地址空间中,各运行模块的绝对地址、相对位 置都不同。这种不同反映到GOT表上,就是每个进程的每个运行模块都有独立的GOT表,所以进程间不能共享GOT表。
6、.plt段
过程链接表用于把位置独立的函数调用重定向到绝对位置。通过 PLT 动态链接的程序支持惰性绑定模式。每个动态链接的程序和共享库都有一个 PLT,PLT 表的每一项都是一小段代码,对应于本运行模块要引用的一个全局函数。程序对某个函数的访问都被调整为对 PLT 入口的访问。 每个 PLT 入口项对应一个 GOT 项,执行函数实际上就是跳转到相应 GOT 项存储的地址,该 GOT 项初始值为 PLTn项中的 push 指令地址(即 jmp 的下一条指令,所以第 1 次跳转没有任何作用),待符号解析完成后存放符号的真正地址。动态链接器在装载映射共享库时在 GOT 里设置 2 个特殊值:在 GOT+4( 即 GOT[1]) 设置动态库映射信息数据结构link_map 地址;在 GOT+8(即 GOT[2])设置动态链接器符号解析函数的地址_dl_runtime_resolve。
每一个外部定义的符号在全局偏移表 (Global Offset Table GOT)中有相应的条目,如果符号是函数则在过程连接表(Procedure Linkage Table PLT)中也有相应的条目
下面来看张图就了解了.got段和.plt段的关系:
这个在我们之前说到Hook技术就是用着两个段来实现的。只要修改需要hook的函数地址,插入我们hook的函数,执行之后,再回来就可以了,这里只要修改.got和.plt表就可以了,相关知识大家去网上搜一下吧。这里就不在解释了。
|