so库远程加载方案管中窥豹

Posted 有心好书

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了so库远程加载方案管中窥豹相关的知识,希望对你有一定的参考价值。

0x01.为什么要so库远程加载?(又叫动态加载)

so体积过大,如果直接集成在apk里面的话,会造成包体积膨胀。所以有了这种方案。运行app的时候,在需要的时候再去下载so库。这样可以减少apk的体积,并且对于推广收益很大。当然不只so库可以这样,所有体积比较大的资源都可以采用这种方案。

0x02.动态加载so库方案原理

android加载so文件的方式有两种:
System.loadLibrary
System.load

    public static void load(String filename) 
        throw new RuntimeException("Stub!");
    

    public static void loadLibrary(String libname) 
        throw new RuntimeException("Stub!");
    

两种方式都可用来装载库文件:

System.load参数必须为库文件的绝对路径

System.loadLibrary参数为库文件名,不包含库文件的扩展名,必须是在JVM属性Java.library.path所指向的路径中,路径可以通过System.getProperty(‘java.library.path’)获得。

所有动态加载的时候我们不能用System.loadLibrary,只能用System.load来加载。

动态加载API写法:

void System.load(String pathName);

说明:
pathName:文件名+文件路径;
该方法调用成功后so文件中的导出函数都将插入的系统提供的一个映射表(类型Map);
注意:

so文件是不能随便放到一个指定的目录然后再通过参数pathName直接引用的。
因为System.load只能加载两个目录路径下的so文件:
** ①/system/lib ;
** ②安装包的路径,即:/data/data//…
而且这两个路径又是有权限保护的不能直接访问;

0x03.代码实现及思路

动态加载SO库流程:

  1. 网络下载 so 文件到指定目录
  2. 从指定下载的目录复制 copy so文件到可动态加载的文件目录下,比如:/data/data/packagename/…
  3. 配置 gradle ,指定 cpu 架构
  4. load 加载

Android 中动态加载 so 文件

具体Demo,参考这个就可以了。时间宝贵,理解原理即可,就不写Demo了。哈哈。

此外,这个只是个Demo,如果用到商业项目上,你需要考虑多方面,比如Android多版本的兼容,安全校验,兜底方案等等。

0x04.开源方案

The Best SoLoader-优雅的so动态加载方案
http://www.duqian.site/2019/05/07/The%20Best%20SoLoader-%E4%BC%98%E9%9B%85%E7%9A%84so%E5%8A%A8%E6%80%81%E5%8A%A0%E8%BD%BD%E6%96%B9%E6%A1%88/

github地址:
https://github.com/duqian291902259/DQ-Android-Labs

参考资料

Android 开发中如何动态加载 so 库文件

以上是关于so库远程加载方案管中窥豹的主要内容,如果未能解决你的问题,请参考以下文章

Android解耦式so库加载方案

Android 逆向Android 进程注入工具开发 ( 远程进程注入动态库文件操作 | 注入动态库 加载 业务动态库 | 业务动态库启动 | pthread_create 线程开发 )

Android NDK常见SO加载错误UnsatisfiedLinkError解决方案

在 Windows 上用 C# 加载 linux 动态库 (.so)

android项目中如何加载已有so库

linux动态库加载的秘密