4

背景是:

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

我搜索了stackoverflow,发现有人说您可以在Activity或Receiver中挂钩该方法来检索他们的上下文。但是我检查了 Activity.class 并没有发现返回 Context 类型值的方法,并且只有一个方法具有 Context 类型参数,即onCreateView(String name, Context context, AttributeSet attrs).

有没有办法获取上下文?

4

2 回答 2

8

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

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”是当前应用程序的类加载器。我认为您可能只是输入了错误的内容,您可以发布代码吗?但是你可以得到当前的钩子应用程序应用程序强烈的女巫可以被强制转换为上下文。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

于 2015-02-01T17:08:55.957 回答
4

下面海报的答案更简洁:

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

另一种技巧是检索当前活动(可以转换为上下文),如下所示:

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

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

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

于 2015-02-20T18:29:17.250 回答