动态链接器笔记

发布于 2021-09-02  38 次阅读


背景

没想到笔者在二进制入门级阶段就已经能够搜索到如此多condisagree错误资料....

英文搜索+ELF标准文档掘地三尺+翻Linux内核开发日志,确定了一些很在意要点

记录如下(仍然有很多疑问点,不保证完全正确性)

正文

因为感到奇怪的细节实在是太多了(侧面说明开发一个编译器,链接器,装载器,重定位解释器是如何的困难),所以并不会按照某种顺序记录,只是大杂烩记录一些东西

首先是为什么需要PLT表,为了解释这一点,先补一个现行PLT和GOT的运作机制

Program                PLT                                 printf
+---------------+      +------------------+                +-----+
| ...           |      | push [0x603008]  |<---+       +-->| ... |
| call j_printf |--+   | jmp [0x603010]   |----+--...--+   +-----+
| ...           |  |   | ...              |    |
+---------------+  +-->| jmp [printf@GOT] |-+  |
                       | push 0xf         |<+  |
                       | jmp 0x400da0     |----+
                       | ...              |

其中,...代表各种间接与PLT联系的机制,包括GOT

现在有一个问题:为什么出现了PLT表,而不是单纯一个GOT表——这在技术上来说似乎是可以轻易实现的

为什么产生了这样的冗余——大可以类似于保护代码段的方法保护GOT表:就算这样不保险,为什么排除安全问题的情况下,也出现了PLT——为什么所有主流编译器允许开启危险编译选项却不允许放弃PLT

然后再补一个笔者纸上谈兵的,仅有GOT的实现

GOT里面存着变量

这种做法,不考虑安全的话实际上完全可以实现,但是问题此时不在于动态链接器,而是编译器

因为编译到目标文件的时候,编译器并不知道某个函数是动态链接库里面的函数还是在目标文件中

当然,这可以在C语言初期解决:采用特殊语法(出现动态链接功能的年代已经不能算是编译器发明的初期了)

同时最重要的,最关键的因素是重定位

我们不能保证GOT表不被强制重定位

而且就算解决了重定位问题

还有一个最致命的底层问题

替换前后call机器码不等长

一个是五字节,一个是六字节(强行替换需要nop,或者是进一步的重定向,这样的话重定向工作简直是多了一到两倍)

我们必须解决以上所有问题,才能够只使用GOT表

而上述这些东西刚出现庞大到不能改的时间节点各不相同,另外肯定还有许多笔者未搜索到的底层机制影响了这一功能

然后就是,dllimport这个语法功能,他确实完成了上述的一些操作,但是也有很致命的一点,如果一个文件用了这个语法然后编译成目标文件,此时便不能再和其他覆写了该函数的目标文件或静态库链接了

总的来说,这是一个两难问题,如果这个世界上真的只有GOT,那么也一定会出现某个小众操作系统的动态连接功能使用的是两层跳转的,更何况,GOT更适合权限管理——上述所有讨论都是建立在不考虑安全性之上,纯理论的基础上的

如果考虑安全性,其实这个问题毫无讨论意义

另外就是两个有意思的问题

能不能把静态库动态连接或者把动态库静态编译?

well,这个是分平台的

如果是Linux平台,.a文件其实不是ELF文件,搜索了一下没有找到静态库动态链接的方法

(施工中)

这部分暂时先放下,后面加在程序员自我修养读书笔记后面,放几个备忘链接先

https://stackoverflow.com/questions/1022120/do-i-need-static-libraries-to-statically-link
https://stackoverflow.com/questions/5720205/is-it-possible-to-statically-link-against-a-shared-object
https://stackoverflow.com/questions/725472/static-link-of-shared-library-function-in-gcc
https://stackoverflow.com/questions/4430645/possible-to-statically-link-shared-object-libraries
https://stackoverflow.com/questions/8331456/mixing-pic-and-non-pic-objects-in-a-shared-library