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

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

概述文章目录一、LoadedApk后续分析二、LoadedApk后续先关源码dex解密时,需要将代理Application替换为真实Application;替换Application首先要理解系统如何注册应用的Application的;一、LoadedApk后续分析在LoadedApk的makeApplication方

文章目录一、LoadedApk 后续分析二、LoadedApk 后续先关源码



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





一、LoadedApk 后续分析

在 LoadedApk 的 makeApplication 方法中 , 调用 mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext) 方法创建出 Application ;

之后将该 Application 设置到 appContext 中 ,

            // 创建应用上下文             ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);            // 创建 Application , 传入三个参数 : 类加载器 , Application 全类名名称 , 上下文            app = mActivityThread.mInstrumentation.newApplication(                    cl, appClass, appContext);                                appContext.setouterContext(app);

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


appContext 是 ContextImpl 类型 , 其 setouterContext 方法 , 将 Application 设置到了 Context 上下文中 ,

class ContextImpl extends Context {    private Context mOuterContext;        final voID setouterContext(Context context) {        mOuterContext = context;    }}

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


ContextImpl 的 private Context mOuterContext 成员就是应用的 Application , 启动后就是默认的替换之前的 Application ;


① Application 设置给了 ContextImpl 的 private Context mOuterContext 成员


继续向下分析 , 此处将创建出的 Application 添加到了 mActivityThread.mAllApplications 集合中 , 该集合位于 ActivityThread 中 ;


② Application 添加到了 ActivityThread 中的 ArrayList<Application> mAllApplications 集合中


然后 Application 有设置给了 LoadedApk 的 mApplication 成员 ;


③ Application 设置给了 LoadedApk 中的 mApplication 成员


        mActivityThread.mAllApplications.add(app);        mApplication = app;

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

public final class ActivityThread {    final ArrayList<Application> mAllApplications            = new ArrayList<Application>();}

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


后面的分支中 instrumentation 不为空 , 不会命中该分支 , 不予考虑 ;

        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);                }            }        }





二、LoadedApk 后续先关源码

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;    }}

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

总结

以上是内存溢出为你收集整理的【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | LoadedApk 后续分析 )全部内容,希望文章能够帮你解决【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | LoadedApk 后续分析 )所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/1057484.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存