From c5791951db9b8da95e0856aa80d4e5e7f44d36f3 Mon Sep 17 00:00:00 2001 From: solohsu Date: Sun, 16 Jun 2019 00:53:21 +0800 Subject: [PATCH] Fix exceptions when hooking pending methods --- appveyor.yml | 2 +- .../riru/edxp/art/ClassLinker.java | 4 ++-- edxp-core/build.gradle | 4 ++-- .../main/include/art/runtime/mirror/class.h | 12 +++++++++- .../src/main/cpp/main/src/edxp_context.cpp | 11 +++++++-- .../common/util_functions.sh | 2 +- .../de/robv/android/xposed/PendingHooks.java | 24 +++++++++++++++++++ .../de/robv/android/xposed/XposedBridge.java | 21 ++-------------- 8 files changed, 52 insertions(+), 28 deletions(-) create mode 100644 xposed-bridge/src/main/java/de/robv/android/xposed/PendingHooks.java diff --git a/appveyor.yml b/appveyor.yml index e1c62129..12f8182b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -36,4 +36,4 @@ only_commits: - gradle.properties - appveyor.yml -version: '0.4.4.4_alpha (4441) {build}' +version: '0.4.4.5_alpha (4450) {build}' diff --git a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/art/ClassLinker.java b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/art/ClassLinker.java index 5d2eeeb9..a99cf092 100644 --- a/edxp-common/src/main/java/com/elderdrivers/riru/edxp/art/ClassLinker.java +++ b/edxp-common/src/main/java/com/elderdrivers/riru/edxp/art/ClassLinker.java @@ -4,13 +4,13 @@ import com.elderdrivers.riru.common.KeepAll; import java.lang.reflect.Member; -import de.robv.android.xposed.XposedBridge; +import de.robv.android.xposed.PendingHooks; public class ClassLinker implements KeepAll { public static native void setEntryPointsToInterpreter(Member method); public static void onPostFixupStaticTrampolines(Class clazz) { - XposedBridge.hookPendingMethod(clazz); + PendingHooks.hookPendingMethod(clazz); } } diff --git a/edxp-core/build.gradle b/edxp-core/build.gradle index bcdb23c5..6e9f38d0 100644 --- a/edxp-core/build.gradle +++ b/edxp-core/build.gradle @@ -3,10 +3,10 @@ import org.gradle.internal.os.OperatingSystem apply plugin: 'com.android.library' -version "v0.4.4.4_alpha" +version "v0.4.4.5_alpha" ext { - versionCode = "4441" + versionCode = "4450" module_name = "EdXposed" jar_dest_dir = "${projectDir}/template_override/system/framework/" is_windows = OperatingSystem.current().isWindows() diff --git a/edxp-core/src/main/cpp/main/include/art/runtime/mirror/class.h b/edxp-core/src/main/cpp/main/include/art/runtime/mirror/class.h index 38d6122c..72eb8f2c 100644 --- a/edxp-core/src/main/cpp/main/include/art/runtime/mirror/class.h +++ b/edxp-core/src/main/cpp/main/include/art/runtime/mirror/class.h @@ -16,7 +16,10 @@ namespace art { CREATE_FUNC_SYMBOL_ENTRY(const char *, GetDescriptor, void *thiz, std::string *storage) { - return GetDescriptorSym(thiz, storage); + if (GetDescriptorSym) + return GetDescriptorSym(thiz, storage); + else + return ""; } CREATE_HOOK_STUB_ENTRIES(bool, IsInSamePackage, void *thiz, void *that) { @@ -57,6 +60,13 @@ namespace art { // HOOK_FUNC(ClassForName, // "_ZN3artL18Class_classForNameEP7_JNIEnvP7_jclassP8_jstringhP8_jobject"); } + + const char *GetDescriptor(std::string *storage) { + if (thiz_ && GetDescriptorSym) { + return GetDescriptor(thiz_, storage); + } + return ""; + } }; } // namespace mirror diff --git a/edxp-core/src/main/cpp/main/src/edxp_context.cpp b/edxp-core/src/main/cpp/main/src/edxp_context.cpp index 831d8d8c..dd2a6640 100644 --- a/edxp-core/src/main/cpp/main/src/edxp_context.cpp +++ b/edxp-core/src/main/cpp/main/src/edxp_context.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "edxp_context.h" #include "config_manager.h" @@ -36,11 +38,16 @@ namespace edxp { if (UNLIKELY(!post_fixup_static_mid_ || !class_linker_class_)) { return; } + if (!class_ptr) { + return; + } JNIEnv *env; vm_->GetEnv((void **) (&env), JNI_VERSION_1_4); art::JNIEnvExt env_ext(env); ScopedLocalRef clazz(env, env_ext.NewLocalRefer(class_ptr)); - JNI_CallStaticVoidMethod(env, class_linker_class_, post_fixup_static_mid_, clazz.get()); + if (clazz != nullptr) { + JNI_CallStaticVoidMethod(env, class_linker_class_, post_fixup_static_mid_, clazz.get()); + } } void Context::LoadDexAndInit(JNIEnv *env, const char *dex_path) { @@ -169,7 +176,7 @@ namespace edxp { if (LIKELY(mid)) { va_list args; va_start(args, method_sig); - env->functions->CallStaticVoidMethodV(env, entry_class_, mid, args); + env->CallStaticVoidMethodV(entry_class_, mid, args); va_end(args); } else { LOGE("method %s id is null", method_name); diff --git a/edxp-core/template_override/common/util_functions.sh b/edxp-core/template_override/common/util_functions.sh index 99ef6b28..00ca706c 100644 --- a/edxp-core/template_override/common/util_functions.sh +++ b/edxp-core/template_override/common/util_functions.sh @@ -1,6 +1,6 @@ #!/system/bin/sh -EDXP_VERSION="0.4.4.4_alpha (4441)" +EDXP_VERSION="0.4.4.5_alpha (4450)" ANDROID_SDK=`getprop ro.build.version.sdk` BUILD_DESC=`getprop ro.build.description` PRODUCT=`getprop ro.build.product` diff --git a/xposed-bridge/src/main/java/de/robv/android/xposed/PendingHooks.java b/xposed-bridge/src/main/java/de/robv/android/xposed/PendingHooks.java new file mode 100644 index 00000000..ea843829 --- /dev/null +++ b/xposed-bridge/src/main/java/de/robv/android/xposed/PendingHooks.java @@ -0,0 +1,24 @@ +package de.robv.android.xposed; + +import java.lang.reflect.Member; +import java.util.concurrent.ConcurrentHashMap; + +import static de.robv.android.xposed.XposedBridge.hookMethodNative; + +public final class PendingHooks { + + private static final ConcurrentHashMap + sPendingHookMethods = new ConcurrentHashMap<>(); + + public synchronized static void hookPendingMethod(Class clazz) { + for (Member member : sPendingHookMethods.keySet()) { + if (member.getDeclaringClass().equals(clazz)) { + hookMethodNative(member, clazz, 0, sPendingHookMethods.get(member)); + } + } + } + + public synchronized static void recordPendingMethod(Member hookMethod, XposedBridge.AdditionalHookInfo additionalInfo) { + sPendingHookMethods.put(hookMethod, additionalInfo); + } +} diff --git a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java index fdaea140..9be482d2 100644 --- a/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java +++ b/xposed-bridge/src/main/java/de/robv/android/xposed/XposedBridge.java @@ -18,7 +18,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import dalvik.system.InMemoryDexClassLoader; import de.robv.android.xposed.XC_MethodHook.MethodHookParam; @@ -235,29 +234,13 @@ public final class XposedBridge { if (reflectMethod != null) { hookMethodNative(reflectMethod, declaringClass, slot, additionalInfo); } else { - synchronized (pendingLock) { - sPendingHookMethods.put(hookMethod, additionalInfo); - } + PendingHooks.recordPendingMethod(hookMethod, additionalInfo); } } return callback.new Unhook(hookMethod); } - private static final ConcurrentHashMap - sPendingHookMethods = new ConcurrentHashMap<>(); - private static final Object pendingLock = new Object(); - - public static void hookPendingMethod(Class clazz) { - synchronized (pendingLock) { - for (Member member : sPendingHookMethods.keySet()) { - if (member.getDeclaringClass().equals(clazz)) { - hookMethodNative(member, clazz, 0, sPendingHookMethods.get(member)); - } - } - } - } - /** * Removes the callback for a hooked method/constructor. * @@ -448,7 +431,7 @@ public final class XposedBridge { * Intercept every call to the specified method and call a handler function instead. * @param method The method to intercept */ - private synchronized static void hookMethodNative(final Member method, Class declaringClass, + /*package*/ synchronized static void hookMethodNative(final Member method, Class declaringClass, int slot, final Object additionalInfoObj) { EdXpConfigGlobal.getHookProvider().hookMethod(method, (AdditionalHookInfo) additionalInfoObj); }