From 045104d1bf58e8a30eab1f3cf36ccc4037d469aa Mon Sep 17 00:00:00 2001 From: solohsu Date: Fri, 25 Jan 2019 00:42:39 +0800 Subject: [PATCH] Add a temporary workaround to fix Application#attach(Context) hook not working --- .../riru/xposed/util/MethodHookUtils.java | 35 +++++++++++++++++++ .../de/robv/android/xposed/XposedBridge.java | 2 ++ 2 files changed, 37 insertions(+) create mode 100644 Bridge/src/main/java/com/elderdrivers/riru/xposed/util/MethodHookUtils.java diff --git a/Bridge/src/main/java/com/elderdrivers/riru/xposed/util/MethodHookUtils.java b/Bridge/src/main/java/com/elderdrivers/riru/xposed/util/MethodHookUtils.java new file mode 100644 index 00000000..256b98a3 --- /dev/null +++ b/Bridge/src/main/java/com/elderdrivers/riru/xposed/util/MethodHookUtils.java @@ -0,0 +1,35 @@ +package com.elderdrivers.riru.xposed.util; + +import android.app.Application; +import android.content.Context; +import android.content.ContextWrapper; + +import java.lang.reflect.Member; +import java.lang.reflect.Method; + +public class MethodHookUtils { + + /** + * FIXME + * Some methods, for instance Application#attach(Context) in framework would be inlined, + * which makes our hooking of them not working. + * Actually we can append --debuggable option to dexoat args to avoid inlining, + * but it has significant impact on app's performance. + * So here is just a temporary workaround. + */ + public static Member preCheck(Member target) { + try { + if (target instanceof Method) { + Method method = (Method) target; + if (method.getDeclaringClass().equals(Application.class) + && method.getName().equals("attach")) { + return ContextWrapper.class.getDeclaredMethod("attachBaseContext", Context.class); + } + } + } catch (Throwable throwable) { + Utils.logE("error when preCheck " + target, throwable); + } + return target; + } + +} diff --git a/Bridge/src/main/java/de/robv/android/xposed/XposedBridge.java b/Bridge/src/main/java/de/robv/android/xposed/XposedBridge.java index 07f2b55f..55badbca 100644 --- a/Bridge/src/main/java/de/robv/android/xposed/XposedBridge.java +++ b/Bridge/src/main/java/de/robv/android/xposed/XposedBridge.java @@ -6,6 +6,7 @@ import android.util.Log; import com.elderdrivers.riru.xposed.core.HookMain; import com.elderdrivers.riru.xposed.dexmaker.DynamicBridge; import com.elderdrivers.riru.xposed.dexmaker.MethodInfo; +import com.elderdrivers.riru.xposed.util.MethodHookUtils; import java.io.File; import java.io.IOException; @@ -154,6 +155,7 @@ public final class XposedBridge { * @see #hookAllConstructors */ public static XC_MethodHook.Unhook hookMethod(Member hookMethod, XC_MethodHook callback) { + hookMethod = MethodHookUtils.preCheck(hookMethod); if (!(hookMethod instanceof Method) && !(hookMethod instanceof Constructor)) { throw new IllegalArgumentException("Only methods and constructors can be hooked: " + hookMethod.toString()); } else if (hookMethod.getDeclaringClass().isInterface()) {