diff --git a/README.md b/README.md index 4b84d218..9cc35fd6 100644 --- a/README.md +++ b/README.md @@ -9,13 +9,27 @@ # Introduce +## 项目介绍 + - 这是一个使用 Kotlin 重新构建的高效 Xposed Hook API - 名称取自 《ももくり》女主 栗原 雪(Yuki) - 前身为 [开发学习项目](https://github.com/fankes/TMore) 中使用的 Innocent Xposed API,现在重新命名并开源 +# Why YukiHookAPI + +## 它能做什么 + +- 1.模块开发:自动构建程序可以帮你快速创建一个 Xposed 模块,完全省去配置入口类和 xposed_init 文件 +- 2.轻量优雅:拥有一套强大、优雅和人性的 Koltin lambda Hook API,可以帮你快速实现 Method、Constructor、Field 的查找以及 Hook +- 3.高效调试:拥有丰富的调试日志功能,细到每个 Hook 方法的名称、所在类以及查找耗时,可进行快速调试和排错 +- 4.方便移植:原生支持 Xposed API 用法,并原生对接 Xposed API,拥有 Xposed API 的 Hook 框架都能快速对接 YuKiHookAPI +- 5.快速上手:简单易用,不需要繁琐的配置,不需要十足的开发经验,搭建环境集成依赖即可立即开始使用 + # Get Started +## 开始使用 + - 暂定 1.0 版本 - 可做学习参考但暂时不要 Fork 也不要使用 - 还差 Wiki 没有撰写 Demo 没有写完和 API 未提交至 Maven @@ -23,6 +37,8 @@ # License +## 许可证 + - [MIT](https://choosealicense.com/licenses/mit) ``` diff --git a/app/build.gradle b/app/build.gradle index ded8b2cb..c84f8b76 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,6 +5,17 @@ plugins { } android { + signingConfigs { + debug { + storeFile file('../keystore/public') + storePassword '123456' + keyAlias 'public' + keyPassword '123456' + v1SigningEnabled true + v2SigningEnabled true + } + } + compileSdk 31 defaultConfig { @@ -20,6 +31,7 @@ android { buildTypes { release { minifyEnabled false + signingConfig signingConfigs.debug proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } diff --git a/app/src/main/java/com/highcapable/yukihookapi/demo/hook/inject/MainInjecter.kt b/app/src/main/java/com/highcapable/yukihookapi/demo/hook/inject/MainInjecter.kt index a139e8fb..3f312e0f 100644 --- a/app/src/main/java/com/highcapable/yukihookapi/demo/hook/inject/MainInjecter.kt +++ b/app/src/main/java/com/highcapable/yukihookapi/demo/hook/inject/MainInjecter.kt @@ -50,8 +50,10 @@ class MainInjecter : YukiHookXposedInitProxy { override fun onHook() { // 设置模式 - YukiHookAPI.debugTag = "YukiSuki" - YukiHookAPI.isDebug = true + YukiHookAPI.configs { + debugTag = "YukiSuki" + isDebug = true + } // 方案 1 // encase(MainHooker(), SecondHooker()) // 方案 2 @@ -81,7 +83,7 @@ class MainInjecter : YukiHookXposedInitProxy { method { name = "a" param(StringType, StringType) - returnType = UnitType + returnType = StringType } beforeHook { args(index = 0).set("✌️改了前面的") diff --git a/keystore/public b/keystore/public new file mode 100644 index 00000000..4d536971 Binary files /dev/null and b/keystore/public differ 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 ed318c3d..4529d3f7 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 @@ -153,6 +153,7 @@ class YukiHookXposedProcessor : SymbolProcessorProvider { "\n" + "import androidx.annotation.Keep\n" + "import com.highcapable.yukihookapi.YukiHookAPI\n" + + "import com.highcapable.yukihookapi.YukiHookAPI.Configs\n" + "import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus\n" + "import com.highcapable.yukihookapi.hook.log.loggerE\n" + "import de.robv.android.xposed.IXposedHookLoadPackage\n" + @@ -171,8 +172,8 @@ class YukiHookXposedProcessor : SymbolProcessorProvider { " }.onFailure {\n" + " loggerE(msg = \"Try to load $packageName.$className Failed\", e = it)\n" + " }\n" + - " YukiHookAPI.modulePackageName.ifEmpty {\n" + - " YukiHookAPI.modulePackageName = \"$realPackageName\"\n" + + " YukiHookAPI.Configs.modulePackageName.ifEmpty {\n" + + " YukiHookAPI.Configs.modulePackageName = \"$realPackageName\"\n" + " \"$realPackageName\"\n" + " }.also {\n" + " if (lpparam.packageName == it)\n" + diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt index b6fcbf3b..4b0e1012 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/YukiHookAPI.kt @@ -32,11 +32,11 @@ package com.highcapable.yukihookapi import android.content.pm.ApplicationInfo import androidx.annotation.Keep import com.highcapable.yukihookapi.YukiHookAPI.encase -import com.highcapable.yukihookapi.annotation.DoNotUseField import com.highcapable.yukihookapi.annotation.DoNotUseMethod import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.param.CustomParam import com.highcapable.yukihookapi.hook.param.PackageParam +import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus import de.robv.android.xposed.callbacks.XC_LoadPackage /** @@ -49,37 +49,52 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage @Keep object YukiHookAPI { - /** - * 这是一个调试日志的全局标识 - * - * 默认文案为 YukiHookAPI - * - * 你可以修改为你自己的文案 - */ - var debugTag = "YukiHookAPI" - - /** - * 是否开启调试模式 - 默认启用 - * - * 启用后将交由日志输出管理器打印详细 Hook 日志到控制台 - * - * 关闭后将只输出 Error 级别的日志 - * - * 请过滤 [debugTag] 即可找到每条日志 - */ - var isDebug = true - - /** - * Xposed Hook API 绑定的模块包名 - 未写将自动生成 - * - 你不应该设置此变量的名称 - 请使用 [encase] 装载模块包名 - */ - @DoNotUseField - @Keep - var modulePackageName = "" - /** Xposed Hook API 方法体回调 */ private var packageParamCallback: (PackageParam.() -> Unit)? = null + /** + * 配置 YukiHook + */ + object Configs { + + /** + * 这是一个调试日志的全局标识 + * + * 默认文案为 YukiHookAPI + * + * 你可以修改为你自己的文案 + */ + var debugTag = "YukiHookAPI" + + /** + * 是否开启调试模式 - 默认启用 + * + * 启用后将交由日志输出管理器打印详细 Hook 日志到控制台 + * + * 关闭后将只输出 Error 级别的日志 + * + * 请过滤 [debugTag] 即可找到每条日志 + */ + var isDebug = true + + /** + * Xposed Hook API 绑定的模块包名 + * + * - 用于 [YukiHookModuleStatus] 判断模块激活状态 + * + * 未写将自动生成 + */ + @Keep + var modulePackageName = "" + } + + /** + * 配置 YukiHook 相关参数 + * @param initiate 方法体 + * @return [Configs] + */ + fun configs(initiate: Configs.() -> Unit) = Configs.apply(initiate) + /** * 装载 Xposed API 回调 * @@ -92,22 +107,18 @@ object YukiHookAPI { /** * 作为模块装载调用入口方法 - Xposed API - * @param moduleName 你的模块包名 - 可通过 Xposed API 自动生成 * @param initiate Hook 方法体 */ - fun encase(moduleName: String = "", initiate: PackageParam.() -> Unit) { - modulePackageName = moduleName + fun encase(initiate: PackageParam.() -> Unit) { packageParamCallback = initiate } /** * 作为模块装载调用入口方法 - Xposed API - * @param moduleName 你的模块包名 - 可通过 Xposed API 自动生成 * @param hooker Hook 子类数组 - 必填不能为空 * @throws IllegalStateException 如果 [hooker] 是空的 */ - fun encase(moduleName: String = "", vararg hooker: YukiBaseHooker) { - modulePackageName = moduleName + fun encase(vararg hooker: YukiBaseHooker) { packageParamCallback = { if (hooker.isNotEmpty()) hooker.forEach { it.assignInstance(packageParam = this) } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/xposed/InjectYukiHookWithXposed.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/xposed/InjectYukiHookWithXposed.kt index 1f9632f0..337fb0ab 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/xposed/InjectYukiHookWithXposed.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/annotation/xposed/InjectYukiHookWithXposed.kt @@ -48,7 +48,7 @@ import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy * * - 你的模块包名将被这样识别:|com.example.module|.hook... * - * - 若你不喜欢这样创建类 - 没问题 - 请在 [YukiHookAPI.encase] 中自行指定模块包名即可 - 但不按照规则定义包名你将会收到编译警告 + * - 若你不喜欢这样创建类 - 没问题 - 请在 [YukiHookAPI.Configs.modulePackageName] 填写模块包名即可 - 但不按照规则定义包名你将会收到编译警告 * * 例子:YukiHookAPI.encase(moduleName = "com.example.module", ...) * diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiHookCreater.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiHookCreater.kt index 16fe7c45..aca75043 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiHookCreater.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiHookCreater.kt @@ -133,6 +133,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla * * 你只能使用一次 [method] 或 [constructor] 方法 - 否则结果会被替换 * @param initiate 方法体 + * @return [ConstructorFinder.Result] */ fun constructor(initiate: ConstructorFinder.() -> Unit): ConstructorFinder.Result { isHookMemberSetup = true @@ -327,11 +328,11 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla } /** - * Hook 过程中开启了 [YukiHookAPI.isDebug] 输出调试信息 + * Hook 过程中开启了 [YukiHookAPI.Configs.isDebug] 输出调试信息 * @param msg 调试日志内容 */ internal fun onHookLogMsg(msg: String) { - if (YukiHookAPI.isDebug) loggerI(msg = msg) + if (YukiHookAPI.Configs.isDebug) loggerI(msg = msg) } /** @@ -368,7 +369,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla } /** - * 忽略 Hook 进行过程中发生错误 + * 忽略 Hook 进行过程中发生的错误 * @return [Result] 可继续向下监听 */ fun ignoredConductFailure() = onConductFailure { _, _ -> } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/ConstructorFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/ConstructorFinder.kt index 9d1ed721..50482079 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/ConstructorFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/ConstructorFinder.kt @@ -104,7 +104,7 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea inner class RemedyPlan { /** 失败尝试次数数组 */ - private val remedyPlan = HashSet() + private val remedyPlans = HashSet() /** * 创建需要重新查找的 [Constructor] @@ -115,7 +115,7 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea * @param initiate 方法体 */ fun constructor(initiate: ConstructorFinder.() -> Unit) = - remedyPlan.add(ConstructorFinder(hookInstance, hookClass).apply(initiate)) + remedyPlans.add(ConstructorFinder(hookInstance, hookClass).apply(initiate)) /** * 开始重查找 @@ -123,10 +123,10 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea */ @DoNotUseMethod internal fun build() { - if (remedyPlan.isNotEmpty()) run { + if (remedyPlans.isNotEmpty()) run { var isFindSuccess = false var lastError: Throwable? = null - remedyPlan.forEachIndexed { p, it -> + remedyPlans.forEachIndexed { p, it -> runCatching { runBlocking { hookInstance.member = it.result @@ -143,10 +143,10 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea } if (!isFindSuccess) { onFailureMsg( - msg = "trying ${remedyPlan.size} times and all failure by RemedyPlan", + msg = "trying ${remedyPlans.size} times and all failure by RemedyPlan", throwable = lastError ) - remedyPlan.clear() + remedyPlans.clear() } } else loggerW(msg = "RemedyPlan is empty,forgot it? [${hookInstance.tag}]") } 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 4c12e9f9..b24d95ff 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 @@ -37,9 +37,9 @@ import com.highcapable.yukihookapi.hook.utils.runBlocking import java.lang.reflect.Field /** - * Field 查找结果实现类 + * Field 查找类 * - * 可在这里处理找到的 [fieldInstance] + * 可通过执行类型查找指定变量 * @param hookInstance 当前 Hook 实例 * @param hookClass 当前被 Hook 的 [Class] */ diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/MethodFinder.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/MethodFinder.kt index f1d1b651..670a883a 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/MethodFinder.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/finder/MethodFinder.kt @@ -111,7 +111,7 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, inner class RemedyPlan { /** 失败尝试次数数组 */ - private val remedyPlan = HashSet() + private val remedyPlans = HashSet() /** * 创建需要重新查找的 [Method] @@ -121,7 +121,8 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, * 若最后依然失败 - 将停止查找并输出错误日志 * @param initiate 方法体 */ - fun method(initiate: MethodFinder.() -> Unit) = remedyPlan.add(MethodFinder(hookInstance, hookClass).apply(initiate)) + fun method(initiate: MethodFinder.() -> Unit) = + remedyPlans.add(MethodFinder(hookInstance, hookClass).apply(initiate)) /** * 开始重查找 @@ -129,10 +130,10 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, */ @DoNotUseMethod internal fun build() { - if (remedyPlan.isNotEmpty()) run { + if (remedyPlans.isNotEmpty()) run { var isFindSuccess = false var lastError: Throwable? = null - remedyPlan.forEachIndexed { p, it -> + remedyPlans.forEachIndexed { p, it -> runCatching { runBlocking { hookInstance.member = it.result @@ -149,10 +150,10 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, } if (!isFindSuccess) { onFailureMsg( - msg = "trying ${remedyPlan.size} times and all failure by RemedyPlan", + msg = "trying ${remedyPlans.size} times and all failure by RemedyPlan", throwable = lastError ) - remedyPlan.clear() + remedyPlans.clear() } } else loggerW(msg = "RemedyPlan is empty,forgot it? [${hookInstance.tag}]") } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/entity/YukiBaseHooker.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/entity/YukiBaseHooker.kt index 2a9e82b6..0c71300a 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/entity/YukiBaseHooker.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/entity/YukiBaseHooker.kt @@ -40,13 +40,11 @@ import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy * * 你可以继续继承此类进行自定义 Hooker 相关参数 * - * 你可以在 [YukiHookXposedInitProxy] 的 [YukiHookXposedInitProxy.onHook] 中实现如下用法 + * 你可以在 [YukiHookXposedInitProxy] 的 [YukiHookXposedInitProxy.onHook] 中实现如下用法: * - * 第一种方式:调用 [YukiHookAPI.encase] encase(MainHooker(), SecondHooker(), ThirdHooker() ...) + * 1.调用 [YukiHookAPI.encase] encase(MainHooker(), SecondHooker(), ThirdHooker() ...) * - * 第二种方式:调用 [YukiHookAPI.encase] encase(moduleName = "模块包名", MainHooker(), SecondHooker(), ThirdHooker() ...) - * - * 调用 [PackageParam.loadHooker] loadHooker(hooker = CustomHooker()) + * 2.调用 [PackageParam.loadHooker] loadHooker(hooker = CustomHooker()) * * 更多请参考 [InjectYukiHookWithXposed] 中的注释内容 * diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/YukiHookFactory.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/YukiHookFactory.kt index 9371c059..9b4e41c6 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/YukiHookFactory.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/factory/YukiHookFactory.kt @@ -40,11 +40,9 @@ import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy /** * 在 [YukiHookXposedInitProxy] 中装载 [YukiHookAPI] - * @param moduleName 你的模块包名 - 可通过 Xposed API 自动生成 * @param initiate Hook 方法体 */ -fun YukiHookXposedInitProxy.encase(moduleName: String = "", initiate: PackageParam.() -> Unit) = - YukiHookAPI.encase(moduleName, initiate) +fun YukiHookXposedInitProxy.encase(initiate: PackageParam.() -> Unit) = YukiHookAPI.encase(initiate) /** * 在 [YukiHookXposedInitProxy] 中装载 [YukiHookAPI] @@ -53,15 +51,6 @@ fun YukiHookXposedInitProxy.encase(moduleName: String = "", initiate: PackagePar */ fun YukiHookXposedInitProxy.encase(vararg hooker: YukiBaseHooker) = YukiHookAPI.encase(hooker = hooker) -/** - * 在 [YukiHookXposedInitProxy] 中装载 [YukiHookAPI] - * @param moduleName 你的模块包名 - 可通过 Xposed API 自动生成 - * @param hooker Hook 子类数组 - 必填不能为空 - * @throws IllegalStateException 如果 [hooker] 是空的 - */ -fun YukiHookXposedInitProxy.encase(moduleName: String, vararg hooker: YukiBaseHooker) = - YukiHookAPI.encase(moduleName, *hooker) - /** * 判断模块是否在太极、无极中激活 * @return [Boolean] 是否激活 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/log/LoggerFactory.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/log/LoggerFactory.kt index 26b403ec..131a3970 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/log/LoggerFactory.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/log/LoggerFactory.kt @@ -37,10 +37,10 @@ import de.robv.android.xposed.XposedBridge * 向控制台和 [XposedBridge] 打印日志 - D * * [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg] - * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.debugTag] + * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.Configs.debugTag] * @param msg 日志打印的内容 */ -fun loggerD(tag: String = YukiHookAPI.debugTag, msg: String) = runCatching { +fun loggerD(tag: String = YukiHookAPI.Configs.debugTag, msg: String) = runCatching { Log.d(tag, msg) XposedBridge.log("[$tag][D]--> $msg") } @@ -49,10 +49,10 @@ fun loggerD(tag: String = YukiHookAPI.debugTag, msg: String) = runCatching { * 向控制台和 [XposedBridge] 打印日志 - I * * [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg] - * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.debugTag] + * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.Configs.debugTag] * @param msg 日志打印的内容 */ -fun loggerI(tag: String = YukiHookAPI.debugTag, msg: String) = runCatching { +fun loggerI(tag: String = YukiHookAPI.Configs.debugTag, msg: String) = runCatching { Log.i(tag, msg) XposedBridge.log("[$tag][I]--> $msg") } @@ -61,10 +61,10 @@ fun loggerI(tag: String = YukiHookAPI.debugTag, msg: String) = runCatching { * 向控制台和 [XposedBridge] 打印日志 - W * * [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg] - * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.debugTag] + * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.Configs.debugTag] * @param msg 日志打印的内容 */ -fun loggerW(tag: String = YukiHookAPI.debugTag, msg: String) = runCatching { +fun loggerW(tag: String = YukiHookAPI.Configs.debugTag, msg: String) = runCatching { Log.w(tag, msg) XposedBridge.log("[$tag][W]--> $msg") } @@ -73,11 +73,11 @@ fun loggerW(tag: String = YukiHookAPI.debugTag, msg: String) = runCatching { * 向控制台和 [XposedBridge] 打印日志 - E * * [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg] - * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.debugTag] + * @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.Configs.debugTag] * @param msg 日志打印的内容 * @param e 可填入异常堆栈信息 - 将自动完整打印到控制台 */ -fun loggerE(tag: String = YukiHookAPI.debugTag, msg: String, e: Throwable? = null) = runCatching { +fun loggerE(tag: String = YukiHookAPI.Configs.debugTag, msg: String, e: Throwable? = null) = runCatching { Log.e(tag, msg, e) XposedBridge.log("[$tag][E]--> $msg") e?.also { XposedBridge.log(it) } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/type/VariableTypeFactory.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/type/VariableTypeFactory.kt index bbe65679..3fccbfc6 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/type/VariableTypeFactory.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/type/VariableTypeFactory.kt @@ -35,13 +35,13 @@ import java.io.Serializable * 获得 [Any] 类型 * @return [Class] */ -val AnyType get() = Any::class.javaPrimitiveType +val AnyType get() = Any::class.java /** * 获得 [Unit] 类型 * @return [Class] */ -val UnitType get() = Unit::class.javaPrimitiveType +val UnitType get() = Void.TYPE ?: Unit::class.java /** * 获得 [Boolean] 类型 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/proxy/YukiHookXposedInitProxy.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/proxy/YukiHookXposedInitProxy.kt index 0f43de60..652227da 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/proxy/YukiHookXposedInitProxy.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/proxy/YukiHookXposedInitProxy.kt @@ -41,13 +41,31 @@ import com.highcapable.yukihookapi.hook.factory.encase * * Hook 开始时将自动调用 [onHook] 方法 * + * 你可以对 [YukiHookAPI] 进行配置 + * + * 调用 [YukiHookAPI.configs] 进行配置 + * + * .... + * + * YukiHookApi.configs { + * + * ....debugTag = "自定义 TAG" + * + * ....modulePackageName = "模块包名/可选" + * + * ....isDebug = true + * + * } + * + * .... + * * 请在 [onHook] 中调用 [YukiHookAPI.encase] 或直接调用 [encase] * * 可写作如下形式: * * .... * - * override fun onHook() = YukiHookAPI.encase(moduleName = "模块包名/可选") { + * override fun onHook() = YukiHookAPI.encase { * * ....// Your code here. * @@ -59,7 +77,7 @@ import com.highcapable.yukihookapi.hook.factory.encase * * .... * - * override fun onHook() = encase(moduleName = "模块包名/可选") { + * override fun onHook() = encase { * * ....// Your code here. * @@ -71,7 +89,7 @@ import com.highcapable.yukihookapi.hook.factory.encase * * ...... * - * override fun onHook() = encase(moduleName = "模块包名", MainHooker(), SecondHooker(), ThirdHooker() ...) + * override fun onHook() = encase(MainHooker(), SecondHooker(), ThirdHooker() ...) * * ...... * @@ -80,7 +98,13 @@ import com.highcapable.yukihookapi.hook.factory.encase @Keep interface YukiHookXposedInitProxy { - /** 模块装载调用入口方法 - Xposed API */ + /** + * 模块装载调用入口方法 + * + * Xposed API + * + * 调用 [YukiHookAPI.encase] 或直接调用 [encase] 开始 Hook + */ @Keep fun onHook() } \ No newline at end of file