如何通过 hook in android 获取 Context

How to get Context through hooking in android

背景是:

  1. 我正在使用 xposed 框架来挂接第三方应用程序。
  2. 当我 hook 方法 XXX 时,xposed 给我 "ClassNotFound" 错误。我检查并发现方法 XXX 在 dex 文件中,并且将由 运行.
  3. 上的 DexClassLoader 加载
  4. 为了hook方法XXX,我需要把xposed中默认的ClassLoader改成DexClassLoader。要获取 DexClassLoader 实例,我需要第三方应用程序的 Context 实例。
  5. 问题来了:如何获取context实例?

我搜索了 Whosebug,发现有人说您可以挂钩 Activity 或 Receiver 中的方法来检索它们的上下文。但是我查看了Activity.class,没有发现return Context类型值的方法,只有一个方法有Context类型参数,onCreateView(String name, Context context, AttributeSet attrs).

有什么方法可以获取上下文吗?

Xposed 已经为您提供了当前的挂钩应用 class 加载器。

public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
        if (!lpparam.packageName.equals("com.android.systemui"))
            return;

        findAndHookMethod("com.android.systemui.statusbar.policy.Clock", lpparam.classLoader, "updateClock", new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                // this will be called before the clock was updated by the original method
            }
            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                // this will be called after the clock was updated by the original method
            }
    });
    }

如您所见,"lpparam.classLoader" 是当前应用 class 加载器。 我认为您可能只是输入了错误的内容,您可以 post 代码吗?但是您可以获得当前的挂钩应用程序应用程序 intense can be cast to context。 Context context = (Context) AndroidAppHelper.currentApplication();

来源:https://github.com/rovo89/XposedBridge/blob/master/src/android/app/AndroidAppHelper.java#L131 资料来源:https://github.com/rovo89/XposedBridge/wiki/Development-tutorial

下面发帖人的回答比较简洁:

Context context = (Context) AndroidAppHelper.currentApplication();

另一种方法是像这样检索当前 activity(可以转换为上下文):

Class<?> instrumentation = XposedHelpers.findClass(
                "android.app.Instrumentation", lpparam.classLoader);

XposedBridge.hookAllMethods(instrumentation, "newActivity", new XC_MethodHook() {

                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {

                    mCurrentActivity = (Activity) param.getResult();

                    Log.v(TAG, "Current Activity : " + mCurrentActivity.getClass().getName());
                }
});

关于 class 加载器,如果它由主应用 classloader 组成,那么您可以从传递给 handleLoadPackage 方法的 LoadPackageParam 中检索它。

如果应用程序本身创建了一个新的 DexClassLoader,那么您可以挂钩 DexClassLoader 构造函数以保留对它的引用。 这样您就拥有了包含您的 class 和方法的实际 ClassLoader。无需获取任何上下文。