動的置換APKアプリケーションのパフォーマンスの最適化(h)の強化

前のスポークDEX暗号化と復号化を次のDEXは最初、これはDEXエージェント復号化する必要が完了した後、残りの作業を完了するために行くことができます、どのように暗号化と復号化を理解することができます見ていないProxyApplicationを削除するには、その後、我々そのアプリケーションは、私たちのプログラムに追加します。交換したいProxyApplicationは単純なことではありません、あなたが最初に起動する必要があり、今の世界のソースに一緒に皆を持って来るために私を次、それを操作するために、アプリケーションのソースコードに精通しています。

アプリケーションの結合プロセス

APPは、私の他の記事を参照してプロセスを開始することができ、最適化を開始する(a)は、パフォーマンスの最適化を、今日は主から()ActivityThread =>メイン説明するためにフローチャートの隣に始まります。

私たちのアプリケーションでXMLを解析する方法

  • ActivityThread.java

    ミアン() - > thread.attach() - > attachApplication() - ここ> handleBindApplication()準備アプリケーション - - >処理BIND_APPLICATION - =データ>アプリケーションapp> AMSはのsendMessage(H.BIND_APPLICATION)の後に、送信されたパラメータを受け取り、 .info.makeApplication() - > mInitialApplication =アプリ。

  • LoadedApk.java

    このクラスは、メモリ内の表現のAPKで、あなたは、などのコード、データ、機能一覧、などの情報を得ることができます

    1. mApplicationInfo.classNameによる米国で登録された完全なクラス名を取得
    2. アプリ= mActivityThread.mInstrumentation.newApplication()创建アプリケーション
    3. 次はappContext.setOuterContext(アプリ)を使用します
    4. mApplication =アプリ

コンテンツは反射を交換する必要があります

  • ContextImpl - アプリケーションのattachBaseContextコールバックパラメータによって得られた> mOuterContext(APP)
  • ActivityThread - mMainThreadの属性ContextImplによって取得> mAllApplication(ArrayListの)
  • LoadedApk - mPackageInfoにより取得> mApplication ContextImplプロパティ

リフレクションは、アプリケーションを置き換えるために始めました

    boolean isBindReal;
    Application delegate;
    private void bindRealApplicatin() throws Exception {
        if (isBindReal) {
            return;
        }
        if (TextUtils.isEmpty(app_name)) {
            return;
        }
        //得到attachBaseContext(context) 传入的上下文 ContextImpl
        Context baseContext = getBaseContext();
        //创建用户真实的application (MyApplication)
        Class<?> delegateClass = Class.forName(app_name);
        delegate = (Application) delegateClass.newInstance();
        //得到attach()方法
        Method attach = Application.class.getDeclaredMethod("attach", Context.class);
        attach.setAccessible(true);
        attach.invoke(delegate, baseContext);


//        ContextImpl---->mOuterContext(app)   通过Application的attachBaseContext回调参数获取
        Class<?> contextImplClass = Class.forName("android.app.ContextImpl");
        //获取mOuterContext属性
        Field mOuterContextField = contextImplClass.getDeclaredField("mOuterContext");
        mOuterContextField.setAccessible(true);
        mOuterContextField.set(baseContext, delegate);

//        ActivityThread--->mAllApplications(ArrayList)       ContextImpl的mMainThread属性
        Field mMainThreadField = contextImplClass.getDeclaredField("mMainThread");
        mMainThreadField.setAccessible(true);
        Object mMainThread = mMainThreadField.get(baseContext);

//        ActivityThread--->>mInitialApplication
        Class<?> activityThreadClass=Class.forName("android.app.ActivityThread");
        Field mInitialApplicationField = activityThreadClass.getDeclaredField("mInitialApplication");
        mInitialApplicationField.setAccessible(true);
        mInitialApplicationField.set(mMainThread,delegate);
//        ActivityThread--->mAllApplications(ArrayList)       ContextImpl的mMainThread属性
        Field mAllApplicationsField = activityThreadClass.getDeclaredField("mAllApplications");
        mAllApplicationsField.setAccessible(true);
        ArrayList<Application> mAllApplications =(ArrayList<Application>) mAllApplicationsField.get(mMainThread);
        mAllApplications.remove(this);
        mAllApplications.add(delegate);

//        LoadedApk------->mApplication                      ContextImpl的mPackageInfo属性
        Field mPackageInfoField = contextImplClass.getDeclaredField("mPackageInfo");
        mPackageInfoField.setAccessible(true);
        Object mPackageInfo=mPackageInfoField.get(baseContext);

        Class<?> loadedApkClass=Class.forName("android.app.LoadedApk");
        Field mApplicationField = loadedApkClass.getDeclaredField("mApplication");
        mApplicationField.setAccessible(true);
        mApplicationField.set(mPackageInfo,delegate);

        //修改ApplicationInfo className   LooadedApk
        Field mApplicationInfoField = loadedApkClass.getDeclaredField("mApplicationInfo");
        mApplicationInfoField.setAccessible(true);
        ApplicationInfo mApplicationInfo = (ApplicationInfo)mApplicationInfoField.get(mPackageInfo);
        mApplicationInfo.className=app_name;

        delegate.onCreate();
        isBindReal = true;
    }
