动态链接与静态链接

  • 什么是静态链接
  • 如何实现静态链接
  • 静态链接的优点与缺点
  • 什么是动态链接
  • 如何实现动态链接
  • 动态链接的优点与缺点
  • SO文件格式简析
  • 根据SO文件格式进行静态反编译

静态链接

一段代码从文本编辑器上产生到最终能够在机器上运行,经历了非常多的阶段,概括而言,至少包含了以下几个阶段:

  • 编译: 编译器通过词法分析,语法分析,语义分析等,将一段代码翻译成汇编语言
  • 汇编:将汇编语言翻译成机器指令
  • 链接:解决符号之间的重定位问题
  • 装载:将可执行文件加载到内存

静态链接就是在装载之前,就完成所有的符号引用的一种链接方式。静态链接的处理过程分为2个步骤:

  1. 空间与地址的分配。扫描所有的目标文件,合并相似段,收集当中所有的符号信息。
  2. 符号解析与重定位。调整代码位置。
链接前和链接后

如何可得,在完成静态链接之后,可执行文件中代码段、数据段等的虚拟地址已经确定,即当此可执行文件被载入到内存后,代码段的起始位置就在0000000000400400的位置。

静态链接的优缺点

  • 优点: 简单
  • 缺点:
    • 浪费内存空间。在多进程的操作系统下,同一时间,内存中可能存在多个相同的公共库函数。
    • 程序的开发与发布流程受模块制约。 只要有一个模块更新,那么就需要重新编译打包整个代码。

为了解决以上2个问题,就诞生了动态链接。

动态链接

基本思想就是将对符号的重定位推迟到程序运行时才进行。

只要推迟到运行时进行符号的重定位,就能解决静态链接的两个缺点。

对于第一个缺点:在运行时重定位,如果在运行过程中调用了公共库函数或者其他模块的函数,系统只需要在内存中维护一份公共库代码即可,只要将不同应用程序对公共库函数的调用地址设置成相同即可。

对于第二个缺点:理论上只要将需要替换的模块更新,无需将整个应用程序打包。

动态链接的实现

对于静态链接来说,系统只需要加载一个文件(可执行文件)到内存即可,但是在动态链接下,系统需要映射一个主程序和多个动态链接模块,因此,相比于静态链接,动态链接使得内存的空间分布更加复杂。

不同模块在内存中的装载位置一定要保证不一样。

装载时重定位

对于每一个模块,对于代码中符号的绝对引用,都需要加上一个基地址偏移量。(比如一个模块中存在一个绝对地址的引用A,它假定的是模块可以被加载到0x1000的地方,但是系统在加载该位置已经被其他模块占用了,系统选择将它加载到0x4000的地方,那么对绝对地址A的引用就需要被修改为A+0x3000,即修改代码)。

但是它也有缺点,因为不同进程可能使用同一个模块,但是对于不同进程,代码段是不能共享的,因此,多个进程还是没有办法共享一个模块。因为不能修改模块当中的代码,一旦一个进程将共享模块的绝对地址修改了,其他进程此时调用就一定会报错。

解决这个问题也有办法,在Windows中使用的就是装载时重定位,但是在Linux下使用的是另外一种方式。

地址无关代码

一个模块的代码部分是共享的,但是数据部分是每个进程一个副本的。因此,地址无关代码的基本思想就是将代码段中的绝对地址引用剥离出来放到数据段中,以保证代码指令不变。在Android系统下进行SO文件的编译,默认就是产生地址无关代码。

因此程序执行的流程就变成了:当模块A调用模块B的某个方法的时候,会从模块A的数据段部分找到模块B中函数地址,然后进行函数调用。

动态链接的优点与缺点

优点: 解决了静态链接的缺陷,更适应现代的大规模的软件开发

缺点:1. 结构复杂 2.引入了安全问题,这也是我们能够进行PLT HOOK的基础

SO文件格式

ELF头表

ELF头表记录了ELF文件的基本信息,包括魔数,目标文件类型(可执行文件,共享库文件或者目标文件),文件的目标体系结构,程序入口地址(共享库文件为此值为0),然后是section表大小和数目,程序头表的大小和数目,分别对应的是链接视图和执行视图。

Section表

Section表记录了每一个Section的基本信息,名称,类型,字节数,虚拟地址偏移和文件偏移。文件偏移指的是在ELF文件中,Section距离ELF文件起始位置的字节数,而虚拟地址偏移指的是当此section被加载到内存中后,该Section距离ELF起始位置的字节数。由于有些section只存在于文件中,而不会被系统加载到内存中,因此虚拟地址偏移可能为0.

程序头表

程序头表是装载视图下,系统进行segment解析的入口,它给出了每一个segment的类型,文件偏移,虚拟地址偏移和对齐等。通过对程序头表的遍历,我们可以得到ELF文件所有的segment。

重定位表

静态链接下需要对符号的引用进行重定位,并且ELF文件中对符号的引用可能出现在代码段,也可能出现在数据段,因此重定位表分为了代码段重定位表和数据段重定位表,分别记录引用的符号名和所在的偏移地址。因此,重定位表的格式就是记录符号名和重定位地址的数组。

.dynamic段

.dynamic段是动态链接中最重要的段,它记录了和动态链接有关的段的类型,地址或者数值。指向了与动态链接相关的段

.got段

位于数据区,就是上文所述为了实现位置无关代码将对绝对地址的引用抽离出来存放的集合

.plt段

在介绍.rel.plt段之前,对比静态链接与动态链接我们需要知道.plt段的作用。我们会发现,动态链接将所有的重定位操作延迟到加载时处理,那么就难以避免的会降低程序执行的效率,试想,如果有1000个对外部模块的函数引用,动态链接器就需要先解决这1000个函数引用,然后才开始执行程序。为此,链接器为了提升效率,采取了这样一种策略:仅当函数被调用时,才会唤醒动态链接器解决重定位问题。

.plt段就是为了实现这种策略增加的段。增加了.plt段之后,代码段中的地址就不再指向.got段而是指向了.plt段,再由.plt段指向.got段,具体过程如下:

.plt段是包含了若干数目的代码片段组成的段,代码段中的地址指向对应函数的.plt代码段,代码片段的第一行代码就是间接调用.got表中对应函数地址,但是此时,.got表中的地址指向的是.plt中代码片段的第二行代码,而第二行以后的代码作用就是调用动态链接器处理.got表中的地址。当再次调用此函数时,.plt中代码段第一行代码就可以正确的跳入函数地址执行相应的函数了。

但是,在Android平台下,由于兼容性的限制,并没有采用这种"延迟加载"的特性,所以一开始加载,.got表中的地址就是真实的函数调用地址。但是,Android下的ELF文件仍然保留了.plt表这种结构。

根据SO文件结构进行静态反编译

静态反编译是指对未载入内存控件的SO文件进行的反编译,在这种情况下,主要是针对SO文件的链接视图进行关键参数上的修改,使得静态反编译工具不能够正常的工作。

根据SO文件的格式,在ELF头表中会表明Section表的位置和Section表格的大小。绝大部分静态反编译工具是依据SO文件的链接视图还原出SO文件内容的,那么在这种情况下,我们只需要修改ELF头表中与SECTION表相关的2个参数,就能使得工具反编译SO文件失效。但是SO文件在系统载入内存之后,是使用的执行视图对SO文件进行解析,因此不会影响SO文件运行时。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容