【Android 安全】DEX 加密 ( Application 替换 | 判定自定义 Application 存在 | 获取 ContextImpl 对象 )

2023-03-28 20:22:34 浏览数 (1)

文章目录

  • 一、需要替换 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();

0 人点赞