From 25e3dd2d59f25b5ff959b7459dd683ff72878f48 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Fri, 26 Aug 2022 22:27:43 +0800 Subject: [PATCH] Modify move HookParamWrapper to YukiHookCallback.Param --- docs/api/public/HookParam.md | 8 +- .../hook/core/YukiMemberHookCreater.kt | 35 ++-- .../yukihookapi/hook/param/HookParam.kt | 40 +++-- .../hook/param/wrapper/HookParamWrapper.kt | 118 ------------- .../bridge/factory/YukiBridgeFactory.kt | 167 +++++++++++++----- .../hook/xposed/parasitic/AppParasitics.kt | 65 ++++--- 6 files changed, 202 insertions(+), 231 deletions(-) delete mode 100644 yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/HookParamWrapper.kt diff --git a/docs/api/public/HookParam.md b/docs/api/public/HookParam.md index 89e51512..22156e11 100644 --- a/docs/api/public/HookParam.md +++ b/docs/api/public/HookParam.md @@ -1,13 +1,17 @@ ## HookParam *- class* ```kotlin -class HookParam internal constructor(private val createrInstance: YukiMemberHookCreater, private var wrapper: HookParamWrapper?) +class HookParam internal constructor(private val createrInstance: YukiMemberHookCreater, private var param: YukiHookCallback.Param?) ``` **变更记录** `v1.0` `添加` +`v1.0.93` `修改` + +移动 `HookParamWrapper` 到 `YukiHookCallback.Param` + **功能描述** > Hook 方法、构造方法的目标对象实现类。 @@ -26,6 +30,8 @@ val args: Array > 获取当前 Hook 对象 `member` 或 `constructor` 的参数对象数组。 +这里的数组每项类型默认为 `Any`,你可以使用 `args` 方法来实现 `ArgsModifyer.cast` 功能。 + ### ~~firstArgs *- field*~~ **变更记录** diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreater.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreater.kt index bc61b6a2..5b716fd5 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreater.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/core/YukiMemberHookCreater.kt @@ -43,7 +43,6 @@ import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.param.HookParam import com.highcapable.yukihookapi.hook.param.PackageParam import com.highcapable.yukihookapi.hook.param.type.HookEntryType -import com.highcapable.yukihookapi.hook.param.wrapper.HookParamWrapper import com.highcapable.yukihookapi.hook.type.java.* import com.highcapable.yukihookapi.hook.utils.await import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge @@ -554,20 +553,20 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara /** 定义替换 Hook 回调方法体 */ val replaceMent = object : YukiMemberReplacement(priority) { - override fun replaceHookedMember(wrapper: HookParamWrapper) = - replaceHookParam.assign(wrapper).let { param -> + override fun replaceHookedMember(param: Param) = + replaceHookParam.assign(param).let { assign -> try { - replaceHookCallback?.invoke(param).also { - checkingReturnType((wrapper.member as? Method?)?.returnType, it?.javaClass) + replaceHookCallback?.invoke(assign).also { + checkingReturnType((param.member as? Method?)?.returnType, it?.javaClass) if (replaceHookCallback != null) onHookLogMsg(msg = "Replace Hook Member [${this@hook}] done [$tag]") HookParam.invoke() } } catch (e: Throwable) { - onConductFailureCallback?.invoke(param, e) + onConductFailureCallback?.invoke(assign, e) onAllFailureCallback?.invoke(e) if (onConductFailureCallback == null && onAllFailureCallback == null) onHookFailureMsg(e) /** 若发生异常则会自动调用未经 Hook 的原始方法保证 Hook APP 正常运行 */ - wrapper.member?.also { wrapper.invokeOriginalMember(it, wrapper.args) } + param.member?.also { member -> param.invokeOriginalMember(member, param.args) } } } } @@ -580,33 +579,33 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara /** 定义前后 Hook 回调方法体 */ val beforeAfterHook = object : YukiMemberHook(priority) { - override fun beforeHookedMember(wrapper: HookParamWrapper) { - beforeHookParam.assign(wrapper).also { param -> + override fun beforeHookedMember(param: Param) { + beforeHookParam.assign(param).also { assign -> runCatching { - beforeHookCallback?.invoke(param) - checkingReturnType((wrapper.member as? Method?)?.returnType, wrapper.result?.javaClass) + beforeHookCallback?.invoke(assign) + checkingReturnType((param.member as? Method?)?.returnType, param.result?.javaClass) if (beforeHookCallback != null) onHookLogMsg(msg = "Before Hook Member [${this@hook}] done [$tag]") HookParam.invoke() }.onFailure { - onConductFailureCallback?.invoke(param, it) + onConductFailureCallback?.invoke(assign, it) onAllFailureCallback?.invoke(it) if (onConductFailureCallback == null && onAllFailureCallback == null) onHookFailureMsg(it) - if (isOnFailureThrowToApp) wrapper.throwable = it + if (isOnFailureThrowToApp) param.throwable = it } } } - override fun afterHookedMember(wrapper: HookParamWrapper) { - afterHookParam.assign(wrapper).also { param -> + override fun afterHookedMember(param: Param) { + afterHookParam.assign(param).also { assign -> runCatching { - afterHookCallback?.invoke(param) + afterHookCallback?.invoke(assign) if (afterHookCallback != null) onHookLogMsg(msg = "After Hook Member [${this@hook}] done [$tag]") HookParam.invoke() }.onFailure { - onConductFailureCallback?.invoke(param, it) + onConductFailureCallback?.invoke(assign, it) onAllFailureCallback?.invoke(it) if (onConductFailureCallback == null && onAllFailureCallback == null) onHookFailureMsg(it) - if (isOnFailureThrowToApp) wrapper.throwable = it + if (isOnFailureThrowToApp) param.throwable = it } } } diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/HookParam.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/HookParam.kt index 72f7cbce..d675e955 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/HookParam.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/HookParam.kt @@ -33,7 +33,7 @@ import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreater import com.highcapable.yukihookapi.hook.core.YukiMemberHookCreater.MemberHookCreater import com.highcapable.yukihookapi.hook.factory.classOf import com.highcapable.yukihookapi.hook.log.yLoggerE -import com.highcapable.yukihookapi.hook.param.wrapper.HookParamWrapper +import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookCallback import java.lang.reflect.Constructor import java.lang.reflect.Member import java.lang.reflect.Method @@ -41,9 +41,9 @@ import java.lang.reflect.Method /** * Hook 方法、构造方法的目标对象实现类 * @param createrInstance [YukiMemberHookCreater] 的实例对象 - * @param wrapper [HookParam] 的参数包装类实例 + * @param param Hook 结果回调接口 */ -class HookParam internal constructor(private val createrInstance: YukiMemberHookCreater, private var wrapper: HookParamWrapper? = null) { +class HookParam internal constructor(private val createrInstance: YukiMemberHookCreater, private var param: YukiHookCallback.Param? = null) { internal companion object { @@ -57,20 +57,22 @@ class HookParam internal constructor(private val createrInstance: YukiMemberHook } /** - * 在回调中设置 [HookParam] 使用的 [HookParamWrapper] - * @param wrapper [HookParamWrapper] 实例 + * 在回调中设置 [HookParam] 使用的 [YukiHookCallback.Param] + * @param param Hook 结果回调接口 * @return [HookParam] */ - internal fun assign(wrapper: HookParamWrapper): HookParam { - this.wrapper = wrapper + internal fun assign(param: YukiHookCallback.Param): HookParam { + this.param = param return this } /** * 获取当前 Hook 对象 [method] or [constructor] 的参数对象数组 + * + * 这里的数组每项类型默认为 [Any] - 你可以使用 [args] 方法来实现 [ArgsModifyer.cast] 功能 * @return [Array] */ - val args get() = wrapper?.args ?: arrayOf(0) + val args get() = param?.args ?: arrayOf(0) /** * 获取当前 Hook 实例的对象 @@ -79,13 +81,13 @@ class HookParam internal constructor(private val createrInstance: YukiMemberHook * @return [Any] * @throws IllegalStateException 如果对象为空 */ - val instance get() = wrapper?.instance ?: error("HookParam instance got null! Is this a static member?") + val instance get() = param?.instance ?: error("HookParam instance got null! Is this a static member?") /** * 获取当前 Hook 实例的类对象 * @return [Class] */ - val instanceClass get() = wrapper?.instance?.javaClass ?: createrInstance.instanceClass + val instanceClass get() = param?.instance?.javaClass ?: createrInstance.instanceClass /** * 获取当前 Hook 对象的 [Member] @@ -94,7 +96,7 @@ class HookParam internal constructor(private val createrInstance: YukiMemberHook * @return [Member] * @throws IllegalStateException 如果 [member] 为空 */ - val member get() = wrapper?.member ?: error("Current hooked Member is null") + val member get() = param?.member ?: error("Current hooked Member is null") /** * 获取当前 Hook 对象的方法 @@ -115,22 +117,22 @@ class HookParam internal constructor(private val createrInstance: YukiMemberHook * @return [Any] or null */ var result: Any? - get() = wrapper?.result + get() = param?.result set(value) { - wrapper?.result = value + param?.result = value } /** * 判断是否存在设置过的方法调用抛出异常 * @return [Boolean] */ - val hasThrowable get() = wrapper?.hasThrowable + val hasThrowable get() = param?.hasThrowable /** * 获取设置的方法调用抛出异常 * @return [Throwable] or null */ - val throwable get() = wrapper?.throwable + val throwable get() = param?.throwable /** * 向 Hook APP 抛出异常 @@ -146,7 +148,7 @@ class HookParam internal constructor(private val createrInstance: YukiMemberHook * @throws Throwable */ fun Throwable.throwToApp() { - wrapper?.throwable = this + param?.throwable = this yLoggerE(msg = message ?: "$this", e = this) } @@ -183,7 +185,7 @@ class HookParam internal constructor(private val createrInstance: YukiMemberHook * @param args 参数实例 * @return [T] */ - fun Member.invokeOriginal(vararg args: Any?) = wrapper?.invokeOriginalMember(member = this, *args) as? T? + fun Member.invokeOriginal(vararg args: Any?) = param?.invokeOriginalMember(member = this, *args) as? T? /** * 设置当前 Hook 对象方法的 [result] 返回值为 true @@ -349,7 +351,7 @@ class HookParam internal constructor(private val createrInstance: YukiMemberHook if (index < 0) error("HookParam Method args index must be >= 0") if (args.isEmpty()) error("HookParam Method args is empty, mabe not has args") if (index > args.lastIndex) error("HookParam Method args index out of bounds, max is ${args.lastIndex}") - wrapper?.setArgs(index, any) + param?.setArgs(index, any) } /** @@ -376,5 +378,5 @@ class HookParam internal constructor(private val createrInstance: YukiMemberHook override fun toString() = "Args of index $index" } - override fun toString() = "HookParam by $wrapper" + override fun toString() = "HookParam by $param" } \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/HookParamWrapper.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/HookParamWrapper.kt deleted file mode 100644 index 5aaf2885..00000000 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/wrapper/HookParamWrapper.kt +++ /dev/null @@ -1,118 +0,0 @@ -/* - * YukiHookAPI - An efficient Kotlin version of the Xposed Hook API. - * Copyright (C) 2019-2022 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 2022/2/9. - */ -package com.highcapable.yukihookapi.hook.param.wrapper - -import com.highcapable.yukihookapi.annotation.YukiPrivateApi -import com.highcapable.yukihookapi.hook.param.HookParam -import com.highcapable.yukihookapi.hook.xposed.bridge.factory.YukiHookHelper -import de.robv.android.xposed.XC_MethodHook -import java.lang.reflect.Member - -/** - * 用于包装 [HookParam] - * - * - ❗这是一个私有 API - 请不要在外部使用 - * @param baseParam 对接 [XC_MethodHook.MethodHookParam] - */ -@YukiPrivateApi -class HookParamWrapper internal constructor(private var baseParam: XC_MethodHook.MethodHookParam? = null) { - - /** - * 在回调中设置 [HookParamWrapper] 使用的 [XC_MethodHook.MethodHookParam] - * @param baseParam 对接 [XC_MethodHook.MethodHookParam] - * @return [HookParamWrapper] - */ - internal fun assign(baseParam: XC_MethodHook.MethodHookParam): HookParamWrapper { - this.baseParam = baseParam - return this - } - - /** - * [Member] 实例 - * @return [Member] or null - */ - val member: Member? get() = baseParam?.method - - /** - * 当前实例对象 - * @return [Any] or null - */ - val instance: Any? get() = baseParam?.thisObject - - /** - * 方法、构造方法数组 - * @return [Array] or null - */ - val args: Array? get() = baseParam?.args - - /** - * 获取、设置方法结果 - * @return [Any] or null - */ - var result: Any? - get() = baseParam?.result - set(value) { - baseParam?.result = value - } - - /** - * 判断是否存在设置过的方法调用抛出异常 - * @return [Boolean] - */ - val hasThrowable get() = baseParam?.hasThrowable() ?: false - - /** - * 获取、设置方法调用抛出的异常 - * @return [Throwable] or null - * @throws Throwable - */ - var throwable: Throwable? - get() = baseParam?.throwable - set(value) { - baseParam?.throwable = value - } - - /** - * 设置方法参数 - * @param index 数组下标 - * @param any 参数对象实例 - */ - fun setArgs(index: Int, any: Any?) = baseParam?.args?.set(index, any) - - /** - * 执行原始 [Member] - * - * 未进行 Hook 的 [Member] - * @param member 实例 - * @param args 参数实例 - * @return [Any] or null - */ - fun invokeOriginalMember(member: Member, vararg args: Any?): Any? = YukiHookHelper.invokeOriginalMember(member, instance, args) - - override fun toString() = "HookParamWrapper[$baseParam]" -} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/factory/YukiBridgeFactory.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/factory/YukiBridgeFactory.kt index 792c3750..aec64135 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/factory/YukiBridgeFactory.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/factory/YukiBridgeFactory.kt @@ -33,7 +33,6 @@ import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder import com.highcapable.yukihookapi.hook.core.finder.MethodFinder import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder import com.highcapable.yukihookapi.hook.log.yLoggerE -import com.highcapable.yukihookapi.hook.param.wrapper.HookParamWrapper import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge import de.robv.android.xposed.XC_MethodHook import de.robv.android.xposed.XposedBridge @@ -114,9 +113,9 @@ internal object YukiHookHelper { return when { member == null -> Pair(null, false) YukiHookBridge.hasXposedBridge -> - YukiMemberHook.Unhook.wrapper(XposedBridge.hookMethod(member, callback.compat())).let { - YukiHookedMembers.hookedMembers.add(it) - Pair(it, false) + XposedBridge.hookMethod(member, callback.compat()).compat().let { memberUnhook -> + YukiHookedMembers.hookedMembers.add(memberUnhook) + Pair(memberUnhook, false) } else -> Pair(null, false) } @@ -135,105 +134,189 @@ internal object YukiHookHelper { member?.let { XposedBridge.invokeOriginalMethod(it, instance, args) } else null + /** + * 兼容对接已 Hook 的 [Member] 接口 + * @return [YukiMemberHook.Unhook] + */ + private fun XC_MethodHook.Unhook.compat() = object : YukiMemberHook.Unhook() { + override val member get() = hookedMethod + override fun unhook() = this@compat.unhook() + } + /** * 兼容对接 Hook 回调接口 * @return [XC_MethodHook] 原始接口 */ private fun YukiHookCallback.compat() = object : XC_MethodHook(priority) { - /** 创建 Hook 前 [HookParamWrapper] */ - private val beforeHookWrapper = HookParamWrapper() - - /** 创建 Hook 后 [HookParamWrapper] */ - private val afterHookWrapper = HookParamWrapper() - override fun beforeHookedMethod(param: MethodHookParam?) { if (param == null) return if (this@compat !is YukiMemberHook) error("Invalid YukiHookCallback type") if (this@compat is YukiMemberReplacement) - param.result = replaceHookedMember(beforeHookWrapper.assign(param)) - else beforeHookedMember(beforeHookWrapper.assign(param)) + param.result = replaceHookedMember(param.compat()) + else beforeHookedMember(param.compat()) } override fun afterHookedMethod(param: MethodHookParam?) { if (param == null) return if (this@compat !is YukiMemberHook) error("Invalid YukiHookCallback type") - afterHookedMember(afterHookWrapper.assign(param)) + afterHookedMember(param.compat()) } } + + /** + * 兼容对接 Hook 结果回调接口 + * @return [YukiHookCallback.Param] + */ + private fun XC_MethodHook.MethodHookParam.compat() = object : YukiHookCallback.Param { + override val member get() = this@compat.method + override val instance get() = this@compat.thisObject + override val args get() = this@compat.args + override val hasThrowable get() = this@compat.hasThrowable() + override var result + get() = this@compat.result + set(value) { + this@compat.result = value + } + override var throwable + get() = this@compat.throwable + set(value) { + this@compat.throwable = value + } + + override fun setArgs(index: Int, any: Any?) { + this@compat.args[index] = any + } + + override fun invokeOriginalMember(member: Member, vararg args: Any?) = + YukiHookHelper.invokeOriginalMember(member, this@compat.thisObject, args) + } } /** - * Hook 替换方法回调接口 + * Hook 替换方法回调接口抽象类 * @param priority Hook 优先级- 默认 [YukiHookPriority.PRIORITY_DEFAULT] */ internal abstract class YukiMemberReplacement(override val priority: Int = YukiHookPriority.PRIORITY_DEFAULT) : YukiMemberHook(priority) { - override fun beforeHookedMember(wrapper: HookParamWrapper) { - wrapper.result = replaceHookedMember(wrapper) + override fun beforeHookedMember(param: Param) { + param.result = replaceHookedMember(param) } - override fun afterHookedMember(wrapper: HookParamWrapper) {} + override fun afterHookedMember(param: Param) {} /** * 拦截替换为指定结果 - * @param wrapper 包装实例 + * @param param Hook 结果回调接口 * @return [Any] or null */ - abstract fun replaceHookedMember(wrapper: HookParamWrapper): Any? + abstract fun replaceHookedMember(param: Param): Any? } /** - * Hook 方法回调接口 + * Hook 方法回调接口抽象类 * @param priority Hook 优先级 - 默认 [YukiHookPriority.PRIORITY_DEFAULT] */ internal abstract class YukiMemberHook(override val priority: Int = YukiHookPriority.PRIORITY_DEFAULT) : YukiHookCallback(priority) { /** * 在方法执行之前注入 - * @param wrapper 包装实例 + * @param param Hook 结果回调接口 */ - open fun beforeHookedMember(wrapper: HookParamWrapper) {} + open fun beforeHookedMember(param: Param) {} /** * 在方法执行之后注入 - * @param wrapper 包装实例 + * @param param Hook 结果回调接口 */ - open fun afterHookedMember(wrapper: HookParamWrapper) {} + open fun afterHookedMember(param: Param) {} /** - * 已经 Hook 且可被解除 Hook 的 [Member] 实现类 - * @param instance 对接 [XC_MethodHook.Unhook] + * 已经 Hook 且可被解除 Hook 的 [Member] 实现接口抽象类 */ - internal class Unhook private constructor(private val instance: XC_MethodHook.Unhook) { - - internal companion object { - - /** - * 从 [XC_MethodHook.Unhook] 创建 [Unhook] 实例 - * @param instance [XC_MethodHook.Unhook] 实例 - * @return [Unhook] - */ - internal fun wrapper(instance: XC_MethodHook.Unhook) = Unhook(instance) - } + internal abstract class Unhook internal constructor() { /** * 当前被 Hook 的 [Member] * @return [Member] or null */ - internal val member: Member? get() = instance.hookedMethod + internal abstract val member: Member? - /** 解除 [instance] 的 Hook 并从 [YukiHookedMembers.hookedMembers] 缓存数组中移除 */ + /** 解除 Hook */ + internal abstract fun unhook() + + /** 解除 Hook 并从 [YukiHookedMembers.hookedMembers] 缓存数组中移除 */ internal fun remove() { if (YukiHookBridge.hasXposedBridge.not()) return - instance.unhook() + unhook() runCatching { YukiHookedMembers.hookedMembers.remove(this) } } } } /** - * Hook 回调接口父类 + * Hook 回调接口抽象类 * @param priority Hook 优先级 */ -internal abstract class YukiHookCallback(open val priority: Int) \ No newline at end of file +internal abstract class YukiHookCallback(open val priority: Int) { + + /** + * Hook 结果回调接口 + */ + internal interface Param { + + /** + * [Member] 实例 + * @return [Member] or null + */ + val member: Member? + + /** + * 当前实例对象 + * @return [Any] or null + */ + val instance: Any? + + /** + * 方法、构造方法数组 + * @return [Array] or null + */ + val args: Array? + + /** + * 获取、设置方法结果 + * @return [Any] or null + */ + var result: Any? + + /** + * 判断是否存在设置过的方法调用抛出异常 + * @return [Boolean] + */ + val hasThrowable: Boolean + + /** + * 获取、设置方法调用抛出的异常 + * @return [Throwable] or null + * @throws Throwable + */ + var throwable: Throwable? + + /** + * 设置方法参数 + * @param index 数组下标 + * @param any 参数对象实例 + */ + fun setArgs(index: Int, any: Any?) + + /** + * 执行原始 [Member] + * + * 未进行 Hook 的 [Member] + * @param member 实例 + * @param args 参数实例 + * @return [Any] or null + */ + fun invokeOriginalMember(member: Member, vararg args: Any?): Any? + } +} \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt index 0ffe8fe3..5fa9cf40 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/parasitic/AppParasitics.kt @@ -44,7 +44,6 @@ import com.highcapable.yukihookapi.hook.factory.* import com.highcapable.yukihookapi.hook.log.yLoggerE import com.highcapable.yukihookapi.hook.log.yLoggerW import com.highcapable.yukihookapi.hook.param.type.HookEntryType -import com.highcapable.yukihookapi.hook.param.wrapper.HookParamWrapper import com.highcapable.yukihookapi.hook.type.android.* import com.highcapable.yukihookapi.hook.type.java.BooleanType import com.highcapable.yukihookapi.hook.type.java.IntType @@ -133,24 +132,24 @@ internal object AppParasitics { internal fun hookModuleAppRelated(loader: ClassLoader?, type: HookEntryType) { if (YukiHookAPI.Configs.isEnableHookSharedPreferences && type == HookEntryType.PACKAGE) YukiHookHelper.hook(ContextImplClass.method { name = "setFilePermissionsFromMode" }, object : YukiMemberHook() { - override fun beforeHookedMember(wrapper: HookParamWrapper) { - if ((wrapper.args?.get(0) as? String?)?.endsWith(suffix = "preferences.xml") == true) wrapper.args?.set(1, 1) + override fun beforeHookedMember(param: Param) { + if ((param.args?.get(0) as? String?)?.endsWith(suffix = "preferences.xml") == true) param.setArgs(index = 1, any = 1) } }) if (YukiHookAPI.Configs.isEnableHookModuleStatus) classOf(loader).apply { if (type != HookEntryType.RESOURCES) { YukiHookHelper.hook(method { name = YukiHookModuleStatus.IS_ACTIVE_METHOD_NAME }, object : YukiMemberReplacement() { - override fun replaceHookedMember(wrapper: HookParamWrapper) = true + override fun replaceHookedMember(param: Param) = true }) YukiHookHelper.hook(method { name = YukiHookModuleStatus.GET_XPOSED_TAG_METHOD_NAME }, object : YukiMemberReplacement() { - override fun replaceHookedMember(wrapper: HookParamWrapper) = YukiHookBridge.executorName + override fun replaceHookedMember(param: Param) = YukiHookBridge.executorName }) YukiHookHelper.hook(method { name = YukiHookModuleStatus.GET_XPOSED_VERSION_METHOD_NAME }, object : YukiMemberReplacement() { - override fun replaceHookedMember(wrapper: HookParamWrapper) = YukiHookBridge.executorVersion + override fun replaceHookedMember(param: Param) = YukiHookBridge.executorVersion }) } else YukiHookHelper.hook(method { name = YukiHookModuleStatus.HAS_RESOURCES_HOOK_METHOD_NAME }, object : YukiMemberReplacement() { - override fun replaceHookedMember(wrapper: HookParamWrapper) = true + override fun replaceHookedMember(param: Param) = true }) } } @@ -164,56 +163,56 @@ internal object AppParasitics { runCatching { if (AppLifecycleCallback.isCallbackSetUp) { YukiHookHelper.hook(ApplicationClass.method { name = "attach"; param(ContextClass) }, object : YukiMemberHook() { - override fun beforeHookedMember(wrapper: HookParamWrapper) { + override fun beforeHookedMember(param: Param) { runCatching { - (wrapper.args?.get(0) as? Context?)?.also { AppLifecycleCallback.attachBaseContextCallback?.invoke(it, false) } - }.onFailure { wrapper.throwable = it } + (param.args?.get(0) as? Context?)?.also { AppLifecycleCallback.attachBaseContextCallback?.invoke(it, false) } + }.onFailure { param.throwable = it } } - override fun afterHookedMember(wrapper: HookParamWrapper) { + override fun afterHookedMember(param: Param) { runCatching { - (wrapper.args?.get(0) as? Context?)?.also { AppLifecycleCallback.attachBaseContextCallback?.invoke(it, true) } - }.onFailure { wrapper.throwable = it } + (param.args?.get(0) as? Context?)?.also { AppLifecycleCallback.attachBaseContextCallback?.invoke(it, true) } + }.onFailure { param.throwable = it } } }) YukiHookHelper.hook(ApplicationClass.method { name = "onTerminate" }, object : YukiMemberHook() { - override fun afterHookedMember(wrapper: HookParamWrapper) { + override fun afterHookedMember(param: Param) { runCatching { - (wrapper.instance as? Application?)?.also { AppLifecycleCallback.onTerminateCallback?.invoke(it) } - }.onFailure { wrapper.throwable = it } + (param.instance as? Application?)?.also { AppLifecycleCallback.onTerminateCallback?.invoke(it) } + }.onFailure { param.throwable = it } } }) YukiHookHelper.hook(ApplicationClass.method { name = "onLowMemory" }, object : YukiMemberHook() { - override fun afterHookedMember(wrapper: HookParamWrapper) { + override fun afterHookedMember(param: Param) { runCatching { - (wrapper.instance as? Application?)?.also { AppLifecycleCallback.onLowMemoryCallback?.invoke(it) } - }.onFailure { wrapper.throwable = it } + (param.instance as? Application?)?.also { AppLifecycleCallback.onLowMemoryCallback?.invoke(it) } + }.onFailure { param.throwable = it } } }) YukiHookHelper.hook(ApplicationClass.method { name = "onTrimMemory"; param(IntType) }, object : YukiMemberHook() { - override fun afterHookedMember(wrapper: HookParamWrapper) { + override fun afterHookedMember(param: Param) { runCatching { - val self = wrapper.instance as? Application? ?: return - val type = wrapper.args?.get(0) as? Int? ?: return + val self = param.instance as? Application? ?: return + val type = param.args?.get(0) as? Int? ?: return AppLifecycleCallback.onTrimMemoryCallback?.invoke(self, type) - }.onFailure { wrapper.throwable = it } + }.onFailure { param.throwable = it } } }) YukiHookHelper.hook(ApplicationClass.method { name = "onConfigurationChanged" }, object : YukiMemberHook() { - override fun afterHookedMember(wrapper: HookParamWrapper) { + override fun afterHookedMember(param: Param) { runCatching { - val self = wrapper.instance as? Application? ?: return - val config = wrapper.args?.get(0) as? Configuration? ?: return + val self = param.instance as? Application? ?: return + val config = param.args?.get(0) as? Configuration? ?: return AppLifecycleCallback.onConfigurationChangedCallback?.invoke(self, config) - }.onFailure { wrapper.throwable = it } + }.onFailure { param.throwable = it } } }) } if (YukiHookAPI.Configs.isEnableDataChannel || AppLifecycleCallback.isCallbackSetUp) YukiHookHelper.hook(InstrumentationClass.method { name = "callApplicationOnCreate" }, object : YukiMemberHook() { - override fun afterHookedMember(wrapper: HookParamWrapper) { + override fun afterHookedMember(param: Param) { runCatching { - (wrapper.args?.get(0) as? Application?)?.also { + (param.args?.get(0) as? Application?)?.also { hostApplication = it AppLifecycleCallback.onCreateCallback?.invoke(it) AppLifecycleCallback.onReceiversCallback.takeIf { e -> e.isNotEmpty() }?.forEach { (_, e) -> @@ -226,7 +225,7 @@ internal object AppParasitics { } runCatching { YukiHookDataChannel.instance().register(it, packageName) } } - }.onFailure { wrapper.throwable = it } + }.onFailure { param.throwable = it } } }) } @@ -240,9 +239,9 @@ internal object AppParasitics { internal fun hookClassLoader(loader: ClassLoader?, result: (clazz: Class<*>, resolve: Boolean) -> Unit) { runCatching { YukiHookHelper.hook(JavaClassLoader.method { name = "loadClass"; param(StringType, BooleanType) }, object : YukiMemberHook() { - override fun afterHookedMember(wrapper: HookParamWrapper) { - if (wrapper.instance?.javaClass?.name == loader?.javaClass?.name) - (wrapper.result as? Class<*>?)?.also { result(it, wrapper.args?.get(1) as? Boolean ?: false) } + override fun afterHookedMember(param: Param) { + if (param.instance?.javaClass?.name == loader?.javaClass?.name) + (param.result as? Class<*>?)?.also { result(it, param.args?.get(1) as? Boolean ?: false) } } }) }.onFailure { yLoggerW(msg = "Try to hook ClassLoader failed: $it") }