复制代码

今すぐ再署名パッケージが完了し、私たちの外観APKログを開始

2019-06-04 23:17:30.892 6064-6064/com.yk.dexdeapplication I/DevYK: provider onCreate:com.example.proxy_core.ProxyApplication@1ec3c70
2019-06-04 23:17:30.892 6064-6064/com.yk.dexdeapplication I/DevYK: provider onCreate:com.example.proxy_core.ProxyApplication@1ec3c70
2019-06-04 23:17:30.892 6064-6064/com.yk.dexdeapplication I/DevYK: provider onCreate:com.example.proxy_core.ProxyApplication
2019-06-04 23:17:30.895 6064-6064/com.yk.dexdeapplication I/DevYK: MyApplication onCreate()
2019-06-04 23:17:30.995 6064-6064/com.yk.dexdeapplication I/DevYK: activity:com.yk.dexdeapplication.App@300b5f6
2019-06-04 23:17:30.995 6064-6064/com.yk.dexdeapplication I/DevYK: activity:com.yk.dexdeapplication.App@300b5f6
2019-06-04 23:17:30.995 6064-6064/com.yk.dexdeapplication I/DevYK: activity:com.yk.dexdeapplication.App
2019-06-04 23:17:31.001 6064-6064/com.yk.dexdeapplication I/DevYK: provider delete:com.example.proxy_core.ProxyApplication@1ec3c70
2019-06-04 23:17:31.021 6064-6064/com.yk.dexdeapplication I/DevYK: service:com.yk.dexdeapplication.App@300b5f6
2019-06-04 23:17:31.021 6064-6064/com.yk.dexdeapplication I/DevYK: service:com.yk.dexdeapplication.App@300b5f6
2019-06-04 23:17:31.021 6064-6064/com.yk.dexdeapplication I/DevYK: service:com.yk.dexdeapplication.App
2019-06-04 23:17:31.022 6064-6064/com.yk.dexdeapplication I/DevYK: reciver:android.app.ReceiverRestrictedContext@9b92293
2019-06-04 23:17:31.022 6064-6064/com.yk.dexdeapplication I/DevYK: reciver:com.yk.dexdeapplication.App@300b5f6
2019-06-04 23:17:31.022 6064-6064/com.yk.dexdeapplication I/DevYK: reciver:com.yk.dexdeapplication.App
复制代码

LOGに注意してください。

MyApplication onCreate()
复制代码

ここでは、私たち自身のMyApplicationを、およびサービス活動に置き換えられているとコンテキストが私たちの成功Applicatonを置き換えています。しかし...多分いくつかのよりよい目は、問題は、なぜコンテンツプロバイダまたはエージェントアプリケーション・コンテキストを見ているだけでなく、私たち自身のアプリケーションよりも実行するために、我々は、このアプリケーションでの問題を参照してくださいする前に行うのonCreate何の事。

我々はinstalllContentProviders(アプリ、プロバイダ)をクリックしてください。

合格ノートまたはプロキシコンテキスト

最後の焦点に

