From c9fa5034c4a1b73a0dfddd39e8865e68814ffb83 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Tue, 6 Sep 2022 01:08:34 +0800 Subject: [PATCH] Modify move clazz, hasClass to toAppClass, hasClass function and add isForceUseAbsolute param to Class.hook function --- docs/api/public/PackageParam.md | 85 ++++++++++++++----- .../yukihookapi/hook/param/PackageParam.kt | 85 ++++++++++++++----- 2 files changed, 126 insertions(+), 44 deletions(-) diff --git a/docs/api/public/PackageParam.md b/docs/api/public/PackageParam.md index 8ebef8f6..46f1839c 100644 --- a/docs/api/public/PackageParam.md +++ b/docs/api/public/PackageParam.md @@ -428,23 +428,43 @@ fun loadHooker(hooker: YukiBaseHooker) 你可以填入 `hooker` 在 Hooker 中继续装载 Hooker。 -### String.clazz *- i-ext-field* - -```kotlin -val String.clazz: Class<*> -``` - -```kotlin -val VariousClass.clazz: Class<*> -``` +### ~~String+VariousClass.clazz *- i-ext-field*~~ **变更记录** `v1.0` `添加` +`v1.0.93` `作废` + +请转移到 `toAppClass()` 方法 + +### ~~String.hasClass *- i-ext-field*~~ + +**变更记录** + +`v1.0` `添加` + +`v1.0.93` `作废` + +请转移到 `hasClass(...)` 方法 + +### String+VariousClass.toAppClass *- i-ext-method* + +```kotlin +fun String.toAppClass(): Class<*> +``` + +```kotlin +fun VariousClass.toAppClass(): Class<*> +``` + +**变更记录** + +`v1.0.93` `新增` + **功能描述** -> 字符串、`VariousClass` 转换为实体类。 +> 通过字符串类名、`VariousClass` 转换为当前 Hook APP 的实体类。 使用当前 `appClassLoader` 装载目标 `Class`。 @@ -455,7 +475,7 @@ val VariousClass.clazz: Class<*> > 示例如下 ```kotlin -"com.example.demo.DemoClass".clazz +"com.example.demo.DemoClass".toAppClass() ``` 为了美观,你可以把字符串用 `(` `)` 括起来。 @@ -463,32 +483,32 @@ val VariousClass.clazz: Class<*> > 示例如下 ```kotlin -("com.example.demo.DemoClass").clazz +("com.example.demo.DemoClass").toAppClass() ``` 你还可以创建一个 `VariousClass`,并转换为实体类。 -`VariousClass` 会枚举所有设置的 `Class` 并最终获得完全匹配的那一个。 +`VariousClass` 会枚举所有设置的 `Class` 并最终获得第一个存在的 `Class`。 > 示例如下 ```kotlin -VariousClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2").clazz +VariousClass("com.example.demo.DemoClass1", "com.example.demo.DemoClass2").toAppClass() ``` -### String.hasClass *- i-ext-field* +### String.hasClass *- i-ext-method* ```kotlin -val String.hasClass: Boolean +fun String.hasClass(loader: ClassLoader?): Boolean ``` **变更记录** -`v1.0` `添加` +`v1.0.93` `新增` **功能描述** -> 通过字符串使用当前 `appClassLoader` 查找类是否存在。 +> 通过字符串类名查找是否存在。 **功能示例** @@ -497,7 +517,18 @@ val String.hasClass: Boolean > 示例如下 ```kotlin -if("com.example.demo.DemoClass".hasClass) { +if("com.example.demo.DemoClass".hasClass()) { + // Your code here. +} +``` + +你还可以自定义其中的 `loader` 参数,默认为 `appClassLoader`。 + +> 示例如下 + +```kotlin +val customClassLoader: ClassLoader? = ... // 假设这个就是你的 ClassLoader +if("com.example.demo.DemoClass".hasClass(customClassLoader)) { // Your code here. } ``` @@ -528,7 +559,7 @@ fun findClass(vararg name: String, loader: ClassLoader?): VariousClass > 通过完整包名+名称查找需要被 Hook 的 `Class`。 -!> 使用此方法会得到一个 `HookClass` 仅用于 Hook,若想查找 `Class` 请使用 `classOf`、`clazz` 功能。 +!> 使用此方法会得到一个 `HookClass` 仅用于 Hook,若想查找 `Class` 请使用 `classOf`、`toAppClass` 功能。 **功能示例** @@ -646,7 +677,7 @@ inline fun String.hook(initiate: YukiMemberHookCreator.() -> Unit): YukiMemberHo ``` ```kotlin -inline fun Class<*>.hook(initiate: YukiMemberHookCreator.() -> Unit): YukiMemberHookCreator.Result +inline fun Class<*>.hook(isForceUseAbsolute: Boolean, initiate: YukiMemberHookCreator.() -> Unit): YukiMemberHookCreator.Result ``` ```kotlin @@ -685,6 +716,8 @@ inline fun HookClass.hook(initiate: YukiMemberHookCreator.() -> Unit): YukiMembe 移除了 ~~`isUseAppClassLoader`~~ 参数 +添加了 `isForceUseAbsolute` 参数到 `Class.hook` 方法 + **功能描述** > 这是一切 Hook 的入口创建方法,Hook 方法、构造方法。 @@ -725,6 +758,16 @@ Stub::class.java.hook { } ``` +若当前 `Class` 不在 `appClassLoader` 且自动匹配无法找到该 `Class`,请启用 `isForceUseAbsolute`。 + +> 示例如下 + +```kotlin +YourClass::class.java.hook(isForceUseAbsolute = true) { + // Your code here. +} +``` + 使用 `VariousClass` 实例进行创建。 > 示例如下 diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt index 30baeb86..334cc6e1 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt @@ -44,7 +44,6 @@ import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreator import com.highcapable.yukihookapi.hook.core.YukiResourcesHookCreator import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.factory.classOf -import com.highcapable.yukihookapi.hook.factory.hasClass import com.highcapable.yukihookapi.hook.param.type.HookEntryType import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper import com.highcapable.yukihookapi.hook.utils.value @@ -296,7 +295,45 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper: fun loadHooker(hooker: YukiBaseHooker) = hooker.assignInstance(packageParam = this) /** - * 通过字符串转换为实体类 + * 通过字符串类名转换为当前 Hook APP 的实体类 + * + * - ❗此方法已弃用 - 在之后的版本中将直接被删除 + * + * - ❗请现在转移到 [toAppClass] + * @return [Class] + * @throws NoClassDefFoundError 如果找不到 [Class] + */ + @Deprecated(message = "请使用新的命名方法", ReplaceWith(expression = "toAppClass()")) + val String.clazz + get() = toAppClass() + + /** + * [VariousClass] 转换为当前 Hook APP 的实体类 + * + * - ❗此方法已弃用 - 在之后的版本中将直接被删除 + * + * - ❗请现在转移到 [toAppClass] + * @return [Class] + * @throws IllegalStateException 如果任何 [Class] 都没有匹配到 + */ + @Deprecated(message = "请使用新的命名方法", ReplaceWith(expression = "toAppClass()")) + val VariousClass.clazz + get() = toAppClass() + + /** + * 通过字符串类名查找是否存在 + * + * - ❗此方法已弃用 - 在之后的版本中将直接被删除 + * + * - ❗请现在转移到 [hasClass] + * @return [Boolean] 是否存在 + */ + @Deprecated(message = "请使用新的命名方法", ReplaceWith(expression = "hasClass()")) + val String.hasClass + get() = hasClass() + + /** + * 通过字符串类名转换为当前 Hook APP 的实体类 * * - 使用当前 [appClassLoader] 装载目标 [Class] * @@ -304,47 +341,46 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper: * @return [Class] * @throws NoClassDefFoundError 如果找不到 [Class] */ - val String.clazz get() = classOf(name = this, appClassLoader) + fun String.toAppClass() = classOf(name = this, appClassLoader) /** - * [VariousClass] 转换为实体类 + * [VariousClass] 转换为当前 Hook APP 的实体类 * * - 使用当前 [appClassLoader] 装载目标 [Class] * @return [Class] * @throws IllegalStateException 如果任何 [Class] 都没有匹配到 */ - val VariousClass.clazz get() = get(appClassLoader) + fun VariousClass.toAppClass() = get(appClassLoader) /** - * 通过字符串查找类是否存在 - * - * - 使用当前 [appClassLoader] 装载目标 [Class] + * 通过字符串类名查找是否存在 + * @param loader [Class] 所在的 [ClassLoader] - 不填使用 [appClassLoader] * @return [Boolean] 是否存在 */ - val String.hasClass get() = hasClass(appClassLoader) + fun String.hasClass(loader: ClassLoader? = appClassLoader) = runCatching { classOf(name = this, loader); true }.getOrNull() ?: false /** - * 查找并装载 [Class] + * 查找并装载 [HookClass] * - * - ❗使用此方法会得到一个 [HookClass] 仅用于 Hook - 若想查找 [Class] 请使用 [classOf]、[clazz] 功能 + * - ❗使用此方法会得到一个 [HookClass] 仅用于 Hook - 若想查找 [Class] 请使用 [classOf]、[toAppClass] 功能 * @param name 类名 * @param loader 当前 [ClassLoader] - 默认使用 [appClassLoader] - 设为 null 使用默认 [ClassLoader] * @return [HookClass] */ fun findClass(name: String, loader: ClassLoader? = appClassLoader) = - runCatching { classOf(name, loader).hookClass }.getOrElse { HookClass(name = name, throwable = it) } + runCatching { classOf(name, loader).toHookClass() }.getOrElse { HookClass(name = name, throwable = it) } /** - * 查找并装载 [Class] + * 查找并装载 [HookClass] * * 使用此方法查找将会取 [name] 其中命中存在的第一个 [Class] 作为结果 * - * - ❗使用此方法会得到一个 [HookClass] 仅用于 Hook - 若想查找 [Class] 请使用 [classOf]、[clazz] 功能 + * - ❗使用此方法会得到一个 [HookClass] 仅用于 Hook - 若想查找 [Class] 请使用 [classOf]、[toAppClass] 功能 * @param name 可填入多个类名 - 自动匹配 * @param loader 当前 [ClassLoader] - 默认使用 [appClassLoader] - 设为 null 使用默认 [ClassLoader] * @return [HookClass] */ - fun findClass(vararg name: String, loader: ClassLoader? = appClassLoader) = VariousClass(*name).hookClass(loader) + fun findClass(vararg name: String, loader: ClassLoader? = appClassLoader) = VariousClass(*name).toHookClass(loader) /** * 监听并 Hook 当前 [ClassLoader] 的 [ClassLoader.loadClass] 方法 @@ -371,12 +407,16 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper: * Hook 方法、构造方法 * * - 自动选择与当前 [Class] 相匹配的 [ClassLoader] - 优先使用 [appClassLoader] + * + * - ❗若当前 [Class] 不在 [appClassLoader] 且自动匹配无法找到该 [Class] - 请启用 [isForceUseAbsolute] + * @param isForceUseAbsolute 是否强制使用绝对实例对象 - 默认否 * @param initiate 方法体 * @return [YukiMemberHookCreator.Result] */ - inline fun Class<*>.hook(initiate: YukiMemberHookCreator.() -> Unit) = when { - name.hasClass(appClassLoader) -> findClass(name) - else -> hookClass + inline fun Class<*>.hook(isForceUseAbsolute: Boolean = false, initiate: YukiMemberHookCreator.() -> Unit) = when { + isForceUseAbsolute -> toHookClass() + name.hasClass() -> findClass(name) + else -> toHookClass() }.hook(initiate) /** @@ -386,7 +426,7 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper: * @param initiate 方法体 * @return [YukiMemberHookCreator.Result] */ - inline fun VariousClass.hook(initiate: YukiMemberHookCreator.() -> Unit) = hookClass(appClassLoader).hook(initiate) + inline fun VariousClass.hook(initiate: YukiMemberHookCreator.() -> Unit) = toHookClass(appClassLoader).hook(initiate) /** * Hook 方法、构造方法 @@ -411,16 +451,15 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper: * @return [HookClass] */ @PublishedApi - internal fun VariousClass.hookClass(loader: ClassLoader? = null) = - runCatching { get(loader).hookClass }.getOrElse { HookClass(name = "VariousClass", throwable = Throwable(it.message)) } + internal fun VariousClass.toHookClass(loader: ClassLoader? = null) = + runCatching { get(loader).toHookClass() }.getOrElse { HookClass(name = "VariousClass", throwable = Throwable(it.message)) } /** * [Class] 转换为 [HookClass] * @return [HookClass] */ @PublishedApi - internal val Class<*>.hookClass - get() = HookClass(instance = this, name) + internal fun Class<*>.toHookClass() = HookClass(instance = this, name) /** * 当前 Hook APP 的生命周期实例处理类