From 159c65d6b26ea6a5fdc7305a56eee76b13ce23f6 Mon Sep 17 00:00:00 2001 From: LoveSy Date: Tue, 15 Mar 2022 15:59:57 +0800 Subject: [PATCH] Fix predefined deoptmization (#1759) --- .../lspd/deopt/InlinedMethodCallers.java | 52 +++++++++++-------- .../lspd/deopt/PrebuiltMethodsDeopter.java | 20 ++++--- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/org/lsposed/lspd/deopt/InlinedMethodCallers.java b/core/src/main/java/org/lsposed/lspd/deopt/InlinedMethodCallers.java index 2de51c14..5d46d402 100644 --- a/core/src/main/java/org/lsposed/lspd/deopt/InlinedMethodCallers.java +++ b/core/src/main/java/org/lsposed/lspd/deopt/InlinedMethodCallers.java @@ -20,6 +20,14 @@ package org.lsposed.lspd.deopt; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.res.AssetManager; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.util.DisplayMetrics; +import android.util.TypedValue; + import java.util.HashMap; /** @@ -40,38 +48,38 @@ public class InlinedMethodCallers { * Key should be {@link #KEY_BOOT_IMAGE}, {@link #KEY_SYSTEM_SERVER}, or a package name * of system apps or priv-apps i.e. com.android.systemui */ - private static final HashMap CALLERS = new HashMap<>(); + private static final HashMap CALLERS = new HashMap<>(); /** * format for each row: {className, methodName, methodSig} */ - private static final String[][] BOOT_IMAGE = { + private static final Object[][] BOOT_IMAGE = { // callers of Application#attach(Context) - {"android.app.Instrumentation", "newApplication", "(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Context;)Landroid/app/Application;"}, - {"android.app.Instrumentation", "newApplication", "(Ljava/lang/ClassLoader;Landroid/content/Context;)Landroid/app/Application;"}, + {"android.app.Instrumentation", "newApplication", ClassLoader.class, String.class, Context.class}, + {"android.app.Instrumentation", "newApplication", ClassLoader.class, Context.class}, }; // TODO deprecate this - private static final String[][] BOOT_IMAGE_FOR_MIUI_RES = { + private static final Object[][] BOOT_IMAGE_FOR_MIUI_RES = { // for MIUI resources hooking - {"android.content.res.MiuiResources", "init", "(Ljava/lang/String;)V"}, - {"android.content.res.MiuiResources", "updateMiuiImpl", "()V"}, - {"android.content.res.MiuiResources", "setImpl", "(Landroid/content/res/ResourcesImpl;)V"}, - {"android.content.res.MiuiResources", "loadOverlayValue", "(Landroid/util/TypedValue;I)V"}, - {"android.content.res.MiuiResources", "getThemeString", "(I)Ljava/lang/CharSequence;"}, - {"android.content.res.MiuiResources", "", "(Ljava/lang/ClassLoader;)V"}, - {"android.content.res.MiuiResources", "", "()V"}, - {"android.content.res.MiuiResources", "", "(Landroid/content/res/AssetManager;Landroid/util/DisplayMetrics;Landroid/content/res/Configuration;)V"}, - {"android.miui.ResourcesManager", "initMiuiResource", "(Landroid/content/res/Resources;Ljava/lang/String;)V"}, - {"android.app.LoadedApk", "getResources", "()Landroid/content/res/Resources;"}, - {"android.content.res.Resources", "getSystem", "()Landroid/content/res/Resources;"}, - {"android.app.ApplicationPackageManager", "getResourcesForApplication", "(Landroid/content/pm/ApplicationInfo;)Landroid/content/res/Resources;"}, - {"android.app.ContextImpl", "setResources", "(Landroid/content/res/Resources;)V"}, + {"android.content.res.MiuiResources", "init", String.class}, + {"android.content.res.MiuiResources", "updateMiuiImpl"}, + {"android.content.res.MiuiResources", "setImpl", "android.content.res.ResourcesImpl"}, + {"android.content.res.MiuiResources", "loadOverlayValue", TypedValue.class, int.class}, + {"android.content.res.MiuiResources", "getThemeString", CharSequence.class}, + {"android.content.res.MiuiResources", "", ClassLoader.class}, + {"android.content.res.MiuiResources", ""}, + {"android.content.res.MiuiResources", "", AssetManager.class, DisplayMetrics.class, Configuration.class}, + {"android.miui.ResourcesManager", "initMiuiResource", Resources.class, String.class}, + {"android.app.LoadedApk", "getResources", Resources.class}, + {"android.content.res.Resources", "getSystem", Resources.class}, + {"android.app.ApplicationPackageManager", "getResourcesForApplication", ApplicationInfo.class}, + {"android.app.ContextImpl", "setResources", Resources.class}, }; - private static final String[][] SYSTEM_SERVER = {}; + private static final Object[][] SYSTEM_SERVER = {}; - private static final String[][] SYSTEM_UI = {}; + private static final Object[][] SYSTEM_UI = {}; static { CALLERS.put(KEY_BOOT_IMAGE, BOOT_IMAGE); @@ -80,11 +88,11 @@ public class InlinedMethodCallers { CALLERS.put("com.android.systemui", SYSTEM_UI); } - public static HashMap getAll() { + public static HashMap getAll() { return CALLERS; } - public static String[][] get(String where) { + public static Object[][] get(String where) { return CALLERS.get(where); } } diff --git a/core/src/main/java/org/lsposed/lspd/deopt/PrebuiltMethodsDeopter.java b/core/src/main/java/org/lsposed/lspd/deopt/PrebuiltMethodsDeopter.java index d7ea240b..8c14877f 100644 --- a/core/src/main/java/org/lsposed/lspd/deopt/PrebuiltMethodsDeopter.java +++ b/core/src/main/java/org/lsposed/lspd/deopt/PrebuiltMethodsDeopter.java @@ -25,6 +25,7 @@ import static org.lsposed.lspd.deopt.InlinedMethodCallers.KEY_BOOT_IMAGE_MIUI_RE import static org.lsposed.lspd.deopt.InlinedMethodCallers.KEY_SYSTEM_SERVER; import org.lsposed.lspd.nativebridge.HookBridge; +import org.lsposed.lspd.util.Hookers; import org.lsposed.lspd.util.Utils; import java.lang.reflect.Executable; @@ -35,18 +36,25 @@ import de.robv.android.xposed.XposedHelpers; public class PrebuiltMethodsDeopter { public static void deoptMethods(String where, ClassLoader cl) { - String[][] callers = InlinedMethodCallers.get(where); + Object[][] callers = InlinedMethodCallers.get(where); if (callers == null) { return; } - for (String[] caller : callers) { + for (Object[] caller : callers) { try { - Class clazz = XposedHelpers.findClassIfExists(caller[0], cl); - if (clazz == null) { - continue; + if (caller.length < 2) continue; + if (!(caller[0] instanceof String)) continue; + if (!(caller[1] instanceof String)) continue; + Executable method; + Object[] params = new Object[caller.length - 2]; + System.arraycopy(caller, 2, params, 0, params.length); + if ("".equals(caller[1])) { + method = XposedHelpers.findConstructorExactIfExists((String) caller[0], cl, params); + } else { + method = XposedHelpers.findMethodExactIfExists((String) caller[0], cl, (String) caller[1], params); } - Executable method = null; if (method != null) { + Hookers.logD("deoptimizing " + method); HookBridge.deoptimizeMethod(method); } } catch (Throwable throwable) {