、私は割り当てに私たちの団結場合は、当社代理店コンテキストのコンテキストで再びここで、現在のアプリケーションのパッケージ名はXMLでパッケージ名と一致しているかを決定するために概説内部のロジック・ジャッジメントリングに注意してください、そして、我々はルをどのように行いますか私たちは、それが長い間、他行くだろう待機しないエージェントでPackageNameのを書き換え、パッケージ名に応じてコンテキストを作成します

    /**
     * 让代码走入if中的第三段中
     * @return
     */
    @Override
    public String getPackageName() {
        if(!TextUtils.isEmpty(app_name)){
            return "";
        }
        return super.getPackageName();
    }

    @Override
    public Context createPackageContext(String packageName, int flags) throws PackageManager.NameNotFoundException {
       if(TextUtils.isEmpty(app_name)){
           return super.createPackageContext(packageName, flags);
       }
        try {
            bindRealApplicatin();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return delegate;

    }
复制代码
  1. まず、私たち自身のAPP_NAMEのXMLが空であるかどうかを判断します
  2. 空でない場合は、我々は空のパケットを渡します
  3. SDKは最終的に我々はcreatePackageContext着信パケットは、私たち自身のアプリケーションだった書き直す他歩いて、XMLのPCKと同じかどうかを決定します。これは、コンテキストを生成し、

最後に、我々はテストに来ます:

2019-06-05 00:12:30.271 7570-7570/com.yk.dexdeapplication I/DevYK: MyApplication onCreate()
2019-06-05 00:12:30.273 7570-7570/com.yk.dexdeapplication I/DevYK: provider onCreate:com.yk.dexdeapplication.App@1ec3c70
2019-06-05 00:12:30.273 7570-7570/com.yk.dexdeapplication I/DevYK: provider onCreate:com.yk.dexdeapplication.App@1ec3c70
2019-06-05 00:12:30.273 7570-7570/com.yk.dexdeapplication I/DevYK: provider onCreate:com.yk.dexdeapplication.App
2019-06-05 00:12:30.381 7570-7570/com.yk.dexdeapplication I/DevYK: activity:com.yk.dexdeapplication.App@1ec3c70
2019-06-05 00:12:30.381 7570-7570/com.yk.dexdeapplication I/DevYK: activity:com.yk.dexdeapplication.App@1ec3c70
2019-06-05 00:12:30.381 7570-7570/com.yk.dexdeapplication I/DevYK: activity:com.yk.dexdeapplication.App
2019-06-05 00:12:30.387 7570-7570/com.yk.dexdeapplication I/DevYK: provider delete:com.yk.dexdeapplication.App@1ec3c70
2019-06-05 00:12:30.406 7570-7570/com.yk.dexdeapplication I/DevYK: service:com.yk.dexdeapplication.App@1ec3c70
2019-06-05 00:12:30.406 7570-7570/com.yk.dexdeapplication I/DevYK: service:com.yk.dexdeapplication.App@1ec3c70
2019-06-05 00:12:30.406 7570-7570/com.yk.dexdeapplication I/DevYK: service:com.yk.dexdeapplication.App
2019-06-05 00:12:30.408 7570-7570/com.yk.dexdeapplication I/DevYK: reciver:android.app.ReceiverRestrictedContext@b7a3b82
2019-06-05 00:12:30.408 7570-7570/com.yk.dexdeapplication I/DevYK: reciver:com.yk.dexdeapplication.App@1ec3c70
2019-06-05 00:12:30.408 7570-7570/com.yk.dexdeapplication I/DevYK: reciver:com.yk.dexdeapplication.App
复制代码

BroadCaseコンテキストに加え、ログイン、我々はアプリケーション・コンテキストのすべてのコンテキストを交換するシステムです。完璧なソリューション。しかし、隠されたバグがある、それはその後、何ルを依頼する質問に直面すると述べましたか?

あなたは、放送中のサービス・コンテキストを使用するか、それはラジオをオンにバインドすることができますか?

実際には、我々はこの問題の原因を見てみることができます

H - >受信メッセージ

案の定登録放送と結合サービスが例外をスローします。

概要

ここでは、サブDEXから、強化を終えた - >暗号化 - >アライン>署名 - >圧縮APKとしてパッケージ化。プロセスとコードの完全なセットがすでに終了しています。市場プロセスの原理を強化するとほぼ同じです。私はプロのように上に行くために第三者を使用しての原理を理解しています。

コード送信

ます。https://juejin.im/post/5cf69d30f265da1b897abd53で再現

おすすめ

転載: blog.csdn.net/weixin_34391854/article/details/91429554