如何通过 hook in android 获取 Context
How to get Context through hooking in android
背景是:
- 我正在使用 xposed 框架来挂接第三方应用程序。
- 当我 hook 方法 XXX 时,xposed 给我 "ClassNotFound" 错误。我检查并发现方法 XXX 在 dex 文件中,并且将由 运行.
上的 DexClassLoader 加载
- 为了hook方法XXX,我需要把xposed中默认的ClassLoader改成
DexClassLoader
。要获取 DexClassLoader
实例,我需要第三方应用程序的 Context 实例。
- 问题来了:如何获取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
。无需获取任何上下文。
背景是:
- 我正在使用 xposed 框架来挂接第三方应用程序。
- 当我 hook 方法 XXX 时,xposed 给我 "ClassNotFound" 错误。我检查并发现方法 XXX 在 dex 文件中,并且将由 运行. 上的 DexClassLoader 加载
- 为了hook方法XXX,我需要把xposed中默认的ClassLoader改成
DexClassLoader
。要获取DexClassLoader
实例,我需要第三方应用程序的 Context 实例。 - 问题来了:如何获取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
。无需获取任何上下文。