如何通过在android中挂钩来获取Context

时间:2015-01-21 03:44:54

标签: android hook android-context xposed

背景是:

  1. 我使用xposed框架来挂钩第三方应用。
  2. 当我挂钩方法XXX时,xposed给了我" ClassNotFound"错误。我查了一下,发现方法XXX在一个dex文件中,并且在运行时会被DexClassLoader加载。
  3. 要挂钩方法XXX,我需要将xposed中的默认ClassLoader更改为DexClassLoader。要获得DexClassLoader实例,我需要第三方应用程序的Context实例。
  4. 问题是:如何获取上下文实例?
  5. 我搜索了stackoverflow,发现有人说你可以在Activity或Receiver中挂钩方法来检索它们的上下文。但我检查了Activity.class,发现没有返回Context类型值的方法,只有一个方法有Context类型参数onCreateView(String name, Context context, AttributeSet attrs)

    有没有办法获得上下文?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

以下海报的答案更为简洁:

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。无需获得任何背景信息。