【Android 安全】DEX 加密 ( Application 替换 | 获取 ContextImpl、ActivityThread、LoadedApk 类型对象 | 源码分析 )

简介: 【Android 安全】DEX 加密 ( Application 替换 | 获取 ContextImpl、ActivityThread、LoadedApk 类型对象 | 源码分析 )

文章目录

一、获取对象类型分析

二、获取 ContextImpl 类型对象

三、获取 ActivityThread、LoadedApk 类型对象



dex 解密时 , 需要将 代理 Application 替换为 真实 Application ; 替换 Application 首先要理解系统如何注册应用的 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 对象 ;



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


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


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



替换上述类型对象中的成员 , 首先要获取到上述 ContextImpl , ActivityThread , LoadedApk 类型的对象 ;


上述三个对象在每个应用中有且仅有一个 , 只要获取到了就是本应用中唯一的对象 ;



使用反射获取上述对象 ;






二、获取 ContextImpl 类型对象


获取 ContextImpl 类型对象 : Application 创建完毕之后 , 就会立刻调用 Application 的 void attachBaseContext(Context base) 函数 , 该函数中的 Context base 参数就是 ContextImpl 类型对象 ;


通过 Application 的 void attachBaseContext(Context base) 回调函数 , 可获取 ContextImpl 对象 ;


public class ContextWrapper extends Context {
    protected void attachBaseContext(Context base) {
        mBase = base;
    }
}




三、获取 ActivityThread、LoadedApk 类型对象


获取 ActivityThread、LoadedApk 类型对象 :


在 LoadedApk 中的 makeApplication 方法中 ,


ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this) ,


通过调用 ContextImpl.createAppContext 函数创建 ContextImpl 对象 ,


传入的第一个参数就是 ActivityThread 对象

传入的第二个参数就是 LoadedApk 对象

 

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                initializeJavaContextClassLoader();
            }
            // ★ 
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
        }
  }
}


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



分析 ContextImpl.createAppContext 方法 , 在该方法中调用了 ContextImpl 的构造方法创建了 ContextImpl 对象 ;


class ContextImpl extends Context {
    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        // 调用构造函数创建了 ContextImpl 对象 
        return new ContextImpl(null, mainThread,
                packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
    }
}


继续查看 ContextImpl 构造函数 , 该构造函数参数很长 , 其第二个参数是 ActivityThread mainThread , 第三个参数是 LoadedApk packageInfo ;


在构造函数中 , mMainThread = mainThread , 构造函数中 ActivityThread mainThread 参数赋值给了 final ActivityThread mMainThread 成员变量 ;


在构造函数中 , mPackageInfo = packageInfo , 构造函数中 LoadedApk packageInfo 参数赋值给了 final LoadedApk mPackageInfo 成员变量 ;


因此可以通过 ContextImpl 类型对象 , 获取其中的


final ActivityThread mMainThread

final LoadedApk mPackageInfo

两个成员变量 , 即可获取到 ActivityThread 和 LoadedApk ;



class ContextImpl extends Context {
  // 应用的 ActivityThread 
    final ActivityThread mMainThread;
    // 应用的 LoadedApk 
    final LoadedApk mPackageInfo;
  // ContextImpl 构造方法 , 只留下分析到的有用代码 , 其余代码删除 
    private ContextImpl(ContextImpl container, ActivityThread mainThread,
            LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
            Display display, Configuration overrideConfiguration, int createDisplayWithId) {
        mOuterContext = this;
        mMainThread = mainThread;
        mPackageInfo = packageInfo;
    }
    static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
        if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
        // 调用构造函数创建了 ContextImpl 对象 
        return new ContextImpl(null, mainThread,
                packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY);
    }
}


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


目录
相关文章
|
Android开发 开发者
Android基础知识:什么是Intent?有哪些类型的Intent?
Android基础知识:什么是Intent?有哪些类型的Intent?
1507 0
|
Android开发 芯片 开发者
adb 查看安卓手机 CPU 类型(armeabi、armeabi-v7a、arm64-v8a ...)
adb 查看安卓手机 CPU 类型(armeabi、armeabi-v7a、arm64-v8a ...)
6175 0
|
编解码 Android开发
Android获取设备各项信息(设备id、ip地址、设备名称、运行商、品牌、型号、分辨率、处理器、国家码、系统语言、网络类型、oaid、android版本、操作系统版本、mac地址、应用程序签名..)1
Android获取设备各项信息(设备id、ip地址、设备名称、运行商、品牌、型号、分辨率、处理器、国家码、系统语言、网络类型、oaid、android版本、操作系统版本、mac地址、应用程序签名..)
1586 1
|
10月前
|
存储 消息中间件 人工智能
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
290 11
【05】AI辅助编程完整的安卓二次商业实战-消息页面媒体对象(Media Object)布局实战调整-按钮样式调整实践-优雅草伊凡
|
编解码 开发工具 Android开发
Android获取设备各项信息(设备id、ip地址、设备名称、运行商、品牌、型号、分辨率、处理器、国家码、系统语言、网络类型、oaid、android版本、操作系统版本、mac地址、应用程序签名..)2
Android获取设备各项信息(设备id、ip地址、设备名称、运行商、品牌、型号、分辨率、处理器、国家码、系统语言、网络类型、oaid、android版本、操作系统版本、mac地址、应用程序签名..)2
1674 2
|
自然语言处理 Go 数据安全/隐私保护
对 int 类型的数据加密,有哪些好的方案?
对 int 类型的数据加密,有哪些好的方案?
333 13
|
SQL 安全 Java
Android经典面试题之Kotlin中object关键字实现的是什么类型的单例模式?原理是什么?怎么实现双重检验锁单例模式?
Kotlin 单例模式概览 在 Kotlin 中,`object` 关键字轻松实现单例,提供线程安全的“饿汉式”单例。例如: 要延迟初始化,可使用 `companion object` 和 `lazy` 委托: 对于参数化的线程安全单例,结合 `@Volatile` 和 `synchronized`
756 6
|
Android开发 Kotlin
Android面试题之kotlin中怎么限制一个函数参数的取值范围和取值类型等
在Kotlin中,限制函数参数可通过类型系统、泛型、条件检查、数据类、密封类和注解实现。例如,使用枚举限制参数为特定值,泛型约束确保参数为Number子类,条件检查如`require`确保参数在特定范围内,数据类封装可添加验证,密封类限制为一组预定义值,注解结合第三方库如Bean Validation进行校验。
618 6
|
存储 Java Android开发
Android上在两个Activity之间传递Bitmap对象
Android上在两个Activity之间传递Bitmap对象
232 2
|
XML Android开发 数据格式
Android五大布局对象---FrameLayout,LinearLayout ,Absolute
Android五大布局对象---FrameLayout,LinearLayout ,Absolute
284 1