android linker (1) —— __linker_init()


__linker_init() 在 begin.S 中被调用,并传入两个参数:sp(堆栈指针)、#0。

linker(动态链接器,也称解释器)本身也是一个 shared object,__linker_init() 负责初始化 linker,完成 linker 的重定位等工作。由于在调用 __linker_init() 之前,linker 的重定位还没有完成(GOT还不可用),所以任何对外部变量或函数的引用都会产生 segfault。

由于 linker 的重定位由其自己完成,所以该过程称为 bootstrap(自举)。


__linker_init() 的第一步是分解参数,把由 sp 参数传入的 argc、argv、环境变量、ELF aux vectors 分别装入KernelArgumentBlock 对象的相应成员中,方便访问。

在 auxv 数组中,类型为 AT_BASE 的项存储有 linker 镜像的开始地址。__linker_init() 由此得到 linker_addr,继而得到 elf_hdr(elf header) 和 phdr(program header) 的地址。


__linker_init() 接着填充一个 soinfo 结构变量。

成员 flags 设置上 FLAG_LINKER,后面见此标记就不会打印调试信息,因为那些调试函数在 linker 完成重定位前尚不可用。

phdr_table_get_load_size() 计算整个 linker 镜像的大小,方法是根据 program header ,找到段内存的最大地址和最小地址,在完成页对齐之后相减。

get_elf_exec_load_bias() 得到 linker 在内存中的加载地址,实际上是第一个可加载段(PT_LOAD)在内存中的虚拟地址。


__linker_init() 接着以 linker_so 作为参数,调用 soinfo_link_image()。

在 soinfo_link_image() 中先找到动态链接段(PT_DYNAMIC)的地址,并得到动态链接结构的数量。然后遍历所有动态链接结构,获取诸如“字符串表地址”、“符号表地址”、“重定位表地址”等重要信息,填充到 soinfo 结构的相应成员中。接着加载所有依赖库,但其实在 linker 自举过程中,它并不依赖于任何其他shared object。重定位工作也是在 soinfo_link_image() 中完成,包括 rel 和 plt_rel(与 PLT 关联的重定位项)。


__linker_init() 最后调用 __linker_init_post_relocation(),从名字可以看出,那些需要在重定位之后才能进行的工作都在这个函数中完成。

__linker_init() 最后返回镜像的入口地址,也就是 elf header 中的 e_entry 保存的虚拟地址。


时间: 2024-08-12 02:43:04

android linker (1) —— __linker_init()的相关文章

【腾讯Bugly干货分享】Android Linker 与 SO 加壳技术

本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57e3a3bc42eb88da6d4be143 作者:王赛 1. 前言 Android 系统安全愈发重要,像传统pc安全的可执行文件加固一样,应用加固是Android系统安全中非常重要的一环.目前Android 应用加固可以分为dex加固和Native加固,Native 加固的保护对象为 Native 层的 SO 文件,使用加壳.反调试.混淆.VM 等手段增加SO文件的反编译难

android app启动过程(转)

Native进程的运行过程 一般程序的启动步骤,可以用下图描述.程序由内核加载分析,使用linker链接需要的共享库,然后从c运行库的入口开始执行. 通常,native进程是由shell或者init启动,启动的过程如下: Shell接收到命令,启动一个程序,此时shell首先会fork一个新的进程 新fork的进程,通过execve系统调用,陷入到内核中,内核检查和加载需要执行的二进制映像文件,检验其合法性及权限.通常用户态进程要启动一个新的程序(如shell),fork后,execve要紧跟着

Android Native 程序逆向入门(一)—— Native 程序的启动流程

八月的太阳晒得黄黄的,谁说这世界不是黄金?小雀儿在树荫里打盹,孩子们在草地里打滚.八月的太阳晒得黄黄的,谁说这世界不是黄金?金黄的树林,金黄的草地,小雀们合奏着欢畅的清音:金黄的茅舍,金黄的麦屯,金黄是老农们的笑声. —— 徐志摩·八月的太阳 ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 在生成 native 程序时,在链接阶段会传入一个链接脚本,在该脚本中指定了程序的入口函数. 可以看到,在默认的链接脚本 armelf_linux_eabi.x 中

android so加载

本文分析so加载的步骤,其实在之前dalvik浅析二中也有提及,但那重点关注的是jni.android中so库的加载,代码如下: loadLibrary("nanosleep"); 我们来看下它的执行流程吧: 先调用dlopen来载入so文件:find_library在soinfo结构(进程加载的so链)中查找当前so是否已载入,否则去执行so载入流程.so载入后,find_library会返回soinfo,去执行so的CallConstructors函数:如果so包含init.ini

Android c/c++ 应用向linux 平台迁移执行

鉴于近期在minicamera (linux + FPGA) 平台上模拟 安卓系统camera流程遭遇不断升级同步的困扰.尤其是 不开放源代码后 , 应用要链接封闭动态库造成的困难.以及在sprdisk上要不断升级对应的minicamera.minicamera 不能随着安卓系统同步升级. 这两个互相交杂在一起的致命问题,严重迟缓了camera 应用和内核驱动的开发測试进度. 在深圳同事的启示下,做最简单的方案尝试 1 将安卓的 c/c++ 应用及其依赖so编译出来. cp到 buildroot

android so壳入口浅析

本文转自http://www.9hao.info/pages/2014/08/android-soke-ru-kou-q 前言   开年来开始接触一些加固样本,基本都对了so进行了处理,拖入ida一看,要么没有 JNI_OnLoad ,要么 JNI_OnLoad 汇编代码羞涩难懂,让人无法下手. JNI_OnLoad 是真正入口么? 先看看几个文档 1 摘自属性服务一节(<深入理解Android卷1>) 利用gcc的constructor属性,这个属性指明了一个__libc_prenit函数(

Android开发技术周报 Issue#66

好消息,Android 开发技术周报开通了邮件订阅,赶快来订阅吧,订阅请戳我戳我戳我,还有还有现在也可以推荐资源给Android开发技术周报了,推荐资源请戳我戳我戳我 新闻 在 Google 看来,应用商店都将消亡,而搜索永存 搜索才是王道,让用户在 Google 搜索结果里直接安装 App 教程 Android Scroller完全解析,关于Scroller你所需知道的一切 郭神新作,详解 Scroller Android应用安全开发之源码安全 实用 APK 反调试技巧 如何自学Android

Android GDB 调试

原文地址:https://github.com/mapbox/mapbox-gl-native/wiki/Android-debugging-with-remote-GDB Android debugging with remote GDB Leith Bade edited this page on Sep 15, 2015 · 17 revisions Pages 18 Home Android 4.x to 5.0 update Android debugging with remote

Android栈溢出漏洞利用练习

在Github上看到一个Linux系统上的栈溢出漏洞利用练习项目: easy-linux-pwn.在原项目基础上,我稍微做了一些改动,将这个项目移植到了Android 9.0系统上: easy-android-pwn.对Android漏洞利用有兴趣的可以练习一下. 由于Android系统与其他Linux桌面系统在安全配置上有下面两方面的差异,导致此项目不能直接在Android系统上使用.需要对系统做一些改动,重新编译ROM(或者仅编译替换linker程序). 即使通过echo 0 | sudo