首页
社区
课程
招聘
[原创]初探Android Linker 动态库SO的加载流程(1)
发表于: 2025-12-2 22:31 9366

[原创]初探Android Linker 动态库SO的加载流程(1)

2025-12-2 22:31
9366

这部分会比较难,比较复杂,建议学习过ELF文件结构的再来读这份代码,这里推荐读完《程序员的自我修养——链接、装载与库》,以及《ARM汇编与逆向工程 蓝狐卷 基础知识》的第二章知识,然后再来看,这一系列文章。

从这篇文章开始,基于aosp8.1加载SO源码的部分研究,打算将分为3篇写完7个加载步骤,流程十分长,学完对ELF的认识就不会只停留在书籍上了,对研究ELF文件格式、so加固将会有所帮助。

还有一篇番外篇,关于自定义Linker的现实,以及结合开源的so脱壳脚本分析。

第一次调用该方法的加载目标so时候,我后面都称为目标so,传递的参数,如下。

代码如下


so的加载都会被封装成一个LoadTask,load_tasks是本次加载任务链表,是一个链表结构,library_names_count是为1,所在在load_tasks当前只有目标so,下面的代码是为soinfo = nullptr,参数传递的是nullptr。进行soinfo空间分配。

代码如下



load_tasks的大小还是只有1,遍历load_tasks然后调用task->get_needed_by();,needed_by代表的是哪个库需要我。举个例子libA -> libB,A依赖B,此时如果加载的task是libB,则get_needed_by得到的则是libA。needed_by是一个链表结构。

根据结果设置task的属性。find_library_internal,方法会把task和load_tasks传递进去

代码如下


find_library_internal方法的代码如下,这里关注主分支代码,find_loaded_library_by_soname获取的不到,然后会往下走,调用load_library方法,如果上面load_library加载不成功,就会到linked_namespaces进去加载load_library是否存在该so,这里不分析linked_namespaces这部分。

代码如下


我们继续看load_library方法的代码,方法有两个重载。我看先看第一个重载的方法。

代码如下


我们关注主分支流程open_library方法

strchr(name, '/') != nullptr根据注释这里说明如果路径包含斜杠/,则去尝试加载,这里我们不分析。然后往下这里分为三部分。


这里有一篇文章写得非常好,229K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3f1#2x3Y4m8G2K9X3W2W2i4K6u0W2j5$3&6Q4x3V1k6@1K9s2u0W2j5h3c8Q4x3X3b7&6y4o6R3&6y4o6u0Q4x3X3b7I4i4K6u0V1x3g2)9J5k6h3S2@1L8h3H3`.,关于Android7.0以上命名空间详解(dlopen限制)。

代码如下


然后接下来直接看open_library_on_paths方法,该方法中,kZipFileSeparator是const char* const kZipFileSeparator = "!/";不是我们分析的类型,不会走该分支,只有是该分支才会走open_library_in_zipfile,

接下来是调用open(buf, O_RDONLY | O_CLOEXEC),这是Linux系统调用,用于打开文件获取文件描述符fd,然后返回。

代码如下


到此,我们继续回到load_library方法,

load_library方法代码片段如下


然后设置task的fd。以及文件偏移。结合AI分析

那这部分对于普通的so应该就是0。

接着load_library方法开始调用load_library的第二个重载


首先是soinfo_alloc,分配soinfo,task->set_soinfo(si);

然后核心是,task调用read方法,这里说结论,read方法会去读取的内容如下


我们直接来到该方法看看这些方法具体怎么做,该方法处于linker_phdr.cpp中

代码如下


我们挨个进去看,ReadElfHeader

pread64就是read系统调用,这里会进行读取fd_,然后读取的大小是sizeof(header_),文件头的大小,读到header_指针处当中,大小是ElfW(Ehdr)类型是elf文件头的大小。VerifyElfHeader则是验证文件头magic、是32-bit还是64-bit、little-endian等等,比较简单就不贴代码了

代码如下


接下来看看ReadProgramHeaders

该方法读取ProgramHeaders,第一个if,说明phdr_num_不得超过2个字节65536,然后根据elf的phdr_num,来计算size_t size = phdr_num_ * sizeof(ElfW(Phdr));,phdr_fragment_.Map会去调用mmap将ProgramHeaders部分映射到内存中,具体的映射结果的地址以及大小,保存在phdr_fragment_类型是 MappedFileFragment当中,至此,程序头表映射完毕。

代码如下



[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-12-3 09:29 被Ayuer编辑 ,原因:
收藏
免费 96
支持
分享
最新回复 (45)
雪    币: 368
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
学习学习
2025-12-3 09:49
0
雪    币: 6120
活跃值: (5900)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
66
2025-12-3 10:35
0
雪    币: 1
活跃值: (926)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
66666666
2025-12-3 10:54
0
雪    币: 112
活跃值: (1557)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
666
2025-12-3 13:54
0
雪    币: 104
活跃值: (7159)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
TQL
2025-12-3 14:22
0
雪    币: 211
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
666
2025-12-3 14:38
0
雪    币: 7
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
1
2025-12-3 14:46
0
雪    币: 1495
活跃值: (3698)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
9
123
2025-12-3 17:49
0
雪    币: 11
活跃值: (720)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
66666666
2025-12-3 21:03
0
雪    币: 105
活跃值: (2272)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
66666666
2025-12-3 21:06
0
雪    币: 2
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
112345
2025-12-3 21:20
0
雪    币: 23
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
666
2025-12-4 09:14
0
雪    币: 5627
活跃值: (9427)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
很ok的
2025-12-4 09:31
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
1
2025-12-4 09:52
0
雪    币: 530
活跃值: (2000)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
666
2025-12-4 10:20
0
雪    币: 244
活跃值: (3040)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
看看
2025-12-4 10:21
0
雪    币: 155
活跃值: (3921)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
看看 
2025-12-4 14:41
0
雪    币: 209
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
666
2025-12-4 17:27
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
666666666666
2025-12-4 17:59
0
雪    币: 18
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
学习
2025-12-4 18:01
0
雪    币: 361
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
22
66666666
2025-12-5 08:16
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
666
2025-12-5 10:01
0
雪    币: 0
活跃值: (1550)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
感谢分享。
2025-12-5 12:26
0
雪    币: 440
活跃值: (812)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
6666
2025-12-5 13:09
0
游客
登录 | 注册 方可回帖
返回