zoukankan      html  css  js  c++  java
  • Android Native 程序逆向入门(一)—— Native 程序的启动流程

    八月的太阳晒得黄黄的,谁说这世界不是黄金?小雀儿在树荫里打盹,孩子们在草地里打滚。八月的太阳晒得黄黄的,谁说这世界不是黄金?金黄的树林,金黄的草地,小雀们合奏着欢畅的清音:金黄的茅舍,金黄的麦屯,金黄是老农们的笑声。 —— 徐志摩·八月的太阳

    ilocker:关注 Android 安全(新手) QQ: 2597294287

    在生成 native 程序时,在链接阶段会传入一个链接脚本,在该脚本中指定了程序的入口函数。

     

    可以看到,在默认的链接脚本 armelf_linux_eabi.x 中,入口函数指定为“_start”。

    在 NDK 目录下搜索 ldscripts,所有的链接脚本都在该目录中。

    _start 函数定义在 (libc 的 bionic 目录下) Crtbegin.c 中。

     

    在 _start 中又调用了 __libc_init,并将 main 函数的地址作为参数传入。

    再看 __libc_init 的源码 (在 libc 的 bionic 目录下的 Libc_init_static.cpp 文件中):

     

    在 __libc_init 中先进行一些初始化工作,再调用 preinit_array、init_array,最后调用由参数 slingshot 传入的 main 函数。

    上面的描述针对静态链接的程序,对于动态链接的程序还稍有不同。

    对于动态链接 (在 gcc 命令行中指定 -Bdynamic),在生成的可执行文件的 .interp 中保存了程序解释器的文件路径,默认为“/system/bin/linker”。

    当执行动态链接的程序时,系统会解析该 ELF 文件,并找到 .interp 中保存的程序解释器,也就是 android linker。然后先执行 linker,linker 会加载该程序的所依赖的一系列 so,并最后再调用该可执行程序。

    linker 的入口函数 _start 不在 Crtbegin.c 中,而是在 linker 源码的 begin.S 文件中。

     

    调用 __linker_init 函数完成 linker 的“自举”,并进行一些初始化工作,最后会返回原 native 程序的入口函数的地址 (从 native 程序的 ELF Header 中找到)。

    mov pc, r0,跳转到 native 程序的入口函数 (_start) 去执行,接下来的执行过程与上面一样。_start 调用 __libc_init。动态链接程序的 __libc_init 定义在 Libc_init_dynamic.cpp 文件中 (静态链接程序的 __libc_init 定义在 Libc_init_static.cpp 文件中)。

     

    看起来比静态链接程序的 __libc_init 简单点,因为一些初始化工作由 linker 完成了。

    总结:静态链接与动态链接的 native 程序的入口函数都是 _start。动态链接的程序在执行 _start 之前,需要先由 linker 加载依赖库,并进行一些初始化工作。

    学习资料: 《Android 软件安全与逆向分析》

  • 相关阅读:
    葵花宝典,参考学习网站收藏
    安卓工具
    马帮
    C89:vs输出调试信息
    OSG:中级篇 拖拽器类
    OSG:幼儿园篇 第六章 碰撞检测类
    OSG:幼儿园篇 第三章 节点坐标变换类
    OSG:幼儿园篇 第五章 界面交互类
    C++11:智能指针
    OSG:幼儿园篇 第四章 节点回调类
  • 原文地址:https://www.cnblogs.com/ilocker/p/4645308.html
Copyright © 2011-2022 走看看