文章目录
- 一、需要替换 Application 位置
- 二、判定是否有自定义 Application
- 三、获取上下文对象 ContextImpl
dex 解密时 , 需要将 代理 Application 替换为 真实 Application ; 替换 Application 首先要理解系统如何注册应用的 Application 的 ;
一、需要替换 Application 位置
1. 需要替换 Application 位置 :
替换 Application 就是需要替换下面各个类型对象的对应 Application 成员 ;
① ContextImpl 的 private Context mOuterContext 成员是 kim.hsl.multipledex.ProxyApplication 对象 ;
② ActivityThread 中的 ArrayList<Application> mAllApplications 集合中添加了 kim.hsl.multipledex.ProxyApplication 对象 ;
③ LoadedApk 中的 mApplication 成员是 kim.hsl.multipledex.ProxyApplication 对象 ;
④ ActivityThread 中的 Application mInitialApplication 成员是 kim.hsl.multipledex.ProxyApplication 对象 ;
2. 获取 ContextImpl , ActivityThread , LoadedApk 方法 :
在 【Android 安全】DEX 加密 ( Application 替换 | 获取 ContextImpl、ActivityThread、LoadedApk 类型对象 | 源码分析 ) 博客中分析了获取 ContextImpl , ActivityThread , LoadedApk 类型的对象的方法 ,
- ContextImpl : 从 Application 的 attachBaseContext(Context base) 方法中获取 ContextImpl 对象 , ContextImpl 对象就是该方法的参数 ;
- ActivityThread : 从 ContextImpl 对象中获取其 ActivityThread mMainThread 成员变量 ;
- LoadedApk : 从 ContextImpl 对象中获取其 LoadedApk mPackageInfo 成员变量 ;
二、判定是否有自定义 Application
开发者如果自定义了 Application , 需要手动在主应用的 AndroidManifest.xml 中配置如下 app_name 元数据 :
代码语言:javascript复制<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kim.hsl.dex">
<application>
<!-- app_name 值是该应用的 Application 的真实全类名
真实 Application : kim.hsl.dex.MyApplication
代理 Application : kim.hsl.multipledex.ProxyApplication -->
<meta-data android:name="app_name" android:value="kim.hsl.dex.MyApplication"/>
</application>
</manifest>
如果用户没有自定义 Application , 则不配置 app_name 元数据 ;
获取 app_name 元数据 :
代码语言:javascript复制 applicationInfo = getPackageManager().getApplicationInfo(
getPackageName(),
PackageManager.GET_META_DATA
);
Bundle metaData = applicationInfo.metaData;
if (metaData != null) {
// 检查是否存在 app_name 元数据
if (metaData.containsKey("app_name")) {
app_name = metaData.getString("app_name").toString();
}
}
判断 app_name 是否为空 , 如果为空 , 说明开发者没有定义自定义的 Application , 这里不需要替换 Application ;
代码语言:javascript复制 // 先判断是否有配置 Application ,
// 那么在 Manifest.xml 中的 meta-data 元数据 app_name 不为空
// 如果开发者没有自定义 Application , 没有配置元数据 , 直接退出
if (TextUtils.isEmpty(app_name)) {
return;
}
三、获取上下文对象 ContextImpl
上述可以替换 Application 的 ContextImpl 就是上下文对象 , 在 Application 中调用 getBaseContext() 方法 , 即可获取该对象 ;
代码语言:javascript复制 // 获取上下文对象 , 保存下来 , 之后要使用
Context baseContext = getBaseContext();