文章目录

  • 一、LoadedApk 源码分析
  • 二、LoadedApk 源码 makeApplication 方法分析

dex 解密时 , 需要将 代理 Application 替换为 真实 Application ; 替换 Application 首先要理解系统如何注册应用的 Application 的 ;

一、LoadedApk 源码分析


参考源码 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/LoadedApk.java

上一篇博客讲到 加载 Application 最终调用到的是 android.app.LoadedApk 中的 makeApplication 方法 ;

启用应用时 , Zygote 进程孵化器 fork 出应用进程之后 , 会调用 ActivityThread 的 main 函数 ,

  • 111 个应用对应 111 个 ActivityThread
  • 111 个应用对应 111 个 LoadedApk ;

LoadedApk 是 apk 安装文件在内存中的数据 , 可以在 LoadedApk 中得到 apk 文件中的

  • 代码
  • 资源文件
  • Activity , Service 等组件
  • Manifest 配置文件

等 所有封装在 apk 文件中的信息 ;

LoadedApk.java 中的 makeApplication 方法的作用就是 创建 Application ;

    public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {

LoadedApk 中有一个 mApplication 成员 , private Application mApplication , 该成员就是应用的 Application 对象 ;

如果 mApplication 成员不为空 , 则直接返回该成员 , 该 mApplication 成员表示应用的 Application ;

        if (mApplication != null) {return mApplication;}

此处说明 , 一个应用中 , 只存在一个 Application , 如果下次调用 LoadedApk 的 makeApplication 方法 , 直接将 LoadedApk 找那个的 mApplication 成员返回即可 ;

获取开发者在 AndroidManifest.xml 中注册的 Application , 通过 mApplicationInfo.className 可以获取到该应用在 AndroidManifest.xml 中注册的 Application 全类名 ;

     // 从 ApplicationInfo 对象中获取在 AndroidManifest.xml 中注册的 Application 全类名String appClass = mApplicationInfo.className;

应用跳转 Application , 发送模拟按键 , 都需要使用到 mActivityThread.mInstrumentation , Instrumentation 是一个工具类 , 其可以创建 Activity , 创建 Application , 模拟按键等 ;

            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);appContext.setOuterContext(app);

Instrumentation.java 类参考源码 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/Instrumentation.java 常用方法 :

  • newActivity : 创建 Activity ;
  • newApplication : 创建 Application ;
  • sendKeyDownUpSync : 模拟按键 ;

二、LoadedApk 源码 makeApplication 方法分析


