美文网首页
动态加载apk

动态加载apk

作者: carlwu_186 | 来源:发表于2022-06-09 17:05 被阅读0次

插桩方式实现

  • 通过dexClassLoader将第三方的apk加载到ClassLoader中。
  • 打开第三方apk时,实际上打开的是父应用的可以空壳activity。先用packageManager加载apk,拿到LauncherActivity的全类名,通过前面的ClassLoader反射实例化apk中的LauncherActivity
  • 父app的空壳activity里面所有的生命周期方法都调用反射拿到的LauncherActivity对应的方法。把父app的空壳activity保存到第三方activity中备用(that)。
  • 由于反射实例化的LauncherActivity是没有上下文的,所以任何使用到了this的方法都要重写,用父app传进来的that代替this
  • 第三方app中会使用到自己的资源文件,所以父空壳activity还需要重写getResources方法,利用AssetManager加载apk得到Resources
  • 这种方法要求了父app的空壳activity在注册时,launchMode必须是standard
  • 第三方appk的activity不需要在自己的Manifest中注册。
  • Service的方式类似Activity。
  • 第三方apk中的动态广播类似Activity。

插件的静态广播接收器必须转换为宿主的动态广播接收器

  • 插件apk里面的静态广播接收器可以在宿主app中以动态广播接收器的方式注册,核心是如何获取插件apk的Manifest中定义的BoradCastReceiver全类名以及对应的Intent-Filter。
  • 借鉴系统如何安装apk,实现静态广播的注册方式。
  • Android系统安装apk:1.把apk文件复制到data/app 目录下。2.开辟存放应用文件的数据 data/data/包名。3.将apk中的dex文件安装到data/dalvik-cache目录下。
  • 真正加载广播接收器,是发生在系统启动时。1.PackageManagerService的main方法被SystemService调用。2.main方法会去扫描data/app目录,拿到apk文件后new一个PackageParser,调用PackageParser.parsePackage(apkFile)方法得到实体PackageParser.Package,里面就包含了解析apk得到的所有四大组件信息。3.PackageParser.parsePackage(apkFile)实现原理:通过AssetManager.addAssetPath(apkPath)拿到AssetManager,然后作为参数拿到apk对应的Resources,可以从Resources获取到AndroidManifest.xml的xml信息。然后就是解析xml信息得到任何四大组件的内容。
  • 拿到了插件apk里面所谓的静态广播接收器的全类名和intent-filter后,就按照动态广播的方式在宿主app中注册一样intent-filter的动态广播接收器,通过反射的方式实例化插件的静态广播接收器,宿主把所有的广播转发给插件。

Hook绕过AMS方式实现

  • 将插件apk的dexElements导入到系统ClassLoader中。
  • 使用DexClassLoader加载一个插件apk,拿到DexClassLoader。这时它的父类BaseDexClassLoader里面有一个 DexPathList pathList 里面有一个成员Element[] dexElements 就是用来存放dex资源的。
  • 同样,系统Context的ClassLoader是PathClassLoader,它也继承自BaseDexClassLoader,所以它也有pathList对象。把插件包的ClassLoader中的dexElements取出,放入到系统Context的ClassLoader中,之后系统就可以直接找到插件包中的class资源了。

双亲委派机制

  • ClassLoader的双亲委派机制:ClassLoader的loadClass方法会优先查找parent:ClassLoader的loadClass方法,parent为空时就到BootstrapClassLoader中查找,如果还是没找到自己的pathList中找。
  • pathList查找的方式是:遍历里面的dexElements,从Element元素中取出dexFile,然后调用到native层找到Class。
  • 所以,dexElements这个数组里面加入插件的dexElements是有讲究的,如果把插件的dexElements插到前面,系统就会优先使用插件里面定义的类,后面的dexFile即使定义了也不会用到它。
  • 有两个Hook点:1. ActivityManager.startActivity,修改Intent的目标地址为宿主APP的一个空壳Activity,骗过AMS的检查。2. 给ActivityThread的sMainThreadHandler指定mCallback,当msg是startActivity类型时还原msg中Intent参数的目标地址为插件中的Activity地址。

插件包中资源文件的加载问题

  • 参考动态换肤,需要重写插件activity的getResources、getAssets两个方法,还需要重写Application的getAssetManager、getResources两个方法。

相关文章

  • Android apk动态加载机制的研究

    动态加载APK

  • activity插件化hook

    动态加载: 加载已安装和未安装的apk 动态加载技术就是使用类加载器加载相应的apk、dex、jar(必须含有de...

  • android插件化学习资料集合

    Android插件化开发 第一篇 [动态加载apk] Android插件化开发 第二篇 [动态加载apk优化] A...

  • Android的动态加载插件

    Android的动态加载插件apk 分析 动态加载主要分为加载使用插件的资源和管理插件的Activity、serv...

  • 动态加载apk

    插桩方式实现 通过dexClassLoader将第三方的apk加载到ClassLoader中。 打开第三方apk时...

  • 动态加载

    动态加载的前提要知道为什么当前的classloader不能加载其他路径的apk?dex动态加载之后能否和之前加载的...

  • Android实现动态加载dex, res, so

    什么是动态加载? - 简单来说动态加载可以加载原本apk不存在的代码。 什么场景适用? 很多场景都适用,比如可以实...

  • 动态加载

    定义 加载so文件 加载dex/jar/apk文件 动态加载的基础就是classloader,一个app中至少需要...

  • 不废话简述android动态加载so库

    优点 1.灵活可以动态更新so库。2.减少apk文件体积,毕竟动态下载不用打包进apk。3.可以解决so库加载冲突...

  • 动态加载框架研究

    动态加载开源项目 ACDD DL dynamic-load-apk android-pluginmgr Direc...

网友评论

      本文标题:动态加载apk

      本文链接:https://www.haomeiwen.com/subject/dwmflrtx.html