文章目录
一、需要替换 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 元数据 :
<?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 元数据 :
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 ;
// 先判断是否有配置 Application , // 那么在 Manifest.xml 中的 meta-data 元数据 app_name 不为空 // 如果开发者没有自定义 Application , 没有配置元数据 , 直接退出 if (TextUtils.isEmpty(app_name)) { return; }
三、获取上下文对象 ContextImpl
上述可以替换 Application 的 ContextImpl 就是上下文对象 , 在 Application 中调用 getBaseContext() 方法 , 即可获取该对象 ;
// 获取上下文对象 , 保存下来 , 之后要使用 Context baseContext = getBaseContext();