From 7280397d794ac5382448ca41f000323558ec2e82 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Tue, 3 Oct 2023 04:15:59 +0800 Subject: [PATCH] feat: add new api preview functions, mark old api to legacy --- .../yukihookapi/hook/bean/HookClass.kt | 18 +++ .../hook/core/YukiMemberHookCreator.kt | 125 +++++++++++++----- .../yukihookapi/hook/param/HookParam.kt | 2 +- .../yukihookapi/hook/param/PackageParam.kt | 100 +++++++++++++- .../hook/param/annotation/LegacyHookApi.kt | 37 ++++++ .../param/annotation/LegacyResourcesHook.kt | 37 ++++++ 6 files changed, 286 insertions(+), 33 deletions(-) create mode 100644 yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/annotation/LegacyHookApi.kt create mode 100644 yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/annotation/LegacyResourcesHook.kt diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/bean/HookClass.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/bean/HookClass.kt index 4fd91a4b..ef2c3f92 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/bean/HookClass.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/bean/HookClass.kt @@ -39,5 +39,23 @@ class HookClass internal constructor( internal var throwable: Throwable? = null ) { + internal companion object { + + /** 占位符 [Class] 名称 */ + private const val PLACEHOLDER_CLASS_NAME = "placeholder_hook_class" + + /** + * 创建占位符 [HookClass] + * @return [HookClass] + */ + internal fun createPlaceholder() = HookClass(name = PLACEHOLDER_CLASS_NAME, throwable = Throwable("There is no hook class instance")) + } + + /** + * 是否为占位符 [HookClass] + * @return [Boolean] + */ + internal val isPlaceholder get() = name == PLACEHOLDER_CLASS_NAME + override fun toString() = "[class] $name [throwable] $throwable [instance] $instance" } \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator.kt index c413e7d9..5e5eeb38 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreator.kt @@ -25,7 +25,10 @@ * * This file is created by fankes on 2022/2/2. */ -@file:Suppress("unused", "MemberVisibilityCanBePrivate", "UnusedReceiverParameter", "PropertyName", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") +@file:Suppress( + "unused", "MemberVisibilityCanBePrivate", "UnusedReceiverParameter", + "PropertyName", "NON_PUBLIC_CALL_FROM_PUBLIC_INLINE", "OPT_IN_USAGE" +) package com.highcapable.yukihookapi.hook.core @@ -55,6 +58,7 @@ import com.highcapable.yukihookapi.hook.factory.toJavaPrimitiveType import com.highcapable.yukihookapi.hook.log.YLog import com.highcapable.yukihookapi.hook.param.HookParam import com.highcapable.yukihookapi.hook.param.PackageParam +import com.highcapable.yukihookapi.hook.param.annotation.LegacyHookApi import com.highcapable.yukihookapi.hook.type.java.AnyClass import com.highcapable.yukihookapi.hook.type.java.JavaClass import com.highcapable.yukihookapi.hook.type.java.JavaClassLoader @@ -80,6 +84,27 @@ import java.lang.reflect.Method */ class YukiMemberHookCreator internal constructor(private val packageParam: PackageParam, private val hookClass: HookClass) { + internal companion object { + + /** + * 创建 [YukiMemberHookCreator.MemberHookCreator] + * @param packageParam 需要传入 [PackageParam] 实现方法调用 + * @param members 要指定的 [Member] 数组 + * @param initiate 方法体 + * @return [YukiMemberHookCreator.MemberHookCreator.Result] + */ + internal inline fun createMemberHook( + packageParam: PackageParam, + members: List, + initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit + ): YukiMemberHookCreator.MemberHookCreator.Result { + val creator = YukiMemberHookCreator(packageParam, HookClass.createPlaceholder()) + val result = creator.injectMember { if (members.isNotEmpty()) members(*members.toTypedArray()); apply(initiate) } + creator.hook() + return result + } + } + /** 默认 Hook 回调优先级 */ val PRIORITY_DEFAULT = 0x0 @@ -120,10 +145,12 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * * - 不推荐直接使用 - 万一得不到 [Class] 对象则会无法处理异常导致崩溃 * @return [Class] - * @throws IllegalStateException 如果当前 [Class] 未被正确装载 + * @throws IllegalStateException 如果当前 [Class] 未被正确装载或为 [HookClass.isPlaceholder] */ val instanceClass - get() = hookClass.instance ?: error("Cannot get hook class \"${hookClass.name}\" cause ${hookClass.throwable?.message}") + get() = if (hookClass.isPlaceholder) + error("This hook instance is create by Members, not support any hook class instance") + else hookClass.instance ?: error("Cannot get hook class \"${hookClass.name}\" cause ${hookClass.throwable?.message}") /** * 注入要 Hook 的 [Method]、[Constructor] @@ -132,6 +159,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * @param initiate 方法体 * @return [MemberHookCreator.Result] */ + @LegacyHookApi inline fun injectMember(priority: Int = PRIORITY_DEFAULT, tag: String = "Default", initiate: MemberHookCreator.() -> Unit) = MemberHookCreator(priority, tag).apply(initiate).apply { preHookMembers[toString()] = this }.build() @@ -161,15 +189,16 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa preHookMembers.isEmpty() -> Result().also { YLog.innerW(msg = "Hook Members is empty in [${hookClass.name}], hook aborted") } else -> Result().await { when { - isDisableCreatorRunHook.not() && hookClass.instance != null -> runCatching { - hookClass.instance?.checkingDangerous() - it.onPrepareHook?.invoke() - preHookMembers.forEach { (_, m) -> m.hook() } - }.onFailure { - if (onHookClassNotFoundFailureCallback == null) - YLog.innerE(msg = "Hook initialization failed because got an Exception", e = it) - else onHookClassNotFoundFailureCallback?.invoke(it) - } + isDisableCreatorRunHook.not() && (hookClass.instance != null || hookClass.isPlaceholder) -> + runCatching { + hookClass.instance?.checkingDangerous() + it.onPrepareHook?.invoke() + preHookMembers.forEach { (_, m) -> m.hook() } + }.onFailure { + if (onHookClassNotFoundFailureCallback == null) + YLog.innerE(msg = "Hook initialization failed because got an Exception", e = it) + else onHookClassNotFoundFailureCallback?.invoke(it) + } isDisableCreatorRunHook.not() && hookClass.instance == null -> if (onHookClassNotFoundFailureCallback == null) YLog.innerE(msg = "HookClass [${hookClass.name}] not found", e = hookClass.throwable) @@ -240,19 +269,19 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa /** 是否已经执行 Hook */ private var isHooked = false - /** [beforeHook] 回调方法体 ID */ + /** [before] 回调方法体 ID */ private val beforeHookId = RandomSeed.createString() - /** [afterHook] 回调方法体 ID */ + /** [after] 回调方法体 ID */ private val afterHookId = RandomSeed.createString() /** [replaceAny]、[replaceUnit] 回调方法体 ID */ private val replaceHookId = RandomSeed.createString() - /** [beforeHook] 回调 */ + /** [before] 回调 */ private var beforeHookCallback: (HookParam.() -> Unit)? = null - /** [afterHook] 回调 */ + /** [after] 回调 */ private var afterHookCallback: (HookParam.() -> Unit)? = null /** [replaceAny]、[replaceUnit] 回调 */ @@ -421,6 +450,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * @param initiate 方法体 * @return [MemberHookCreator.Result] */ + @LegacyHookApi inline fun HookParam.injectMember( priority: Int = PRIORITY_DEFAULT, tag: String = "InnerDefault", @@ -434,7 +464,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * @param initiate [HookParam] 方法体 * @return [HookCallback] */ - fun beforeHook(initiate: HookParam.() -> Unit): HookCallback { + fun before(initiate: HookParam.() -> Unit): HookCallback { isReplaceHookMode = false beforeHookCallback = initiate return HookCallback() @@ -447,16 +477,38 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * @param initiate [HookParam] 方法体 * @return [HookCallback] */ - fun afterHook(initiate: HookParam.() -> Unit): HookCallback { + fun after(initiate: HookParam.() -> Unit): HookCallback { isReplaceHookMode = false afterHookCallback = initiate return HookCallback() } + /** + * 在 [Member] 执行完成前 Hook + * + * - 此方法已弃用 - 在之后的版本中将直接被删除 + * + * - 请现在迁移到 [before] + * @return [HookCallback] + */ + @Deprecated(message = "请使用新的命名方法", ReplaceWith("before(initiate)")) + fun beforeHook(initiate: HookParam.() -> Unit) = before(initiate) + + /** + * 在 [Member] 执行完成后 Hook + * + * - 此方法已弃用 - 在之后的版本中将直接被删除 + * + * - 请现在迁移到 [after] + * @return [HookCallback] + */ + @Deprecated(message = "请使用新的命名方法", ReplaceWith("after(initiate)")) + fun afterHook(initiate: HookParam.() -> Unit) = after(initiate) + /** * 拦截并替换此 [Member] 内容 - 给出返回值 * - * - 不可与 [beforeHook]、[afterHook] 同时使用 + * - 不可与 [before]、[after] 同时使用 * @param initiate [HookParam] 方法体 */ fun replaceAny(initiate: HookParam.() -> Any?) { @@ -467,7 +519,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa /** * 拦截并替换此 [Member] 内容 - 没有返回值 ([Unit]) * - * - 不可与 [beforeHook]、[afterHook] 同时使用 + * - 不可与 [before]、[after] 同时使用 * @param initiate [HookParam] 方法体 */ fun replaceUnit(initiate: HookParam.() -> Unit) { @@ -478,7 +530,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa /** * 拦截并替换 [Member] 返回值 * - * - 不可与 [beforeHook]、[afterHook] 同时使用 + * - 不可与 [before]、[after] 同时使用 * @param any 要替换为的返回值对象 */ fun replaceTo(any: Any?) { @@ -491,7 +543,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * * - 确保替换 [Member] 的返回对象为 [Boolean] * - * - 不可与 [beforeHook]、[afterHook] 同时使用 + * - 不可与 [before]、[after] 同时使用 */ fun replaceToTrue() { isReplaceHookMode = true @@ -503,7 +555,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * * - 确保替换 [Member] 的返回对象为 [Boolean] * - * - 不可与 [beforeHook]、[afterHook] 同时使用 + * - 不可与 [before]、[after] 同时使用 */ fun replaceToFalse() { isReplaceHookMode = true @@ -517,7 +569,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * * - 注意:例如 [Int]、[Long]、[Boolean] 常量返回值的 [Member] 一旦被设置为 null 可能会造成 Hook APP 抛出异常 * - * - 不可与 [beforeHook]、[afterHook] 同时使用 + * - 不可与 [before]、[after] 同时使用 */ fun intercept() { isReplaceHookMode = true @@ -542,7 +594,7 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa internal fun hook() { if (HookApiCategoryHelper.hasAvailableHookApi.not() || isHooked || isDisableMemberRunHook) return isHooked = true - if (hookClass.instance == null) { + if (hookClass.instance == null && hookClass.isPlaceholder.not()) { (hookClass.throwable ?: Throwable("HookClass [${hookClass.name}] not found")).also { onHookingFailureCallback?.invoke(it) onAllFailureCallback?.invoke(it) @@ -572,10 +624,16 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa onHookingFailureCallback?.invoke(it) onAllFailureCallback?.invoke(it) if (isNotIgnoredNoSuchMemberFailure) YLog.innerE( - msg = (if (isHookMemberSetup) - "Hooked Member with a finding error by $hookClass [$tag]" - else "Hooked Member cannot be non-null by $hookClass [$tag]"), - e = findingThrowable ?: it + msg = when { + hookClass.isPlaceholder -> + if (isHookMemberSetup) + "Hooked Member with a finding error [$tag]" + else "Hooked Member cannot be null [$tag]" + else -> + if (isHookMemberSetup) + "Hooked Member with a finding error by $hookClass [$tag]" + else "Hooked Member cannot be null by $hookClass [$tag]" + }, e = findingThrowable ?: it ) } } @@ -663,7 +721,9 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa * @param member 异常 [Member] - 可空 */ private fun hookErrorMsg(e: Throwable, member: Member? = null) = - YLog.innerE("Try to hook [${hookClass.instance ?: hookClass.name}]${member?.let { "[$it]" } ?: ""} got an Exception [$tag]", e) + if (hookClass.isPlaceholder) + YLog.innerE("Try to hook ${member?.let { "[$it]" } ?: "nothing"} got an Exception [$tag]", e) + else YLog.innerE("Try to hook [${hookClass.instance ?: hookClass.name}]${member?.let { "[$it]" } ?: ""} got an Exception [$tag]", e) /** * 判断是否没有设置 Hook 过程中的任何异常拦截 @@ -677,7 +737,10 @@ class YukiMemberHookCreator internal constructor(private val packageParam: Packa */ internal val isNotIgnoredNoSuchMemberFailure get() = onNoSuchMemberFailureCallback == null && isNotIgnoredHookingFailure - override fun toString() = "[tag] $tag [priority] $priority [class] $hookClass [members] $members" + override fun toString() = + if (hookClass.isPlaceholder) + "[tag] $tag [priority] $priority [members] $members" + else "[tag] $tag [priority] $priority [class] $hookClass [members] $members" /** * Hook 方法体回调实现类 diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/HookParam.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/HookParam.kt index e47d22cd..85177044 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/HookParam.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/HookParam.kt @@ -168,7 +168,7 @@ class HookParam private constructor( * * 使用 [throwable] 获取当前设置的方法调用抛出异常 * - * - 仅会在回调方法的 [MemberHookCreator.beforeHook] or [MemberHookCreator.afterHook] 中生效 + * - 仅会在回调方法的 [MemberHookCreator.before] or [MemberHookCreator.after] 中生效 * * - 设置后会同时执行 [resultNull] 方法并将异常抛出给当前 Hook APP * @return [Throwable] or null diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/PackageParam.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/PackageParam.kt index 0b40ceca..3f51b4ce 100644 --- a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/PackageParam.kt +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/PackageParam.kt @@ -43,11 +43,16 @@ import com.highcapable.yukihookapi.hook.bean.HookResources import com.highcapable.yukihookapi.hook.bean.VariousClass import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreator import com.highcapable.yukihookapi.hook.core.YukiResourcesHookCreator +import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.core.finder.classes.DexClassFinder +import com.highcapable.yukihookapi.hook.core.finder.members.ConstructorFinder +import com.highcapable.yukihookapi.hook.core.finder.members.MethodFinder import com.highcapable.yukihookapi.hook.core.finder.tools.ReflectionTool import com.highcapable.yukihookapi.hook.core.finder.type.factory.ClassConditions import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker import com.highcapable.yukihookapi.hook.log.YLog +import com.highcapable.yukihookapi.hook.param.annotation.LegacyHookApi +import com.highcapable.yukihookapi.hook.param.annotation.LegacyResourcesHook import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper import com.highcapable.yukihookapi.hook.utils.factory.value import com.highcapable.yukihookapi.hook.xposed.bridge.YukiXposedModule @@ -57,6 +62,9 @@ import com.highcapable.yukihookapi.hook.xposed.bridge.type.HookEntryType import com.highcapable.yukihookapi.hook.xposed.channel.YukiHookDataChannel import com.highcapable.yukihookapi.hook.xposed.parasitic.AppParasitics import com.highcapable.yukihookapi.hook.xposed.prefs.YukiHookPrefsBridge +import java.lang.reflect.Constructor +import java.lang.reflect.Member +import java.lang.reflect.Method /** * 装载 Hook 的目标 APP 入口对象实现类 @@ -210,6 +218,7 @@ open class PackageParam internal constructor(internal var wrapper: PackageParamW * 请调用 [HookResources.hook] 方法开始 Hook * @return [HookResources] */ + @LegacyResourcesHook fun resources() = HookResources(wrapper?.appResources) /** 刷新当前 Xposed 模块自身 [Resources] */ @@ -590,6 +599,7 @@ open class PackageParam internal constructor(internal var wrapper: PackageParamW * @param initiate 方法体 * @return [YukiMemberHookCreator.Result] */ + @LegacyHookApi @Deprecated(message = "不再推荐使用此方法", ReplaceWith("this.toClass().hook(initiate = initiate)")) inline fun String.hook(initiate: YukiMemberHookCreator.() -> Unit) = toClass().hook(initiate = initiate) @@ -603,6 +613,7 @@ open class PackageParam internal constructor(internal var wrapper: PackageParamW * @param initiate 方法体 * @return [YukiMemberHookCreator.Result] */ + @LegacyHookApi inline fun Class<*>.hook(isForceUseAbsolute: Boolean = false, initiate: YukiMemberHookCreator.() -> Unit) = when { isForceUseAbsolute -> toHookClass() name.hasClass() -> name.toClass().toHookClass() @@ -616,6 +627,7 @@ open class PackageParam internal constructor(internal var wrapper: PackageParamW * @param initiate 方法体 * @return [YukiMemberHookCreator.Result] */ + @LegacyHookApi inline fun VariousClass.hook(initiate: YukiMemberHookCreator.() -> Unit) = toHookClass(appClassLoader).hook(initiate) /** @@ -623,15 +635,99 @@ open class PackageParam internal constructor(internal var wrapper: PackageParamW * @param initiate 方法体 * @return [YukiMemberHookCreator.Result] */ + @LegacyHookApi inline fun HookClass.hook(initiate: YukiMemberHookCreator.() -> Unit) = YukiMemberHookCreator(packageParam = this@PackageParam, hookClass = this).apply(initiate).hook() + /** + * 直接 Hook 方法、构造方法 + * + * - 此功能尚在试验阶段 - 在 1.x.x 版本将暂定于此 - 在 2.x.x 版本将完全合并到新 API + * @param initiate 方法体 + * @return [YukiMemberHookCreator.MemberHookCreator.Result] + */ + inline fun Member.hook(initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit) = listOf(this).baseHook(initiate) + + /** + * 通过 [BaseFinder.BaseResult] 直接 Hook 方法、构造方法 + * + * - 此功能尚在试验阶段 - 在 1.x.x 版本将暂定于此 - 在 2.x.x 版本将完全合并到新 API + * @param initiate 方法体 + * @return [YukiMemberHookCreator.MemberHookCreator.Result] + */ + inline fun BaseFinder.BaseResult.hook(initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit) = baseHook(isMultiple = false, initiate) + + /** + * 直接 Hook 方法、构造方法 (批量) + * + * - 此功能尚在试验阶段 - 在 1.x.x 版本将暂定于此 - 在 2.x.x 版本将完全合并到新 API + * @param initiate 方法体 + * @return [YukiMemberHookCreator.MemberHookCreator.Result] + */ + inline fun Array.hookAll(initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit) = toList().baseHook(initiate) + + /** + * 直接 Hook 方法、构造方法 (批量) + * + * - 此功能尚在试验阶段 - 在 1.x.x 版本将暂定于此 - 在 2.x.x 版本将完全合并到新 API + * @param initiate 方法体 + * @return [YukiMemberHookCreator.MemberHookCreator.Result] + */ + inline fun List.hookAll(initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit) = baseHook(initiate) + + /** + * 通过 [BaseFinder.BaseResult] 直接 Hook 方法、构造方法 (批量) + * + * - 此功能尚在试验阶段 - 在 1.x.x 版本将暂定于此 - 在 2.x.x 版本将完全合并到新 API + * @param initiate 方法体 + * @return [YukiMemberHookCreator.MemberHookCreator.Result] + */ + inline fun BaseFinder.BaseResult.hookAll(initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit) = baseHook(isMultiple = true, initiate) + + /** + * 通过 [BaseFinder.BaseResult] 直接 Hook 方法、构造方法 + * + * - 此功能尚在试验阶段 - 在 1.x.x 版本将暂定于此 - 在 2.x.x 版本将完全合并到新 API + * @param isMultiple 是否为多重查找 + * @param initiate 方法体 + * @return [YukiMemberHookCreator.MemberHookCreator.Result] + */ + private inline fun BaseFinder.BaseResult.baseHook(isMultiple: Boolean, initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit) = + when (this) { + is DexClassFinder.Result -> + error("Use of searchClass { ... }.hook { ... } is an error, please use like searchClass { ... }.get()?.hook { ... }") + is ConstructorFinder.Result -> { + val members = if (isMultiple) giveAll() + else mutableListOf().also { give()?.also { e -> it.add(e) } } + YukiMemberHookCreator.createMemberHook(packageParam = this@PackageParam, members, initiate) + } + is MethodFinder.Result -> { + val members = if (isMultiple) giveAll() + else mutableListOf().also { give()?.also { e -> it.add(e) } } + YukiMemberHookCreator.createMemberHook(packageParam = this@PackageParam, members, initiate) + } + else -> error("This type [$this] not support to hook, supported are Constructors and Methods") + } + + /** + * 直接 Hook 方法、构造方法 + * + * - 此功能尚在试验阶段 - 在 1.x.x 版本将暂定于此 - 在 2.x.x 版本将完全合并到新 API + * @param initiate 方法体 + * @return [YukiMemberHookCreator.MemberHookCreator.Result] + */ + private inline fun List.baseHook(initiate: YukiMemberHookCreator.MemberHookCreator.() -> Unit) = + YukiMemberHookCreator.createMemberHook(packageParam = this@PackageParam, onEach { + if (it !is Constructor<*> && it !is Method) error("This type [$it] not support to hook, supported are Constructors and Methods") + }, initiate) + /** * Hook APP 的 Resources * - * - 请注意你需要确保当前 Hook Framework 支持且 [InjectYukiHookWithXposed.isUsingResourcesHook] 已启用 + * - 此功能将不再默认启用 - 如需启用 - 请手动设置 [InjectYukiHookWithXposed.isUsingResourcesHook] * @param initiate 方法体 */ + @LegacyResourcesHook inline fun HookResources.hook(initiate: YukiResourcesHookCreator.() -> Unit) = YukiResourcesHookCreator(packageParam = this@PackageParam, hookResources = this).apply(initiate).hook() @@ -640,6 +736,7 @@ open class PackageParam internal constructor(internal var wrapper: PackageParamW * @param loader 当前 [ClassLoader] - 若留空使用默认 [ClassLoader] * @return [HookClass] */ + @LegacyHookApi internal fun VariousClass.toHookClass(loader: ClassLoader? = null) = runCatching { get(loader).toHookClass() }.getOrElse { HookClass(name = "VariousClass", throwable = Throwable(it.message)) } @@ -647,6 +744,7 @@ open class PackageParam internal constructor(internal var wrapper: PackageParamW * [Class] 转换为 [HookClass] * @return [HookClass] */ + @LegacyHookApi internal fun Class<*>.toHookClass() = HookClass(instance = this, name) /** diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/annotation/LegacyHookApi.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/annotation/LegacyHookApi.kt new file mode 100644 index 00000000..93376eb1 --- /dev/null +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/annotation/LegacyHookApi.kt @@ -0,0 +1,37 @@ +/* + * YukiHookAPI - An efficient Hook API and Xposed Module solution built in Kotlin. + * Copyright (C) 2019-2023 HighCapable + * https://github.com/fankes/YukiHookAPI + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * This file is created by fankes on 2023/10/3. + */ +package com.highcapable.yukihookapi.hook.param.annotation + +@RequiresOptIn(message = "这种方式将不再被推荐且将在 2.x.x 版本完全移除,建议迁移到使用 Member 创建 Hook 的新写法", level = RequiresOptIn.Level.WARNING) +@MustBeDocumented +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.BINARY) +/** + * 标记需要 [RequiresOptIn] 的功能 + */ +annotation class LegacyHookApi \ No newline at end of file diff --git a/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/annotation/LegacyResourcesHook.kt b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/annotation/LegacyResourcesHook.kt new file mode 100644 index 00000000..50d1d128 --- /dev/null +++ b/yukihookapi-core/src/main/java/com/highcapable/yukihookapi/hook/param/annotation/LegacyResourcesHook.kt @@ -0,0 +1,37 @@ +/* + * YukiHookAPI - An efficient Hook API and Xposed Module solution built in Kotlin. + * Copyright (C) 2019-2023 HighCapable + * https://github.com/fankes/YukiHookAPI + * + * MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * This file is created by fankes on 2023/10/3. + */ +package com.highcapable.yukihookapi.hook.param.annotation + +@RequiresOptIn(message = "Resources Hook 功能将在 2.x.x 版本完全移除 (如果必须使用,你可以继续使用 1.x.x 版本)", level = RequiresOptIn.Level.WARNING) +@MustBeDocumented +@Target(AnnotationTarget.FUNCTION) +@Retention(AnnotationRetention.BINARY) +/** + * 标记需要 [RequiresOptIn] 的功能 + */ +annotation class LegacyResourcesHook \ No newline at end of file