《Android软件安全与逆向分析》阅读笔记
原生程序的启动流程分析 (P194.)
- GCC命令参数说明
未使用默认C库:
Android 未使用glibc作为C库,而是采用了google自己开发的Bionic C因此编译时需要加入 -nostdlib
静态链接:
gcc 命令参数中指定 -Bstatic,在生成可执行程序时会链接 crtbegin_static.o 与 crtend_android.o。crtbegin_static.o 文件中定义了静态链接的启动函数 _start,这个函数是程序启动时的第一个函数。
动态链接:
需要在gcc命令中指定 -Bdynamic,在生成可执行文件时会链接 crtbegin_dynamic.o 与 crtend_android.o 目标文件,并且动态链接时需要通过 –dynamic-linker 指定 加载器,默认为 /system/bin/linker。在生成的可执行程序中,每个程序都会包含一个 .interp 段存入程序的 加载器。 动态库的启动函数 _start 位于 crtbegin_dynamic.o 文件中。
链接脚本:
无论是动态链接还是静态链接Android原生程序,在链接时都会传入一个链接脚本根据链接时指定参数的不同,所传入的链接脚本也不一样,所有的链接脚本位于Android NDK的 toolchains\arm-linux-android-4.4.3\prebuilt\windows\arm-linux-androideabi\lib\ldscripts 目录。默认情况下链接时会传入 armelf_linux_eabi.x 脚本文件,该文件的第五行代码 ENTRY(_start) 指出程序入口函数为_start。
123456/* 此处省略N行 */OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm","elf32-littlearm")OUTPUT_ARCH(arm)ENTRY(_start)/* 此处省略N行 */
crtbegin_dynamic.S 与 crtbegin_static.S 位于Android源码位置:
bionic\libc\arch-arm\bionic目录下