mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 01:35:17 +08:00
feat: add new api preview functions, mark old api to legacy
This commit is contained in:
@@ -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"
|
||||
}
|
@@ -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<Member>,
|
||||
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 方法体回调实现类
|
||||
|
@@ -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
|
||||
|
@@ -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<Member>.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<Member>.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<Member>().also { give()?.also { e -> it.add(e) } }
|
||||
YukiMemberHookCreator.createMemberHook(packageParam = this@PackageParam, members, initiate)
|
||||
}
|
||||
is MethodFinder.Result -> {
|
||||
val members = if (isMultiple) giveAll()
|
||||
else mutableListOf<Member>().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<Member>.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)
|
||||
|
||||
/**
|
||||
|
@@ -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
|
@@ -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
|
Reference in New Issue
Block a user