public final class LoadedApk {private Application mApplication;public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {// 如果 mApplication 成员不为空 , 则直接返回该成员 , // 该 mApplication 成员表示应用的 Application// 此处说明 , 一个应用中 , 只存在一个 Application , // 如果下次调用 LoadedApk 的 makeApplication 方法 , // 直接将 LoadedApk 找那个的 mApplication 成员返回即可 ; if (mApplication != null) {return mApplication;}// 声明一个空的 Application 变量 Application app = null;// 从 ApplicationInfo 对象中获取在 AndroidManifest.xml 中注册的 Application 全类名String appClass = mApplicationInfo.className;if (forceDefaultAppClass || (appClass == null)) {appClass = "android.app.Application";}try {// 获取类加载器 java.lang.ClassLoader cl = getClassLoader();// 系统相关应用 , 不会命中该分支 if (!mPackageName.equals("android")) {initializeJavaContextClassLoader();}// 创建应用上下文 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);// 创建 Application , 传入三个参数 : 类加载器 , Application 全类名名称 , 上下文app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);appContext.setOuterContext(app);} catch (Exception e) {if (!mActivityThread.mInstrumentation.onException(app, e)) {throw new RuntimeException("Unable to instantiate application " + appClass+ ": " + e.toString(), e);}}mActivityThread.mAllApplications.add(app);mApplication = app;if (instrumentation != null) {try {instrumentation.callApplicationOnCreate(app);} catch (Exception e) {if (!instrumentation.onException(app, e)) {throw new RuntimeException("Unable to create application " + app.getClass().getName()+ ": " + e.toString(), e);}}}// Rewrite the R 'constants' for all library apks.SparseArray<String> packageIdentifiers = getAssets(mActivityThread).getAssignedPackageIdentifiers();final int N = packageIdentifiers.size();for (int i = 0; i < N; i++) {final int id = packageIdentifiers.keyAt(i);if (id == 0x01 || id == 0x7f) {continue;}rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);}return app;}
}

参考源码 : 6.0.1_r16/xref/frameworks/base/core/java/android/app/LoadedApk.java

【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | LoadedApk 源码分析 )相关推荐

  1. 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | ActivityThread 后续分析 | Application 替换位置 )

    文章目录 一.ActivityThread 后续分析 二.ActivityThread 相关源码 三.Application 替换位置 dex 解密时 , 需要将 代理 Application 替换为 ...

  2. 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | Instrumentation 源码分析 )

    文章目录 一.Instrumentation 源码分析 二.Instrumentation 创建 Application 相关的部分源码 dex 解密时 , 需要将 代理 Application 替换 ...

  3. 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | ActivityThread 源码分析 )

    文章目录 一.ActivityThread 源码分析 二.ActivityThread 部分代码示例 dex 解密时 , 需要将 代理 Application 替换为 真实 Application ; ...

  4. 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | LoadedApk 后续分析 )

    文章目录 一.LoadedApk 后续分析 二.LoadedApk 后续先关源码 dex 解密时 , 需要将 代理 Application 替换为 真实 Application ; 替换 Applic ...

  5. 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 )

    文章目录 一.Zygote 进程孵化器 二.应用启动概述 dex 解密时 , 需要将 代理 Application 替换为 真实 Application ; 替换 Application 首先要理解系 ...

  6. 【Android 安全】DEX 加密 ( Application 替换 | 兼容 ContentProvider 操作 | 源码资源 )

    文章目录 一. 命中 ActivityThread 中 installProvider 方法的分支三 1. 原理分析 2. 代码实现 二. 在 ContextImpl 的 createPackageC ...

  7. 【Android 安全】DEX 加密 ( Application 替换 | 分析 ContentProvider 组件中调用 getApplication() 获取的 Application 二 )

    文章目录 一. ActivityThread 中的 installProvider 方法 ( 创建 ContentProvider 内容提供者 ) 二. installProvider 方法的第三分支 ...

  8. 【Android 安全】DEX 加密 ( Application 替换 | 分析 BroadcastReceiver 组件中调用 getApplication() 获取的 Application )

    文章目录 一. Service 中的 getApplication() 方法分析 二. ActivityThread 中的 H 处理 RECEIVER 消息 三. ActivityThread 中的 ...

  9. 【Android 安全】DEX 加密 ( Application 替换 | 替换 LoadedApk 中的 Application mApplication 成员 )

    文章目录 一. 当前 Application 替换进度 二. 替换 LoadedApk 中的 Application mApplication 成员 一. 当前 Application 替换进度 上一 ...

最新文章

  1. #大学#SQL基础学习笔记(02)
  2. Buffer和Cache的区别
  3. mysql删除默认密码_修改mysql默认密码方法
  4. Android UI(三)SlidingMenu实现滑动菜单(详细 官方)
  5. Kinect+OpenNI+OpenCV使用
  6. java中不用impore导入的_java import机制(不用IDE)
  7. 《关于我的那些面经》——百度后端(附答案)
  8. ZZULIOJ 1105: 判断友好数对(函数专题)
  9. C++ Primer 第五版 第6章 6.1——函数及函数定义及调用习题答案
  10. 二月技术通讯.pdf丨核心数据库一波三折异常重启分析
  11. 分布式技术追踪 2018年第二期
  12. paip.提升用户体验---c++ qt自定义窗体(2)---边框线的绘制
  13. 如何选择适合自己的 Linux 发行版
  14. VPP-20.09版本安装教程(离线版)
  15. 计算机一级中替换,08年计算机一级辅导:实战WPS转义符在查找替换中的应用
  16. 更改我的网页默认的暴风影音播放器
  17. Cisco 防火墙 ASA DHCP 配置
  18. linux gz是什么文件,gz是什么
  19. windows系统下进入jupyter本地服务器(localhost)的步骤
  20. 获取Winform窗体或Panel下包含的所有控件、根据控件名称获取指定控件

热门文章

  1. php中$GLOBALS
  2. Routeros双adsl线路基于ip分段策略路由
  3. solr的认识、linux下安装、java下使用(含下载资源)
  4. web项目开启日志打印
  5. Map集合的几种遍历方式
  6. DataGridView的单元格控制只能输入数字
  7. 开发WebService两种开源工具CXF和Axis2的比较
  8. regression
  9. ROS学习笔记九:ROS工具
  10. ztree实现左边动态生成树,右边为具体信息功能