Android .so 文件简析

📅 2026/7/9 15:01:44
Android .so 文件简析
so 文件使用CPU 架构mips / mips64: 极少用于手机可以忽x86 / x86_64: x86 架构的手机都会包含由 Intel 提供的称为 Houdini 的指令集动态转码工具实现对 arm .so 的兼容再考虑 x86 1% 以下的市场占有率x86 相关的两个 .so 也是可以忽略的armeabi: ARM v5 主要 用于 Android 4. 0 之后 的 CPU 是 32 位 的。这是相当老旧的一个版本缺少对浮点数计算的硬件支持在需要大量计算时有性能瓶颈支持 基本 已经 被 淘汰 了armeabi-v7a: ARM v7 目前主流版本向下兼容armeabiarm64-v8a: 主要 用于 Android 5. 0 之后 CPU 是 64 位 的。查找过程。对于一个cpu是arm64-v8a架构的手机它运行app时进入jnilibs去读取库文件时分两种情况先看有没有arm64-v8a文件夹如果没有该文件夹去找armeabi-v7a文件夹如果没有再去找armeabi文件夹如果连这个文件夹也没有就抛出异常如果有arm64-v8a文件夹那么就去找特定名称的.so文件注意如果没有找到不会再往下找了而是直接抛出异常Exception:Java.lang.UnsatisfiedLinkError: dlopen failed: library “/***.so” not found 。兼容性Android 上 启动 每个 App 都会 为 App 创建 一个 虚拟 机。 Android 的 64 位 系统加载 32 位 的 so 或者 App 时 会在 创建 一个 64 位 的 虚拟 机 的 同时 还 创建 一个 32 位 的 虚拟 机 这样 就能 兼容 32 位 的 App 应用 了。所以 在 App 中 保留 一个 armeabi- v7a 版本 的 so 就 足够 了。 64 位 Android 系统 会在 32 位 的 虚拟 机上 加载 它。所有的x86/x86_64/armeabi-v7a/arm64-v8a设备都支持armeabi架构的.so文件.只保留这一套so文件并不保证100%不发生crash特别是对旧设备。也会失去对其他对应CPU架构的一些优化性能有所损失。实践可以全部CPU架构都支持安装包体积会大稳定、性能最佳根据覆盖用户做选择可以只是用armeabi-v7a一套通过设置ndk.abiFilters显示指定支持的ABI栈帧还原调试信息和符号表主要是各种名字以 .debug_ 开头的 section通过这些 section 可以建立 so 每条指令与源码文件的映射关系也就是能够对 so 中每条指令找到其对应的源码文件名、文件行号等信息实际调用的是 NDK 提供的的 strip 命令所用参数为–strip-unneeded删除了调试信息和符号表的 so 只能保证获取到崩溃调用栈的每个栈帧的相应指令在 so 中的位置不一定能获取到符号。带调试信息和符号表的 so 可以将崩溃调用栈的每个栈帧还原成其对应的源码文件名、文件行号、函数名等Hook动态符号表是连接当前 so 与外部环境的“桥梁”PLTProcedure Linkage Table过程链接表用于存储动态链接库中函数的入口地址。当程序调用一个动态链接库中的函数时首先会跳转到PLT中的对应条目然后再通过GOT找到实际的函数地址并执行。GOTGlobal Offset Table全局偏移表用于存储动态链接库中函数和变量的实际地址。在程序运行时动态链接器dynamic linker会根据需要将函数和变量的实际地址填充到GOT中。PLT中的条目会通过GOT来找到函数和变量的实际地址。导出符号存储“ID-地址”的映射关系导入符号记录so 调用其他 so 中的函数