首页
社区
课程
招聘
[原创] 浅谈ELF可执行文件的启动流程
发表于: 2019-11-17 17:11 9034

[原创] 浅谈ELF可执行文件的启动流程

2019-11-17 17:11
9034

博客:www.wireghost.cn

无论是动态链接还是静态链接的原生程序,在链接阶段都会传入一个链接脚本。根据链接时指定参数的不同,所传入的链接脚本也不一样。在 NDK 目录下检索 ldscripts,所有的链接脚本都在该路径中。默认情况下,会传入armelf_linux_eabi.x脚本文件。

在默认的链接脚本中,声明了可执行文件在进程中的基地址为0x00008000,并将"_start"指定为入口函数。这里,我们可以动手用IDA调试一个原生程序进行对比确认。。

其中,_start函数定义在Android源码路径中的/bionic/libc/arch-arm/bionic/Crtbegin.c

_start方法中调用了_libc_init,并将main函数的地址和指向preinit_array、init_array、fini_array数组的指针作为参数传入。再来看下_libc_init的实现,这部分在Android源码中的路径为/bionic/libc/bionic/libc_init_static.cpp及/bionic/libc/bionic/libc_init_dynamic.cpp,分别对应静态链接和动态链接的程序。
这里,让我们先看下静态链接的部分。在__libc_init中会先进行一些初始化工作,再调用preinit_array、init_array,最后调用由参数slingshot传入的main函数。

静态链接的程序在启动时不需要额外加载其他的动态库,不过这类程序相对较少,Android系统已知的有init、adbd、linker等程序。实际我们遇到的大多数可执行文件都是动态链接的,它的情况较上面的描述稍有不同。动态链接的程序在运行前还需要做一些初始化工作,如运行所依赖的动态库需要先被载入内存。当执行动态链接的程序时,系统会解析该ELF文件,并找到.interp段中所保存的程序解释器,默认是"/system/bin/linker"。然后先执行linker,linker会加载该程序的所依赖的一系列so,最后再调用该可执行程序。
值得注意的是,linker的入口函数_start并不在Crtbegin.c中。在源码/bionic/linker/Android.mk文件中,linker指定了自己的启动函数所在路径,即/bionic/linker/arch/arm/begin.S

首先,调用_linker_init函数完成linker的"自举",并进行一些初始化工作,最后会返回原native程序的入口函数地址(根据native程序的文件头获取)。
至于"mov pc, r0"这条语句,它的作用则是跳转到native程序的入口函数(_start)去执行。
再往后的调用过程与之前已经描述过的一样,都是_start调用_libc_init。此外,前面还提到过,动态链接程序的__libc_init是定义在libc_init_dynamic.cpp文件中。

可以发现,这段代码比静态链接程序的__libc_init还要简单些,这是因为一些初始化工作由linker完成了。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 3
支持
分享
最新回复 (9)
雪    币: 6573
活跃值: (3953)
能力值: (RANK:200 )
在线值:
发帖
回帖
粉丝
2
漂亮 , 可见用心了,赞,这样写出来能分享知识,又能深化记忆和理解, 两者兼得,  如果在linker方面在深入的话,可以从查找符号表,解析重定位,从demo入手符号的生成过程,以及可以tricky(比如常见的脱壳,加壳点,双linker,反调试点,为什么要这么做)的点,再加入自己的理解总结,也可以
2019-11-18 10:03
0
雪    币: 529
活跃值: (1015)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
学习了!多谢分享!
2019-11-20 12:17
0
雪    币: 217
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
学习了,多谢分享
2020-4-13 14:19
0
雪    币: 217
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
LowRebSwrd 漂亮 , 可见用心了,赞,这样写出来能分享知识,又能深化记忆和理解, 两者兼得, 如果在linker方面在深入的话,可以从查找符号表,解析重定位,从demo入手符号的生成过程,以及可以tricky( ...
版主,双linker有学习的文章和资料吗?
2020-4-13 14:26
0
雪    币: 6573
活跃值: (3953)
能力值: (RANK:200 )
在线值:
发帖
回帖
粉丝
6
糊涂先生 版主,双linker有学习的文章和资料吗?
这方面没有主要讲这个的,不过了解linker的加载过程和熟悉源代码自然就知道双linker的运行原理了,还是多了解loader的代码吧。https://segmentfault.com/a/1190000007008889
2020-4-14 10:09
0
雪    币: 217
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
LowRebSwrd 这方面没有主要讲这个的,不过了解linker的加载过程和熟悉源代码自然就知道双linker的运行原理了,还是多了解loader的代码吧。https://segmentfault.com/a/11900 ...
谢谢版主~~
2020-4-14 11:12
0
雪    币: 6573
活跃值: (3953)
能力值: (RANK:200 )
在线值:
发帖
回帖
粉丝
8
糊涂先生 谢谢版主~~
https://www.twblogs.net/a/5bb03e142b7177781a0fe408/zh-cn  还有一篇
2020-4-14 11:15
0
雪    币: 217
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
LowRebSwrd https://www.twblogs.net/a/5bb03e142b7177781a0fe408/zh-cn 还有一篇
我要加倍学习了~再次感谢!
2020-4-14 11:24
0
雪    币: 407
活跃值: (566)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
LowRebSwrd https://www.twblogs.net/a/5bb03e142b7177781a0fe408/zh-cn 还有一篇
这个在论坛内发过 https://bbs.pediy.com/thread-226667.htm
2020-7-12 17:44
0
游客
登录 | 注册 方可回帖
返回
//