我想靠自己加载个动态库


差一点

我们就擦肩而过了

有趣

有用

有态度




大家好,我是yeye。

前段时间,断断续续地在研读完了Linux0.12,期间接触到非常多有意思的知识。见识到历史悠久的x86为了保持向前兼容玩出来了芯片硬件的各种骚操作、看到Linus在21岁时往代码注释里面写的各种吐槽等等,尤其是领悟到了程序这玩意本质是怎么回事。

可能各位Linux程序员每天都在和程序打交道,每天都要写不少的代码。得益于GNU这个伟大计划,我们现在已经不需要过于关注程序的底层机制了,只要用好GNU组织提供的自由软件,我们就能轻松地进行程序的编译、链接、运行。

只不过我那该死的好奇心,一直催促着我去一探究竟。几番挣扎,我还是败下阵来,花费一番功夫,勉勉强强搞清楚了程序里面的内容。这里要感谢《程序员的自我修养--链接、装载与库》的几位作者,他们的宝贵经验分享,让我少走了很多弯路。

我这个人,学会了技能不做点什么的时候,心里总是怪痒痒的。于是我设计了一个基于Linux平台的动态模块加载器,这个加载器的源码全部开放,虽说功能和性能与GNU的动态链接器相差甚远,但也确实完整地实现了一个动态库在Linux系统从加载到解析执行的全过程。

或许正是因为阉割了链接器自举、延迟绑定(PLT)等复杂机制,才使得这个项目非常适合想要着手探索程序底层机制和加深了解动态链接器的小伙伴。

这个项目我取名为"hasaki-dll",众所周知,dll是指动态库。而hasaki则是英雄联盟我比较喜欢的角色之一亚索的台词,这位英雄号称"只要e得够快,队友的问号就跟不上我",是一位灵活性十足的英雄。恰好,动态链接库的优势也是在于其的灵活性,因此取名"hasaki"是再好不过。

目前,我已经为该项目的实现原理写了非常详尽的文档,如果大家也对程序的本质感兴趣,不妨去了解一下"hasaki-dll"项目。

项目仓库地址:https://github.com/EmbedHacker/hasaki-dll

欢迎fork、star






下面是项目的README.md

动态模块加载器的实现

Linux平台下的一个安全、简洁的动态模块加载器,其代码实现简洁优雅,非常适合想要探索程序底层机制和加深了解动态链接器的小伙伴。

"hasaki-dll"架构设计

设计分三部分:

  1. 动态模块加载器(主程序)
  2. 动态共享库文件(.so)
    • 自动兼容不同架构ELF文件
    • 自定义修改库文件格式
  3. 函数表/符号表结构(prog_header)

如下图:

它具有以下优点:

  • 支持POSIX 标准的 libdl API,类似于使用dlopen函数把一个动态库加载到内存中(并解析其中的一些符号信息),由这份动态库(通过dlsym函数)提供对应的函数操作集

  • 放弃Gnu/Linux系统下动态连接器的晦涩复杂机制,重新以一种直观、简洁、优雅的方式实现

  • 兼容X86-64/ARM平台,无需修改任何配置文件,直接使用gcc编译器或者交叉编译器编译即可

  • 提供详细的程序说明文档,只需投入一点耐心,几乎不用担心看不懂

如何运行代码测试

请确保你的已经安装了gcc/arm-gcc

测试步骤:

1. 获取项目代码    git clone XXX2. 进入项目文件夹    cd hasaki-dll3. 一键编译并运行    -  x86-64平台:make run    -  ARM平台:make all CROSS_COMPILE=arm-linux-gnueabihf-    也可以手动编译运行    make    cd build    ./loader dll_lib.so

如果一切顺利,你会得到以下执行结果:

这是本项目的第一个版本代码,也是最适合入门了解动态连接器的版本代码。后续会根据实际情况陆续迭代以下动态连接器的功能:

  • 延迟绑定(PLT)

  • 动态链接器自举

  • 共享对象全局符号介入

以下为本人为项目编撰的知识相关文挡,若此前没有研究过ELF文件格式,请从头开始阅读:

(1). 入门ELF文件格式

(2). 共享库设计原理

(3). 动态加载共享库原理

(4). 测试程序分析

注意: arch目录下的平台架构汇编代码,主要为下一个版本添加PLT(延时加载)做准备,现在大家可以忽略它们。


从RTOS到Linux0.12进阶之路

操作系统我说了算!扒一扒调度器

c语言,去你的策略模式!

我想把你的x86当单片机玩




陪伴是最长情的告白

为有趣的编程知识而生

识别二维码

关注我们



在看~

          捧个人场行~