4

The background is :

  1. I'm using xposed framework to hook a third party app.
  2. When I hook method XXX, xposed gave me "ClassNotFound" error. I checked and found the method XXX is in a dex file and would be loaded by DexClassLoader on the run.
  3. To hook the method XXX, I need to change the default ClassLoader in xposed to DexClassLoader. To get a DexClassLoader instance, I need a Context instance of the third party app.
  4. Here comes the question: how to get the context instance?

I searched stackoverflow and found someone said you can hook the method in Activity or Receiver to retrieve their context. But I checked the Activity.class and found no method that return Context type value, and only one method has Context type parameter, the onCreateView(String name, Context context, AttributeSet attrs).

Is there any way to get the Context?

18446744073709551615
  • 16,368
  • 4
  • 94
  • 127
Misty Zhu
  • 83
  • 2
  • 7

2 Answers2

8

Xposed already gives you the current hooked apps class loader.

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

As you can see "lpparam.classLoader" is the current apps class loader. I think you may just have typed something incorrectly, are you able to post the code? But you can get the current hooked apps application intense witch can be casted to context. Context context = (Context) AndroidAppHelper.currentApplication();

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

4

The answer from the poster below is more succinct:

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

An alternative hack is to retrieve the current activity (which can be cast to Context) like this:

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

Regarding the class loader, if it consists of the main app classloader then you can retrieve it from LoadPackageParam passed to the handleLoadPackage method.

If the app itself creates a new DexClassLoader then you can hook the DexClassLoader constructor to keep a reference to it. That way you have the actual ClassLoader that contains your class and method. No need to get any context.

4knahs
  • 629
  • 4
  • 14
  • Thank you so much! You are right, in my case, just hooking DexClassLoader is all I need. – Misty Zhu Jun 01 '15 at 07:45
  • This question answers a different question than is asked, while the original author is happy, this is not useful to people looking for an answer to the stated question of "How to get the context" – MrSynAckSter Oct 20 '16 at 18:13
  • The code I posted does retrieve the context and you can keep it in a static field of the class. That said, it does assume that an Activity is launched beforehand but that is ok for most Xposed modules. – 4knahs Oct 21 '16 at 12:43