diff --git a/README.md b/README.md
index c1c9b9bd..a290db5f 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@


-
+
[](https://t.me/XiaofangInternet)
@@ -154,7 +154,16 @@ class MainHook : YukiHookXposedInitProxy {
修正一处注释错误;
临时修复一个 BUG;
增加了 `type` 中的大量 `android` 类型以及少量 `java` 类型;
- 修复新版与旧版 Kotlin APIs 的兼容性问题。
+ 修复新版与旧版 Kotlin APIs 的兼容性问题。
+- 1.0.6
+ 修复 `YukiHookModulePrefs` 在使用一次 `direct` 忽略缓存后每次都忽略的 BUG;
+ 增加新的 API,作废了 `isActive` 判断模块激活的传统用法;
+ 修复非 Xposed 环境使用 API 时打印调试日志的问题;
+ 修复查找 `Field` 时的日志输出问题和未拦截的异常问题;
+ 解耦合 `ReflectionUtils` 中的 Xposed API;
+ 增加 `YukiHookModuleStatus` 方法名称的混淆,以精简模块生成的体积;
+ 装载模块自身 Hook 时将不再打印欢迎信息;
+ 修复上一个版本仍然存在的某些 BUG。
# Cooperations
diff --git a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi_ksp_xposed/YukiHookXposedProcessor.kt b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi_ksp_xposed/YukiHookXposedProcessor.kt
index dfecb37c..6e1a6bca 100644
--- a/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi_ksp_xposed/YukiHookXposedProcessor.kt
+++ b/yukihookapi-ksp-xposed/src/api/kotlin/com/highcapable/yukihookapi_ksp_xposed/YukiHookXposedProcessor.kt
@@ -296,6 +296,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider {
" object : XC_MethodReplacement() {\n" +
" override fun replaceHookedMethod(param: MethodHookParam?) = XposedBridge.getXposedVersion()\n" +
" })\n" +
+ " YukiHookAPI.isModulePackageXposedEnv = true" +
" }\n" +
" YukiHookAPI.modulePackageName = \"$realPackageName\"\n" +
" YukiHookAPI.onXposedLoaded(lpparam)\n" +
diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt
index c8501040..3f974fe1 100644
--- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt
+++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt
@@ -65,10 +65,10 @@ object YukiHookAPI {
private var isXposedInitialized = false
/** 获取当前 [YukiHookAPI] 的版本 */
- const val API_VERSION_NAME = "1.0.55"
+ const val API_VERSION_NAME = "1.0.6"
/** 获取当前 [YukiHookAPI] 的版本号 */
- const val API_VERSION_CODE = 9
+ const val API_VERSION_CODE = 10
/**
* 模块是否装载了 Xposed 回调方法
@@ -80,6 +80,14 @@ object YukiHookAPI {
val isXposedCallbackSetUp
get() = !isXposedInitialized && packageParamCallback != null
+ /**
+ * 当前 Hook 的对象是模块自身
+ *
+ * - ❗这是私有 API - 请勿手动修改 - 会引发未知异常
+ */
+ @DoNotUseField
+ var isModulePackageXposedEnv = false
+
/**
* 预设的 Xposed 模块包名
*
@@ -291,7 +299,7 @@ object YukiHookAPI {
/** 输出欢迎信息调试日志 */
private fun printSplashLog() {
- if (!Configs.isDebug || !isShowSplashLogOnceTime) return
+ if (!Configs.isDebug || !isShowSplashLogOnceTime || isModulePackageXposedEnv) return
isShowSplashLogOnceTime = false
yLoggerI(msg = "Welcome to YukiHookAPI $API_VERSION_NAME($API_VERSION_CODE)! Using $executorName API $executorVersion")
}
diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/FieldFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/FieldFinder.kt
index 8a54ba94..81755de8 100644
--- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/FieldFinder.kt
+++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/FieldFinder.kt
@@ -89,7 +89,7 @@ class FieldFinder(
} catch (e: Throwable) {
Thread {
SystemClock.sleep(10)
- if (isNotIgnoredNoSuchMemberFailure) yLoggerE(msg = "NoSuchField happend in [$classSet] [${hookTag}]", e = e)
+ onFailureMsg(msg = "NoSuchField happend in [$classSet] [${hookTag}]", throwable = e)
}.start()
Result(isNoSuch = true, e)
}
@@ -122,10 +122,17 @@ class FieldFinder(
/**
* 得到变量实例处理类
+ *
+ * - ❗如果目标对象不是静态 - 你必须设置 [instance]
* @param instance 变量所在的实例对象 - 如果是静态可不填 - 默认 null
* @return [Instance]
*/
- fun get(instance: Any? = null) = Instance(instance, give()?.get(instance))
+ fun get(instance: Any? = null) = try {
+ Instance(instance, give()?.get(instance))
+ } catch (e: Throwable) {
+ onFailureMsg(msg = "Try to get field instance failed", throwable = e)
+ Instance(instance, self = null)
+ }
/**
* 得到变量实例
diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/ReflectionUtils.java b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/ReflectionUtils.java
index d12386e3..ff242019 100644
--- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/ReflectionUtils.java
+++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/ReflectionUtils.java
@@ -36,8 +36,8 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
-
-import de.robv.android.xposed.XposedHelpers;
+import java.util.LinkedList;
+import java.util.List;
@SuppressWarnings("ALL")
@DoNotUseClass
@@ -181,10 +181,30 @@ public class ReflectionUtils {
Class> clz = clazz;
if (returnType == null) return findMethodExact(clazz, methodName, parameterTypes);
do {
- Method[] methods = XposedHelpers.findMethodsByExactParameters(clazz, returnType, parameterTypes);
+ Method[] methods = findMethodsByExactParameters(clazz, returnType, parameterTypes);
for (Method method : methods) if (method.getName().equals(methodName)) return method;
} while ((clz = clz.getSuperclass()) != null);
}
throw new IllegalArgumentException("Can't find this method --> name:[" + methodName + "] returnType:[" + returnType.getName() + "] paramType:[" + getParametersString(parameterTypes) + "] in Class [" + clazz.getName() + "] by YukiHookAPI#finder");
}
+
+ private static Method[] findMethodsByExactParameters(Class> clazz, Class> returnType, Class>... parameterTypes) {
+ List result = new LinkedList();
+ for (Method method : clazz.getDeclaredMethods()) {
+ if (returnType != null && returnType != method.getReturnType()) continue;
+ Class>[] methodParameterTypes = method.getParameterTypes();
+ if (parameterTypes.length != methodParameterTypes.length) continue;
+ boolean match = true;
+ for (int i = 0; i < parameterTypes.length; i++) {
+ if (parameterTypes[i] != methodParameterTypes[i]) {
+ match = false;
+ break;
+ }
+ }
+ if (!match) continue;
+ method.setAccessible(true);
+ result.add(method);
+ }
+ return result.toArray(new Method[result.size()]);
+ }
}