mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
Modify move HookParamWrapper to YukiHookCallback.Param
This commit is contained in:
@@ -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<Any?>
|
||||
|
||||
> 获取当前 Hook 对象 `member` 或 `constructor` 的参数对象数组。
|
||||
|
||||
这里的数组每项类型默认为 `Any`,你可以使用 `args` 方法来实现 `ArgsModifyer.cast` 功能。
|
||||
|
||||
### ~~firstArgs *- field*~~ <!-- {docsify-ignore} -->
|
||||
|
||||
**变更记录**
|
||||
|
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 <T> Member.invokeOriginal(vararg args: Any?) = wrapper?.invokeOriginalMember(member = this, *args) as? T?
|
||||
fun <T> 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"
|
||||
}
|
@@ -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<Any?>? 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]"
|
||||
}
|
@@ -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)
|
||||
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<Any?>?
|
||||
|
||||
/**
|
||||
* 获取、设置方法结果
|
||||
* @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?
|
||||
}
|
||||
}
|
@@ -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<YukiHookModuleStatus>(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") }
|
||||
|
Reference in New Issue
Block a user