1

Android之区段信息解析

 2 years ago
source link: https://www.51cto.com/article/714091.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Android之区段信息解析-51CTO.COM

f864bf2c9cd3d0c07331b6a5dbd1f30e.png
Android之区段信息解析
作者:编码安全 2022-07-15 08:38:58
plt 的好处在于所有需要重定位的指令跳转都保存在 plt 中,便于集中管理、索引,另一方面,plt 还实现了判断符号是否重定位并提供动态链接器的调用功能,这是延迟绑定技术的核心部分。

在进行对so的动态调试分析或者静态代码分析的过程中,都免不了和如下的区段相关信息打交道。

图片

上图是ida工具中静态分析so文件代码中的展示,可以通过快捷键shift+F7进行展示(也可以用ndk自带的readelf程序进行查看区段信息)。

图片

上图通过ndk自带的​readelf程序进行查看so文件的区段信息(命令:readelf -S xx.so)。

下面就针对以上的区段名称信息做下梳理。

LOAD解析

图片

它表示的是共享文件(so文件)的加载部分,linker会根据load区段中的偏移信息把整个so文件加载起来。

plt解析

plt也称为:过程链接表,主要用于函数和全局变量的调用。

图片

Plt它是延迟绑定,延迟绑定的规则为只有在符号被真正引用时才进行重定位,而不是在刚开始就对所有的动态符号进行重定位,一方面加快了程序的启动,将整个动态加载时间分摊到程序运行期间,另一方面,对于共享库中没有用到的符号,不再进行重定位,节省了重定位的时间,随着共享库的发展更新,这种优势变得越来越明显。

plt 的好处在于所有需要重定位的指令跳转都保存在 plt 中,便于集中管理、索引,另一方面,plt 还实现了判断符号是否重定位并提供动态链接器的调用功能,这是延迟绑定技术的核心部分。

text解析

代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。

这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读(某些架构也允许代码段为可写,即允许修改程序)。

在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

图片

bss解析

这个bss它包含着将出现在程序的内存映像中的未初始化数据,这个区段它不占用文件空间。

图片

bss段的全称:Block Started by Symbol,它通常是指用来存放程序中未初始化的全局变量的一块内存区域,它是属于静态内存分配。当程序运行结束后有系统释放。

init_array解析

init_array是程序代码可以控制的最早时机, 其次才加载Jni_onload。这个也是很多在动态调试分析下断点的关键地方。

它包含着进程初始化所运行的函数指针数组。

它就如类对象的初始化构造函数。

图片

fini_array解析

它存储的是终止函数段(也就是函数指针数组)。它是程序代码中最后执行的代码。

它就像类对象的析构函数。

图片

got解析

它全名为 global offset table,即全局偏移表。

在执行的指令中,本来需要引用符号 A ,但是 A 存在于动态库中,链接过程并不知道它的地址,于是将 A 的地址部分改写为 GOT 表中某一项数据,在编译阶段 GOT 表中是没有真实数据的,但是在动态链接的加载阶段,动态链接器就可以将符号 A 的真实地址填写到 GOT 表中对应的数据项中,这样指令对 A 就产生了正确的引用。

GOT 中每一个表项占用 4 个字节(32位),表示运行时的符号的真实地址。它是针对外部符号引用的。

用来存放链接器找到的 函数/变量地址,也就是函数的绝对地址。

图片

data解析

数据段:data segment.

它通常是指用来存放程序中已初始化的全局变量的一块内存区域,它是属于静态内存分配。

它在程序的内存映像中存在。

图片

ret解析

它的作用:本程序装载进内存时,通过自己的rel表项告诉链接器,哪些地方需要重定位。

只要是rel开头的它都是表示跟重定位相关的信息。

rodata解析

它主要是字符串常量段。

它包含着只读数据,这些数据通常会参与进程映像的只读代码段。

图片

extern解析

它表示是外部的导入函数,就是这个so文件中需要使用到的外部的函数。

图片

data.rel.ro解析

它的作用就是表示程序初始化时的只读数据段。

图片

ARM.extab解析

.ARM.extab 作为 .ARM.exidx 的附属存在,存放数据,但无法直接找到每段数据的入口。

图片

ARM.exidx解析

它包含用于展开堆栈信息的部分。

图片

dynsym和dynstr解析

dynsym和dynstr统称为符号表。

对于在链接阶段未解析的符号,就需要在动态链接阶段进行解析和重定位。

这些未解析的符号被保存在 .dynsym 中,而对应的字符串被保存在 .dynstr。

在 .dynstr 和 .dynsym 相关都是以 '\0' 结尾的动态符号表字符串信息。

dynsym是保存动态链接相关符号,记录其偏移值。

dynstr是dynsym的辅助段。

更详细可参考arm文档:https://developer.arm.com/

本文转载自微信公众号「编码安全」,可以通过以下二维码关注。转载本文请联系编码安全公众号。

12b18437744ef390f440614d5430d84f2f35dc.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK