From a6a781121aa2139205bf9fc756d923f81bf348d8 Mon Sep 17 00:00:00 2001 From: fankesyooni Date: Tue, 16 Aug 2022 03:57:25 +0800 Subject: [PATCH] Added HookCallback when catch the throwable make it throw to app function --- docs/api/public/YukiMemberHookCreater.md | 40 +++++++++- docs/guide/example.md | 76 ++++++++++++++++++- .../hook/core/YukiMemberHookCreater.kt | 24 +++++- 3 files changed, 135 insertions(+), 5 deletions(-) diff --git a/docs/api/public/YukiMemberHookCreater.md b/docs/api/public/YukiMemberHookCreater.md index a5cb1073..9f0bf6fb 100644 --- a/docs/api/public/YukiMemberHookCreater.md +++ b/docs/api/public/YukiMemberHookCreater.md @@ -429,13 +429,17 @@ inline fun HookParam.injectMember(priority: Int, tag: String, initiate: MemberHo #### beforeHook [method] ```kotlin -fun beforeHook(initiate: HookParam.() -> Unit) +fun beforeHook(initiate: HookParam.() -> Unit): HookCallback ``` **变更记录** `v1.0` `添加` +`v1.0.93` `修改` + +新增 `HookCallback` 返回类型 + **功能描述** > 在方法执行完成前 Hook。 @@ -443,13 +447,17 @@ fun beforeHook(initiate: HookParam.() -> Unit) #### afterHook [method] ```kotlin -fun afterHook(initiate: HookParam.() -> Unit) +fun afterHook(initiate: HookParam.() -> Unit): HookCallback ``` **变更记录** `v1.0` `添加` +`v1.0.93` `修改` + +新增 `HookCallback` 返回类型 + **功能描述** > 在方法执行完成后 Hook。 @@ -562,6 +570,34 @@ fun removeSelf(result: (Boolean) -> Unit) !> 你只能在 Hook 回调方法中使用此功能。 +#### HookCallback [class] + +```kotlin +inner class HookCallback internal constructor() +``` + +**变更记录** + +`v1.0.93` `新增` + +**功能描述** + +> Hook 方法体回调实现类。 + +##### onFailureThrowToApp [method] + +```kotlin +fun onFailureThrowToApp() +``` + +**变更记录** + +`v1.0.93` `新增` + +**功能描述** + +> 当回调方法体内发生异常时将异常抛出给当前 Hook APP。 + #### Result [class] ```kotlin diff --git a/docs/guide/example.md b/docs/guide/example.md index 6d0d0a1d..78e36341 100644 --- a/docs/guide/example.md +++ b/docs/guide/example.md @@ -348,6 +348,8 @@ injectMember { > `YukiHookAPI` 重新设计了对异常的监听,任何异常都不会在 Hook 过程中抛出,避免打断下一个 Hook 流程导致 Hook 进程“死掉”。 +### 监听异常 + 你可以处理 Hook 方法过程发生的异常。 > 示例如下 @@ -408,6 +410,78 @@ method { 这里介绍了可能发生的常见异常,若要了解更多请参考 [API 异常处理](config/api-exception.md)。 +### 抛出异常 + +在某些情况下,你可以**手动抛出异常**来达到提醒某些功能存在问题的目的。 + +上面已经介绍过,在 `hook` 方法体内抛出的异常会被 `YukiHookAPI` 接管,避免打断下一个 Hook 流程导致 Hook 进程“死掉”。 + +以下是 `YukiHookAPI` 接管时这些异常的运作方式。 + +> 示例如下 + +```kotlin +// <情景1> +injectMember { + throw RuntimeException("Exception Test") +}.result { + // 能够捕获到 RuntimeException + onHookingFailure {} +} +// <情景2> +injectMember { + method { + // ... + } + afterHook { + throw RuntimeException("Exception Test") + } +}.result { + // 能够捕获到 RuntimeException + onConductFailure { param, throwable -> } +} +``` + +以上情景只会在 (Xposed) 宿主环境被处理,不会对宿主自身造成任何影响。 + +若我们想将这些异常直接抛给宿主,原生的 Xposed 为我们提供了 `param.throwable` 方法,`YukiHookAPI` 同样可以实现此功能。 + +若想在 Hook 回调方法中将一个异常直接抛给宿主,可以有如下实现方法。 + +> 示例如下 + +```kotlin +injectMember { + method { + // ... + } + afterHook { + RuntimeException("Exception Test").throwToApp() + } +} +``` + +你也可以直接在 Hook 回调方法中抛出异常,然后标识将异常抛给宿主。 + +> 示例如下 + +```kotlin +injectMember { + method { + // ... + } + afterHook { + throw RuntimeException("Exception Test") + }.onFailureThrowToApp() +} +``` + +以上两种方法均可在宿主接收到异常从而使宿主进程崩溃。 + +!> 为了保证 Hook 调用域与宿主内调用域相互隔离,异常只有在 `beforeHook` 与 `afterHook` 回调方法体中才能抛给宿主。 + +更多功能请参考 [HookCallback](api/document?id=hookcallback-class)。 + ## 状态监听 在使用 `XposedHelper` 的同学往往会在 Hook 后打印 `UnHook` 的方法确定是否 Hook 成功。 @@ -532,7 +606,7 @@ if(YukiHookAPI.Status.isModuleActive) { 若要了解更多可 [点击这里](api/document?id=status-object) 进行查看。 -!> 新版本的 API 修改了激活逻辑判断方式,现在你可以在模块与 Hook APP(宿主)中同时使用此 API。 +!> 新版本的 API 修改了激活逻辑判断方式,现在你可以在模块与 Hook APP (宿主) 中同时使用此 API。 !> 需要确保 `YukiHookAPI.Configs.isEnableHookModuleStatus` 是启用状态。 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 990a8386..b14af341 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 @@ -228,6 +228,9 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara /** 全部错误回调 */ private var onAllFailureCallback: ((Throwable) -> Unit)? = null + /** 发生异常时是否将异常抛出给当前 Hook APP */ + private var isOnFailureThrowToApp = false + /** 是否为替换 Hook 模式 */ private var isReplaceHookMode = false @@ -390,10 +393,12 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara * * - 不可与 [replaceAny]、[replaceUnit]、[replaceTo] 同时使用 * @param initiate [HookParam] 方法体 + * @return [HookCallback] */ - fun beforeHook(initiate: HookParam.() -> Unit) { + fun beforeHook(initiate: HookParam.() -> Unit): HookCallback { isReplaceHookMode = false beforeHookCallback = initiate + return HookCallback() } /** @@ -401,10 +406,12 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara * * - 不可与 [replaceAny]、[replaceUnit]、[replaceTo] 同时使用 * @param initiate [HookParam] 方法体 + * @return [HookCallback] */ - fun afterHook(initiate: HookParam.() -> Unit) { + fun afterHook(initiate: HookParam.() -> Unit): HookCallback { isReplaceHookMode = false afterHookCallback = initiate + return HookCallback() } /** @@ -584,6 +591,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara onConductFailureCallback?.invoke(param, it) onAllFailureCallback?.invoke(it) if (onConductFailureCallback == null && onAllFailureCallback == null) onHookFailureMsg(it) + if (isOnFailureThrowToApp) wrapper.throwable = it } } } @@ -598,6 +606,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara onConductFailureCallback?.invoke(param, it) onAllFailureCallback?.invoke(it) if (onConductFailureCallback == null && onAllFailureCallback == null) onHookFailureMsg(it) + if (isOnFailureThrowToApp) wrapper.throwable = it } } } @@ -650,6 +659,17 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara override fun toString() = "[tag] $tag [priority] $priority [class] $hookClass [members] $members" + /** + * Hook 方法体回调实现类 + */ + inner class HookCallback internal constructor() { + + /** 当回调方法体内发生异常时将异常抛出给当前 Hook APP */ + fun onFailureThrowToApp() { + isOnFailureThrowToApp = true + } + } + /** * 监听 Hook 结果实现类 *