mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-06 10:45:47 +08:00
Added new hookAllMembers function in YukiMemberHookCreater and remove old way and fix some bug
This commit is contained in:
@@ -152,16 +152,26 @@ inner class MemberHookCreater internal constructor(private val priority: Int, in
|
|||||||
|
|
||||||
> Hook 核心功能实现类,查找和处理需要 Hook 的方法、构造方法。
|
> Hook 核心功能实现类,查找和处理需要 Hook 的方法、构造方法。
|
||||||
|
|
||||||
#### member [field]
|
#### ~~member [field]~~ <!-- {docsify-ignore} -->
|
||||||
|
|
||||||
```kotlin
|
|
||||||
var member: Member?
|
|
||||||
```
|
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
|
|
||||||
`v1.0` `添加`
|
`v1.0` `添加`
|
||||||
|
|
||||||
|
`v1.0.93` `移除`
|
||||||
|
|
||||||
|
请转移到 `members`
|
||||||
|
|
||||||
|
#### members [method]
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
fun members(vararg member: Member?)
|
||||||
|
```
|
||||||
|
|
||||||
|
**变更记录**
|
||||||
|
|
||||||
|
`v1.0.93` `新增`
|
||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> 手动指定要 Hook 的方法、构造方法。
|
> 手动指定要 Hook 的方法、构造方法。
|
||||||
@@ -176,72 +186,64 @@ var member: Member?
|
|||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
injectMember {
|
injectMember {
|
||||||
member = instanceClass.getMethod("test", StringType)
|
members(instanceClass.getMethod("test", StringType))
|
||||||
beforeHook {}
|
beforeHook {}
|
||||||
afterHook {}
|
afterHook {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### allMethods [method]
|
同样地,你也可以传入一组方法同时进行 Hook。
|
||||||
|
|
||||||
```kotlin
|
|
||||||
fun allMethods(name: String)
|
|
||||||
```
|
|
||||||
|
|
||||||
**变更记录**
|
|
||||||
|
|
||||||
`v1.0` `添加`
|
|
||||||
|
|
||||||
**功能描述**
|
|
||||||
|
|
||||||
> 查找并 Hook 当前 `Class` 中指定 `name` 的全部方法。
|
|
||||||
|
|
||||||
**功能示例**
|
|
||||||
|
|
||||||
使用此方法可将当前类的全部同名方法进行批量 Hook。
|
|
||||||
|
|
||||||
!> 无法准确处理每个方法的 `param`,建议使用 `method` 对每个方法单独 Hook。
|
|
||||||
|
|
||||||
> 示例如下
|
> 示例如下
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
injectMember {
|
injectMember {
|
||||||
allMethods(name = "test")
|
members(
|
||||||
|
instanceClass.getMethod("test1", StringType),
|
||||||
|
instanceClass.getMethod("test2", StringType),
|
||||||
|
instanceClass.getMethod("test3", StringType)
|
||||||
|
)
|
||||||
beforeHook {}
|
beforeHook {}
|
||||||
afterHook {}
|
afterHook {}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### allConstructors [method]
|
#### ~~allMethods [method]~~ <!-- {docsify-ignore} -->
|
||||||
|
|
||||||
```kotlin
|
|
||||||
fun allConstructors()
|
|
||||||
```
|
|
||||||
|
|
||||||
**变更记录**
|
**变更记录**
|
||||||
|
|
||||||
`v1.0` `添加`
|
`v1.0` `添加`
|
||||||
|
|
||||||
**功能描述**
|
`v1.0.93` `作废`
|
||||||
|
|
||||||
> 查找并 Hook 当前 `Class` 中的全部构造方法。
|
请使用 `method { name = /** name */ }.all()` 来取代它
|
||||||
|
|
||||||
**功能示例**
|
#### ~~allConstructors [method]~~ <!-- {docsify-ignore} -->
|
||||||
|
|
||||||
使用此方法可将当前类的全部构造方法进行批量 Hook。
|
**变更记录**
|
||||||
|
|
||||||
!> 无法准确处理每个构造方法的 `param`,建议使用 `constructor` 对每个构造方法单独 Hook。
|
`v1.0` `添加`
|
||||||
|
|
||||||
> 示例如下
|
`v1.0.93` `作废`
|
||||||
|
|
||||||
|
请使用 `constructor().all()` 来取代它
|
||||||
|
|
||||||
|
#### allMembers [method]
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
injectMember {
|
fun allMembers()
|
||||||
allConstructors()
|
|
||||||
beforeHook {}
|
|
||||||
afterHook {}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**变更记录**
|
||||||
|
|
||||||
|
`v1.0.93` `新增`
|
||||||
|
|
||||||
|
**功能描述**
|
||||||
|
|
||||||
|
> 查找并 Hook `hookClass` 中的全部方法、构造方法。
|
||||||
|
|
||||||
|
!> 警告:无法准确处理每个方法的返回值和 `param`,建议使用 `method` or `constructor` 对每个方法单独 Hook。
|
||||||
|
|
||||||
#### method [method]
|
#### method [method]
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
@@ -618,7 +620,7 @@ fun onHooked(result: (Member) -> Unit): Result
|
|||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> 监听 `member` Hook 成功的回调方法。
|
> 监听 `members` Hook 成功的回调方法。
|
||||||
|
|
||||||
在首次 Hook 成功后回调。
|
在首次 Hook 成功后回调。
|
||||||
|
|
||||||
@@ -636,9 +638,9 @@ fun onAlreadyHooked(result: (Member) -> Unit): Result
|
|||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> 监听 `member` 重复 Hook 的回调方法。
|
> 监听 `members` 重复 Hook 的回调方法。
|
||||||
|
|
||||||
!> 同一个 `hookClass` 中的同一个 `member` 不会被 API 重复 Hook,若由于各种原因重复 Hook 会回调此方法。
|
!> 同一个 `hookClass` 中的同一个 `members` 不会被 API 重复 Hook,若由于各种原因重复 Hook 会回调此方法。
|
||||||
|
|
||||||
##### onNoSuchMemberFailure [method]
|
##### onNoSuchMemberFailure [method]
|
||||||
|
|
||||||
@@ -652,7 +654,7 @@ fun onNoSuchMemberFailure(result: (Throwable) -> Unit): Result
|
|||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> 监听 `member` 不存在发生错误的回调方法。
|
> 监听 `members` 不存在发生错误的回调方法。
|
||||||
|
|
||||||
##### onConductFailure [method]
|
##### onConductFailure [method]
|
||||||
|
|
||||||
@@ -708,7 +710,7 @@ fun ignoredNoSuchMemberFailure(): Result
|
|||||||
|
|
||||||
**功能描述**
|
**功能描述**
|
||||||
|
|
||||||
> 忽略 `member` 不存在发生的错误。
|
> 忽略 `members` 不存在发生的错误。
|
||||||
|
|
||||||
##### ignoredConductFailure [method]
|
##### ignoredConductFailure [method]
|
||||||
|
|
||||||
|
@@ -36,6 +36,8 @@ import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder
|
|||||||
import com.highcapable.yukihookapi.hook.core.finder.FieldFinder
|
import com.highcapable.yukihookapi.hook.core.finder.FieldFinder
|
||||||
import com.highcapable.yukihookapi.hook.core.finder.MethodFinder
|
import com.highcapable.yukihookapi.hook.core.finder.MethodFinder
|
||||||
import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder
|
import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder
|
||||||
|
import com.highcapable.yukihookapi.hook.factory.allConstructors
|
||||||
|
import com.highcapable.yukihookapi.hook.factory.allMethods
|
||||||
import com.highcapable.yukihookapi.hook.log.yLoggerE
|
import com.highcapable.yukihookapi.hook.log.yLoggerE
|
||||||
import com.highcapable.yukihookapi.hook.log.yLoggerI
|
import com.highcapable.yukihookapi.hook.log.yLoggerI
|
||||||
import com.highcapable.yukihookapi.hook.log.yLoggerW
|
import com.highcapable.yukihookapi.hook.log.yLoggerW
|
||||||
@@ -70,12 +72,6 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
/** 更快回调 Hook 方法结果 */
|
/** 更快回调 Hook 方法结果 */
|
||||||
val PRIORITY_HIGHEST = YukiHookPriority.PRIORITY_HIGHEST
|
val PRIORITY_HIGHEST = YukiHookPriority.PRIORITY_HIGHEST
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook 模式定义
|
|
||||||
*/
|
|
||||||
@PublishedApi
|
|
||||||
internal enum class HookMemberMode { HOOK_ALL_METHODS, HOOK_ALL_CONSTRUCTORS, HOOK_CONVENTIONAL }
|
|
||||||
|
|
||||||
/** [hookClass] 找不到时出现的错误回调 */
|
/** [hookClass] 找不到时出现的错误回调 */
|
||||||
private var onHookClassNotFoundFailureCallback: ((Throwable) -> Unit)? = null
|
private var onHookClassNotFoundFailureCallback: ((Throwable) -> Unit)? = null
|
||||||
|
|
||||||
@@ -183,16 +179,13 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
/** [replaceAny]、[replaceUnit] 回调 */
|
/** [replaceAny]、[replaceUnit] 回调 */
|
||||||
private var replaceHookCallback: (HookParam.() -> Any?)? = null
|
private var replaceHookCallback: (HookParam.() -> Any?)? = null
|
||||||
|
|
||||||
/** [replaceTo]、[replaceToTrue]、[replaceToFalse]、[intercept] 的值 */
|
|
||||||
private var replaceHookResult: Any? = null
|
|
||||||
|
|
||||||
/** Hook 成功时回调 */
|
/** Hook 成功时回调 */
|
||||||
private var onHookedCallback: ((Member) -> Unit)? = null
|
private var onHookedCallback: ((Member) -> Unit)? = null
|
||||||
|
|
||||||
/** 重复 Hook 时回调 */
|
/** 重复 Hook 时回调 */
|
||||||
private var onAlreadyHookedCallback: ((Member) -> Unit)? = null
|
private var onAlreadyHookedCallback: ((Member) -> Unit)? = null
|
||||||
|
|
||||||
/** 找不到 [member] 出现错误回调 */
|
/** 找不到 [members] 出现错误回调 */
|
||||||
private var onNoSuchMemberFailureCallback: ((Throwable) -> Unit)? = null
|
private var onNoSuchMemberFailureCallback: ((Throwable) -> Unit)? = null
|
||||||
|
|
||||||
/** Hook 过程中出现错误回调 */
|
/** Hook 过程中出现错误回调 */
|
||||||
@@ -207,9 +200,6 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
/** 是否为替换 Hook 模式 */
|
/** 是否为替换 Hook 模式 */
|
||||||
private var isReplaceHookMode = false
|
private var isReplaceHookMode = false
|
||||||
|
|
||||||
/** 是否为仅替换 Hook 结果模式 */
|
|
||||||
private var isReplaceHookOnlyResultMode = false
|
|
||||||
|
|
||||||
/** 是否对当前 [MemberHookCreater] 禁止执行 Hook 操作 */
|
/** 是否对当前 [MemberHookCreater] 禁止执行 Hook 操作 */
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal var isDisableMemberRunHook = false
|
internal var isDisableMemberRunHook = false
|
||||||
@@ -218,77 +208,84 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal var findingThrowable: Throwable? = null
|
internal var findingThrowable: Throwable? = null
|
||||||
|
|
||||||
/** 标识是否已经设置了要 Hook 的 [member] */
|
/** 标识是否已经设置了要 Hook 的 [members] */
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal var isHookMemberSetup = false
|
internal var isHookMemberSetup = false
|
||||||
|
|
||||||
/** Hook 当前模式类型 */
|
|
||||||
@PublishedApi
|
|
||||||
internal var hookMemberMode = HookMemberMode.HOOK_CONVENTIONAL
|
|
||||||
|
|
||||||
/** 当前的查找实例 */
|
/** 当前的查找实例 */
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal var finder: BaseFinder? = null
|
internal var finder: BaseFinder? = null
|
||||||
|
|
||||||
/** 全部方法的名称 */
|
/** 当前被 Hook 的方法、构造方法实例数组 */
|
||||||
private var allMethodsName = ""
|
private val memberUnhooks = HashSet<YukiMemberHook.Unhook>()
|
||||||
|
|
||||||
/** 当前被 Hook 的方法、构造方法实例 */
|
/** 当前需要 Hook 的方法、构造方法 */
|
||||||
private var memberUnhook: YukiMemberHook.Unhook? = null
|
internal val members = HashSet<Member>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手动指定要 Hook 的方法、构造方法
|
* 手动指定要 Hook 的方法、构造方法
|
||||||
*
|
*
|
||||||
* 你可以调用 [instanceClass] 来手动查询要 Hook 的方法
|
* 你可以调用 [instanceClass] 来手动查询要 Hook 的方法
|
||||||
|
*
|
||||||
|
* - ❗不建议使用此方法设置目标需要 Hook 的 [Member] 对象 - 你可以使用 [method] 或 [constructor] 方法
|
||||||
|
*
|
||||||
|
* - ❗在同一个 [injectMember] 中你只能使用一次 [members]、[allMembers]、[method]、[constructor] 方法 - 否则结果会被替换
|
||||||
|
* @param member 要指定的 [Member] 或 [Member] 数组
|
||||||
|
* @throws IllegalStateException 如果 [member] 参数为空
|
||||||
*/
|
*/
|
||||||
var member: Member? = null
|
fun members(vararg member: Member?) {
|
||||||
|
if (member.isEmpty()) error("Custom Hooking Members is empty")
|
||||||
|
members.clear()
|
||||||
|
member.forEach { it?.also { members.add(it) } }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找并 Hook [hookClass] 中指定 [name] 的全部方法
|
* 查找并 Hook [hookClass] 中指定 [name] 的全部方法
|
||||||
*
|
*
|
||||||
* 在同一个 [injectMember] 中
|
* - ❗此方法已弃用 - 在之后的版本中将直接被删除
|
||||||
*
|
*
|
||||||
* 你只能使用一次 [allMethods]、[allConstructors]、[method]、[constructor] 方法 - 否则结果会被替换
|
* - ❗请现在转移到 [MethodFinder]
|
||||||
*
|
|
||||||
* - ❗警告:无法准确处理每个方法的返回值和 param - 建议使用 [method] 对每个方法单独 Hook
|
|
||||||
*
|
|
||||||
* - ❗如果 [hookClass] 中没有方法可能会发生错误
|
|
||||||
* @param name 方法名称
|
* @param name 方法名称
|
||||||
|
* @return [ArrayList]<[MethodFinder.Result.Instance]>
|
||||||
*/
|
*/
|
||||||
fun allMethods(name: String) {
|
@Deprecated("请使用新方式来实现 Hook 所有方法", ReplaceWith(expression = "method { this.name = name }.all()"))
|
||||||
allMethodsName = name
|
fun allMethods(name: String) = method { this.name = name }.all()
|
||||||
hookMemberMode = HookMemberMode.HOOK_ALL_METHODS
|
|
||||||
isHookMemberSetup = true
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找并 Hook [hookClass] 中的全部构造方法
|
* 查找并 Hook [hookClass] 中的全部构造方法
|
||||||
*
|
*
|
||||||
* 在同一个 [injectMember] 中
|
* - ❗此方法已弃用 - 在之后的版本中将直接被删除
|
||||||
*
|
*
|
||||||
* 你只能使用一次 [allMethods]、[allConstructors]、[method]、[constructor] 方法 - 否则结果会被替换
|
* - ❗请现在转移到 [ConstructorFinder]
|
||||||
*
|
* @return [ArrayList]<[ConstructorFinder.Result.Instance]>
|
||||||
* - ❗警告:无法准确处理每个构造方法的 param - 建议使用 [constructor] 对每个构造方法单独 Hook
|
|
||||||
*
|
|
||||||
* - ❗如果 [hookClass] 中没有构造方法可能会发生错误
|
|
||||||
*/
|
*/
|
||||||
fun allConstructors() {
|
@Deprecated("请使用新方式来实现 Hook 所有构造方法", ReplaceWith(expression = "constructor().all()"))
|
||||||
allMethodsName = "<init>"
|
fun allConstructors() = constructor().all()
|
||||||
hookMemberMode = HookMemberMode.HOOK_ALL_CONSTRUCTORS
|
|
||||||
|
/**
|
||||||
|
* 查找并 Hook [hookClass] 中的全部方法、构造方法
|
||||||
|
*
|
||||||
|
* - ❗在同一个 [injectMember] 中你只能使用一次 [members]、[allMembers]、[method]、[constructor] 方法 - 否则结果会被替换
|
||||||
|
*
|
||||||
|
* - ❗警告:无法准确处理每个方法的返回值和 param - 建议使用 [method] or [constructor] 对每个方法单独 Hook
|
||||||
|
*
|
||||||
|
* - ❗如果 [hookClass] 中没有方法可能会发生错误
|
||||||
|
*/
|
||||||
|
fun allMembers() {
|
||||||
|
members.clear()
|
||||||
|
hookClass.instance?.allConstructors { _, constructor -> members.add(constructor) }
|
||||||
|
hookClass.instance?.allMethods { _, method -> members.add(method) }
|
||||||
isHookMemberSetup = true
|
isHookMemberSetup = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找 [hookClass] 需要 Hook 的方法
|
* 查找 [hookClass] 需要 Hook 的方法
|
||||||
*
|
*
|
||||||
* 在同一个 [injectMember] 中
|
* - ❗在同一个 [injectMember] 中你只能使用一次 [members]、[allMembers]、[method]、[constructor] 方法 - 否则结果会被替换
|
||||||
*
|
|
||||||
* 你只能使用一次 [allMethods]、[allConstructors]、[method]、[constructor] 方法 - 否则结果会被替换
|
|
||||||
* @param initiate 方法体
|
* @param initiate 方法体
|
||||||
* @return [MethodFinder.Result]
|
* @return [MethodFinder.Result]
|
||||||
*/
|
*/
|
||||||
inline fun method(initiate: MethodFinder.() -> Unit) = try {
|
inline fun method(initiate: MethodFinder.() -> Unit) = try {
|
||||||
hookMemberMode = HookMemberMode.HOOK_CONVENTIONAL
|
|
||||||
isHookMemberSetup = true
|
isHookMemberSetup = true
|
||||||
MethodFinder(hookInstance = this, hookClass.instance).apply(initiate).apply { finder = this }.build(isBind = true)
|
MethodFinder(hookInstance = this, hookClass.instance).apply(initiate).apply { finder = this }.build(isBind = true)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
@@ -299,14 +296,11 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
/**
|
/**
|
||||||
* 查找 [hookClass] 需要 Hook 的构造方法
|
* 查找 [hookClass] 需要 Hook 的构造方法
|
||||||
*
|
*
|
||||||
* 在同一个 [injectMember] 中
|
* - ❗在同一个 [injectMember] 中你只能使用一次 [members]、[allMembers]、[method]、[constructor] 方法 - 否则结果会被替换
|
||||||
*
|
|
||||||
* 你只能使用一次 [allMethods]、[allConstructors]、[method]、[constructor] 方法 - 否则结果会被替换
|
|
||||||
* @param initiate 方法体
|
* @param initiate 方法体
|
||||||
* @return [ConstructorFinder.Result]
|
* @return [ConstructorFinder.Result]
|
||||||
*/
|
*/
|
||||||
inline fun constructor(initiate: ConstructorFinder.() -> Unit = { emptyParam() }) = try {
|
inline fun constructor(initiate: ConstructorFinder.() -> Unit = { emptyParam() }) = try {
|
||||||
hookMemberMode = HookMemberMode.HOOK_CONVENTIONAL
|
|
||||||
isHookMemberSetup = true
|
isHookMemberSetup = true
|
||||||
ConstructorFinder(hookInstance = this, hookClass.instance).apply(initiate).apply { finder = this }.build(isBind = true)
|
ConstructorFinder(hookInstance = this, hookClass.instance).apply(initiate).apply { finder = this }.build(isBind = true)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
@@ -357,7 +351,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
/**
|
/**
|
||||||
* 在方法执行完成前 Hook
|
* 在方法执行完成前 Hook
|
||||||
*
|
*
|
||||||
* 不可与 [replaceAny]、[replaceUnit]、[replaceTo] 同时使用
|
* - 不可与 [replaceAny]、[replaceUnit]、[replaceTo] 同时使用
|
||||||
* @param initiate [HookParam] 方法体
|
* @param initiate [HookParam] 方法体
|
||||||
*/
|
*/
|
||||||
fun beforeHook(initiate: HookParam.() -> Unit) {
|
fun beforeHook(initiate: HookParam.() -> Unit) {
|
||||||
@@ -368,7 +362,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
/**
|
/**
|
||||||
* 在方法执行完成后 Hook
|
* 在方法执行完成后 Hook
|
||||||
*
|
*
|
||||||
* 不可与 [replaceAny]、[replaceUnit]、[replaceTo] 同时使用
|
* - 不可与 [replaceAny]、[replaceUnit]、[replaceTo] 同时使用
|
||||||
* @param initiate [HookParam] 方法体
|
* @param initiate [HookParam] 方法体
|
||||||
*/
|
*/
|
||||||
fun afterHook(initiate: HookParam.() -> Unit) {
|
fun afterHook(initiate: HookParam.() -> Unit) {
|
||||||
@@ -379,37 +373,34 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
/**
|
/**
|
||||||
* 拦截并替换此方法内容 - 给出返回值
|
* 拦截并替换此方法内容 - 给出返回值
|
||||||
*
|
*
|
||||||
* 不可与 [beforeHook]、[afterHook] 同时使用
|
* - 不可与 [beforeHook]、[afterHook] 同时使用
|
||||||
* @param initiate [HookParam] 方法体
|
* @param initiate [HookParam] 方法体
|
||||||
*/
|
*/
|
||||||
fun replaceAny(initiate: HookParam.() -> Any?) {
|
fun replaceAny(initiate: HookParam.() -> Any?) {
|
||||||
isReplaceHookMode = true
|
isReplaceHookMode = true
|
||||||
isReplaceHookOnlyResultMode = false
|
|
||||||
replaceHookCallback = initiate
|
replaceHookCallback = initiate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拦截并替换此方法内容 - 没有返回值 ([Unit])
|
* 拦截并替换此方法内容 - 没有返回值 ([Unit])
|
||||||
*
|
*
|
||||||
* 不可与 [beforeHook]、[afterHook] 同时使用
|
* - 不可与 [beforeHook]、[afterHook] 同时使用
|
||||||
* @param initiate [HookParam] 方法体
|
* @param initiate [HookParam] 方法体
|
||||||
*/
|
*/
|
||||||
fun replaceUnit(initiate: HookParam.() -> Unit) {
|
fun replaceUnit(initiate: HookParam.() -> Unit) {
|
||||||
isReplaceHookMode = true
|
isReplaceHookMode = true
|
||||||
isReplaceHookOnlyResultMode = false
|
|
||||||
replaceHookCallback = initiate
|
replaceHookCallback = initiate
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拦截并替换方法返回值
|
* 拦截并替换方法返回值
|
||||||
*
|
*
|
||||||
* 不可与 [beforeHook]、[afterHook] 同时使用
|
* - 不可与 [beforeHook]、[afterHook] 同时使用
|
||||||
* @param any 要替换为的返回值对象
|
* @param any 要替换为的返回值对象
|
||||||
*/
|
*/
|
||||||
fun replaceTo(any: Any?) {
|
fun replaceTo(any: Any?) {
|
||||||
isReplaceHookMode = true
|
isReplaceHookMode = true
|
||||||
isReplaceHookOnlyResultMode = true
|
replaceHookCallback = { any }
|
||||||
replaceHookResult = any
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -417,12 +408,11 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
*
|
*
|
||||||
* - ❗确保替换方法的返回对象为 [Boolean]
|
* - ❗确保替换方法的返回对象为 [Boolean]
|
||||||
*
|
*
|
||||||
* 不可与 [beforeHook]、[afterHook] 同时使用
|
* - 不可与 [beforeHook]、[afterHook] 同时使用
|
||||||
*/
|
*/
|
||||||
fun replaceToTrue() {
|
fun replaceToTrue() {
|
||||||
isReplaceHookMode = true
|
isReplaceHookMode = true
|
||||||
isReplaceHookOnlyResultMode = true
|
replaceHookCallback = { true }
|
||||||
replaceHookResult = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -430,12 +420,11 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
*
|
*
|
||||||
* - ❗确保替换方法的返回对象为 [Boolean]
|
* - ❗确保替换方法的返回对象为 [Boolean]
|
||||||
*
|
*
|
||||||
* 不可与 [beforeHook]、[afterHook] 同时使用
|
* - 不可与 [beforeHook]、[afterHook] 同时使用
|
||||||
*/
|
*/
|
||||||
fun replaceToFalse() {
|
fun replaceToFalse() {
|
||||||
isReplaceHookMode = true
|
isReplaceHookMode = true
|
||||||
isReplaceHookOnlyResultMode = true
|
replaceHookCallback = { false }
|
||||||
replaceHookResult = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -443,12 +432,11 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
*
|
*
|
||||||
* - ❗这将会禁止此方法执行并返回 null
|
* - ❗这将会禁止此方法执行并返回 null
|
||||||
*
|
*
|
||||||
* 不可与 [beforeHook]、[afterHook] 同时使用
|
* - 不可与 [beforeHook]、[afterHook] 同时使用
|
||||||
*/
|
*/
|
||||||
fun intercept() {
|
fun intercept() {
|
||||||
isReplaceHookMode = true
|
isReplaceHookMode = true
|
||||||
isReplaceHookOnlyResultMode = true
|
replaceHookCallback = { null }
|
||||||
replaceHookResult = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -480,17 +468,51 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
members.takeIf { it.isNotEmpty() }?.forEach { member ->
|
||||||
|
runCatching {
|
||||||
|
member.hook().also {
|
||||||
|
when {
|
||||||
|
it.first?.member == null -> error("Hook Member [$member] failed")
|
||||||
|
it.second -> onAlreadyHookedCallback?.invoke(it.first?.member!!)
|
||||||
|
else -> it.first?.also { e ->
|
||||||
|
memberUnhooks.add(e)
|
||||||
|
onHookedCallback?.invoke(e.member!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.onFailure {
|
||||||
|
onHookingFailureCallback?.invoke(it)
|
||||||
|
onAllFailureCallback?.invoke(it)
|
||||||
|
if (isNotIgnoredHookingFailure) onHookFailureMsg(it, member)
|
||||||
|
}
|
||||||
|
} ?: Throwable("Finding Error isSetUpMember [$isHookMemberSetup] [$tag]").also {
|
||||||
|
onNoSuchMemberFailureCallback?.invoke(it)
|
||||||
|
onHookingFailureCallback?.invoke(it)
|
||||||
|
onAllFailureCallback?.invoke(it)
|
||||||
|
if (isNotIgnoredNoSuchMemberFailure) yLoggerE(
|
||||||
|
msg = "$hostTagName " + (if (isHookMemberSetup)
|
||||||
|
"Hooked Member with a finding error by $hookClass [$tag]"
|
||||||
|
else "Hooked Member cannot be non-null by $hookClass [$tag]"),
|
||||||
|
e = findingThrowable ?: it
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook 方法、构造方法
|
||||||
|
* @return [Pair] - ([YukiMemberHook.Unhook] or null,[Boolean] 是否已经 Hook)
|
||||||
|
*/
|
||||||
|
private fun Member.hook(): Pair<YukiMemberHook.Unhook?, Boolean> {
|
||||||
/** 定义替换 Hook 的 [HookParam] */
|
/** 定义替换 Hook 的 [HookParam] */
|
||||||
val replaceHookParam = HookParam(createrInstance = this@YukiMemberHookCreater)
|
val replaceHookParam = HookParam(createrInstance = this@YukiMemberHookCreater)
|
||||||
|
|
||||||
/** 定义替换 Hook 回调方法体 */
|
/** 定义替换 Hook 回调方法体 */
|
||||||
val replaceMent = object : YukiMemberReplacement(priority) {
|
val replaceMent = object : YukiMemberReplacement(priority) {
|
||||||
override fun replaceHookedMember(wrapper: HookParamWrapper): Any? {
|
override fun replaceHookedMember(wrapper: HookParamWrapper) =
|
||||||
return replaceHookParam.assign(wrapper).let { param ->
|
replaceHookParam.assign(wrapper).let { param ->
|
||||||
try {
|
try {
|
||||||
if (replaceHookCallback != null || isReplaceHookOnlyResultMode)
|
if (replaceHookCallback != null) onHookLogMsg(msg = "Replace Hook Member [${this@hook}] done [$tag]")
|
||||||
onHookLogMsg(msg = "Replace Hook Member [${member ?: "All Member $allMethodsName"}] done [$tag]")
|
replaceHookCallback?.invoke(param).also { HookParam.invoke() }
|
||||||
(if (isReplaceHookOnlyResultMode) replaceHookResult else replaceHookCallback?.invoke(param)).also { HookParam.invoke() }
|
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
onConductFailureCallback?.invoke(param, e)
|
onConductFailureCallback?.invoke(param, e)
|
||||||
onAllFailureCallback?.invoke(e)
|
onAllFailureCallback?.invoke(e)
|
||||||
@@ -499,7 +521,6 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/** 定义前 Hook 的 [HookParam] */
|
/** 定义前 Hook 的 [HookParam] */
|
||||||
val beforeHookParam = HookParam(createrInstance = this@YukiMemberHookCreater)
|
val beforeHookParam = HookParam(createrInstance = this@YukiMemberHookCreater)
|
||||||
@@ -513,8 +534,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
beforeHookParam.assign(wrapper).also { param ->
|
beforeHookParam.assign(wrapper).also { param ->
|
||||||
runCatching {
|
runCatching {
|
||||||
beforeHookCallback?.invoke(param)
|
beforeHookCallback?.invoke(param)
|
||||||
if (beforeHookCallback != null)
|
if (beforeHookCallback != null) onHookLogMsg(msg = "Before Hook Member [${this@hook}] done [$tag]")
|
||||||
onHookLogMsg(msg = "Before Hook Member [${member ?: "All of \"$allMethodsName\""}] done [$tag]")
|
|
||||||
HookParam.invoke()
|
HookParam.invoke()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
onConductFailureCallback?.invoke(param, it)
|
onConductFailureCallback?.invoke(param, it)
|
||||||
@@ -528,8 +548,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
afterHookParam.assign(wrapper).also { param ->
|
afterHookParam.assign(wrapper).also { param ->
|
||||||
runCatching {
|
runCatching {
|
||||||
afterHookCallback?.invoke(param)
|
afterHookCallback?.invoke(param)
|
||||||
if (afterHookCallback != null)
|
if (afterHookCallback != null) onHookLogMsg(msg = "After Hook Member [${this@hook}] done [$tag]")
|
||||||
onHookLogMsg(msg = "After Hook Member [${member ?: "All of \"$allMethodsName\""}] done [$tag]")
|
|
||||||
HookParam.invoke()
|
HookParam.invoke()
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
onConductFailureCallback?.invoke(param, it)
|
onConductFailureCallback?.invoke(param, it)
|
||||||
@@ -539,74 +558,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hookMemberMode == HookMemberMode.HOOK_CONVENTIONAL)
|
return YukiHookHelper.hookMethod(hookMethod = this, if (isReplaceHookMode) replaceMent else beforeAfterHook)
|
||||||
if (member != null)
|
|
||||||
member.also { member ->
|
|
||||||
runCatching {
|
|
||||||
(if (isReplaceHookMode) YukiHookHelper.hookMethod(member, replaceMent)
|
|
||||||
else YukiHookHelper.hookMethod(member, beforeAfterHook)).also {
|
|
||||||
when {
|
|
||||||
it.first?.member == null -> error("Hook Member [$member] failed")
|
|
||||||
it.second -> onAlreadyHookedCallback?.invoke(it.first?.member!!)
|
|
||||||
else -> {
|
|
||||||
memberUnhook = it.first
|
|
||||||
onHookedCallback?.invoke(it.first?.member!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.onFailure {
|
|
||||||
onHookingFailureCallback?.invoke(it)
|
|
||||||
onAllFailureCallback?.invoke(it)
|
|
||||||
if (isNotIgnoredHookingFailure) onHookFailureMsg(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else Throwable("Finding Error isSetUpMember [$isHookMemberSetup] [$tag]").also {
|
|
||||||
onNoSuchMemberFailureCallback?.invoke(it)
|
|
||||||
onHookingFailureCallback?.invoke(it)
|
|
||||||
onAllFailureCallback?.invoke(it)
|
|
||||||
if (isNotIgnoredNoSuchMemberFailure) yLoggerE(
|
|
||||||
msg = "$hostTagName " + (if (isHookMemberSetup)
|
|
||||||
"Hooked Member with a finding error by $hookClass [$tag]"
|
|
||||||
else "Hooked Member cannot be non-null by $hookClass [$tag]"),
|
|
||||||
e = findingThrowable ?: it
|
|
||||||
)
|
|
||||||
}
|
|
||||||
else runCatching {
|
|
||||||
when (hookMemberMode) {
|
|
||||||
HookMemberMode.HOOK_ALL_METHODS ->
|
|
||||||
(if (isReplaceHookMode) YukiHookHelper.hookAllMethods(hookClass.instance, allMethodsName, replaceMent)
|
|
||||||
else YukiHookHelper.hookAllMethods(hookClass.instance, allMethodsName, beforeAfterHook)).also {
|
|
||||||
when {
|
|
||||||
it.first.isEmpty() -> throw NoSuchMethodError("No Method name \"$allMethodsName\" matched")
|
|
||||||
it.second -> it.first.forEach { e -> if (e.member != null) onAlreadyHookedCallback?.invoke(e.member!!) }
|
|
||||||
else -> {
|
|
||||||
memberUnhook = it.first.first()
|
|
||||||
it.first.forEach { e -> if (e.member != null) onHookedCallback?.invoke(e.member!!) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
HookMemberMode.HOOK_ALL_CONSTRUCTORS ->
|
|
||||||
(if (isReplaceHookMode) YukiHookHelper.hookAllConstructors(hookClass.instance, replaceMent)
|
|
||||||
else YukiHookHelper.hookAllConstructors(hookClass.instance, beforeAfterHook)).also {
|
|
||||||
when {
|
|
||||||
it.first.isEmpty() -> throw NoSuchMethodError("No Constructor matched")
|
|
||||||
it.second -> it.first.forEach { e -> if (e.member != null) onAlreadyHookedCallback?.invoke(e.member!!) }
|
|
||||||
else -> {
|
|
||||||
memberUnhook = it.first.first()
|
|
||||||
it.first.forEach { e -> if (e.member != null) onHookedCallback?.invoke(e.member!!) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> error("Hooked got a no error possible")
|
|
||||||
}
|
|
||||||
}.onFailure {
|
|
||||||
val isMemberNotFound = it.message?.lowercase()?.contains(other = "nosuch") == true ||
|
|
||||||
it is NoSuchMethodError || it is NoSuchFieldError
|
|
||||||
if (isMemberNotFound) onNoSuchMemberFailureCallback?.invoke(it)
|
|
||||||
onAllFailureCallback?.invoke(it)
|
|
||||||
if ((isNotIgnoredHookingFailure && isMemberNotFound.not()) || (isNotIgnoredNoSuchMemberFailure && isMemberNotFound))
|
|
||||||
yLoggerE(msg = "$hostTagName Hooked All Members with an error in $hookClass [$tag]", e = it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -620,9 +572,12 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
/**
|
/**
|
||||||
* Hook 失败但未设置 [onAllFailureCallback] 将默认输出失败信息
|
* Hook 失败但未设置 [onAllFailureCallback] 将默认输出失败信息
|
||||||
* @param throwable 异常信息
|
* @param throwable 异常信息
|
||||||
|
* @param member 异常 [Member] - 可空
|
||||||
*/
|
*/
|
||||||
private fun onHookFailureMsg(throwable: Throwable) =
|
private fun onHookFailureMsg(throwable: Throwable, member: Member? = null) = yLoggerE(
|
||||||
yLoggerE(msg = "$hostTagName Try to hook ${hookClass.instance ?: hookClass.name}[$member] got an Exception [$tag]", e = throwable)
|
msg = "$hostTagName Try to hook [${hookClass.instance ?: hookClass.name}]${member?.let { "[$it]" } ?: ""} got an Exception [$tag]",
|
||||||
|
e = throwable
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否没有设置 Hook 过程中的任何异常拦截
|
* 判断是否没有设置 Hook 过程中的任何异常拦截
|
||||||
@@ -631,7 +586,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
private val isNotIgnoredHookingFailure get() = onHookingFailureCallback == null && onAllFailureCallback == null
|
private val isNotIgnoredHookingFailure get() = onHookingFailureCallback == null && onAllFailureCallback == null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否没有设置 Hook 过程中 [member] 找不到的任何异常拦截
|
* 判断是否没有设置 Hook 过程中 [members] 找不到的任何异常拦截
|
||||||
* @return [Boolean] 没有设置任何异常拦截
|
* @return [Boolean] 没有设置任何异常拦截
|
||||||
*/
|
*/
|
||||||
internal val isNotIgnoredNoSuchMemberFailure get() = onNoSuchMemberFailureCallback == null && isNotIgnoredHookingFailure
|
internal val isNotIgnoredNoSuchMemberFailure get() = onNoSuchMemberFailureCallback == null && isNotIgnoredHookingFailure
|
||||||
@@ -642,7 +597,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
*/
|
*/
|
||||||
internal val hostTagName get() = if (packageParam.appUserId != 0) "[$packageName][${packageParam.appUserId}]" else "[$packageName]"
|
internal val hostTagName get() = if (packageParam.appUserId != 0) "[$packageName][${packageParam.appUserId}]" else "[$packageName]"
|
||||||
|
|
||||||
override fun toString() = "[tag] $tag [priority] $priority [class] $hookClass [member] $member $allMethodsName [mode] $hookMemberMode"
|
override fun toString() = "[tag] $tag [priority] $priority [class] $hookClass [members] $members"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听 Hook 结果实现类
|
* 监听 Hook 结果实现类
|
||||||
@@ -672,7 +627,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听 [member] Hook 成功的回调方法
|
* 监听 [members] Hook 成功的回调方法
|
||||||
*
|
*
|
||||||
* 在首次 Hook 成功后回调
|
* 在首次 Hook 成功后回调
|
||||||
*
|
*
|
||||||
@@ -686,9 +641,9 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听 [member] 重复 Hook 的回调方法
|
* 监听 [members] 重复 Hook 的回调方法
|
||||||
*
|
*
|
||||||
* - ❗同一个 [hookClass] 中的同一个 [member] 不会被 API 重复 Hook - 若由于各种原因重复 Hook 会回调此方法
|
* - ❗同一个 [hookClass] 中的同一个 [members] 不会被 API 重复 Hook - 若由于各种原因重复 Hook 会回调此方法
|
||||||
* @param result 回调被重复 Hook 的 [Member]
|
* @param result 回调被重复 Hook 的 [Member]
|
||||||
* @return [Result] 可继续向下监听
|
* @return [Result] 可继续向下监听
|
||||||
*/
|
*/
|
||||||
@@ -698,7 +653,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听 [member] 不存在发生错误的回调方法
|
* 监听 [members] 不存在发生错误的回调方法
|
||||||
* @param result 回调错误
|
* @param result 回调错误
|
||||||
* @return [Result] 可继续向下监听
|
* @return [Result] 可继续向下监听
|
||||||
*/
|
*/
|
||||||
@@ -708,7 +663,7 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 忽略 [member] 不存在发生的错误
|
* 忽略 [members] 不存在发生的错误
|
||||||
* @return [Result] 可继续向下监听
|
* @return [Result] 可继续向下监听
|
||||||
*/
|
*/
|
||||||
fun ignoredNoSuchMemberFailure() = onNoSuchMemberFailure {}
|
fun ignoredNoSuchMemberFailure() = onNoSuchMemberFailure {}
|
||||||
@@ -768,11 +723,15 @@ class YukiMemberHookCreater(@PublishedApi internal val packageParam: PackagePara
|
|||||||
* @param result 回调是否成功
|
* @param result 回调是否成功
|
||||||
*/
|
*/
|
||||||
fun remove(result: (Boolean) -> Unit = {}) {
|
fun remove(result: (Boolean) -> Unit = {}) {
|
||||||
memberUnhook?.remove()
|
memberUnhooks.takeIf { it.isNotEmpty() }?.apply {
|
||||||
|
forEach {
|
||||||
|
it.remove()
|
||||||
|
onHookLogMsg(msg = "Remove Hooked Member [${it.member}] done [$tag]")
|
||||||
|
}
|
||||||
runCatching { preHookMembers.remove(this@MemberHookCreater.toString()) }
|
runCatching { preHookMembers.remove(this@MemberHookCreater.toString()) }
|
||||||
if (memberUnhook != null) onHookLogMsg(msg = "Remove Hooked Member [${member ?: "All of \"$allMethodsName\""}] done [$tag]")
|
clear()
|
||||||
result(memberUnhook != null)
|
result(true)
|
||||||
memberUnhook = null
|
} ?: result(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,6 @@ import com.highcapable.yukihookapi.hook.param.wrapper.HookParamWrapper
|
|||||||
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge
|
import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge
|
||||||
import de.robv.android.xposed.XC_MethodHook
|
import de.robv.android.xposed.XC_MethodHook
|
||||||
import de.robv.android.xposed.XposedBridge
|
import de.robv.android.xposed.XposedBridge
|
||||||
import java.lang.reflect.Constructor
|
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import java.lang.reflect.Member
|
import java.lang.reflect.Member
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
@@ -58,12 +57,6 @@ internal object YukiHookedMembers {
|
|||||||
|
|
||||||
/** 已经 Hook 的 [Member] 数组 */
|
/** 已经 Hook 的 [Member] 数组 */
|
||||||
internal val hookedMembers = HashSet<YukiMemberHook.Unhook>()
|
internal val hookedMembers = HashSet<YukiMemberHook.Unhook>()
|
||||||
|
|
||||||
/** 已经 Hook 的成组 [Method] 数组 */
|
|
||||||
internal val hookedQueueMethods = HashMap<String, HashSet<YukiMemberHook.Unhook>>()
|
|
||||||
|
|
||||||
/** 已经 Hook 的成组 [Constructor] 数组 */
|
|
||||||
internal val hookedQueueConstructors = HashMap<String, HashSet<YukiMemberHook.Unhook>>()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,59 +117,6 @@ internal object YukiHookHelper {
|
|||||||
else Pair(null, false)
|
else Pair(null, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook 当前 [hookClass] 所有 [methodName] 的方法
|
|
||||||
*
|
|
||||||
* 对接 [XposedBridge.hookAllMethods]
|
|
||||||
* @param hookClass 当前 Hook 的 [Class]
|
|
||||||
* @param methodName 方法名
|
|
||||||
* @param callback 回调
|
|
||||||
* @return [Pair] - ([HashSet] 成功 Hook 的 [YukiMemberHook.Unhook] 数组,[Boolean] 是否已经 Hook)
|
|
||||||
*/
|
|
||||||
internal fun hookAllMethods(
|
|
||||||
hookClass: Class<*>?, methodName: String, callback: YukiHookCallback
|
|
||||||
): Pair<HashSet<YukiMemberHook.Unhook>, Boolean> {
|
|
||||||
var isAlreadyHook = false
|
|
||||||
val hookedMembers = HashSet<YukiMemberHook.Unhook>().also {
|
|
||||||
val allMethodsName = "$hookClass$methodName"
|
|
||||||
if (YukiHookedMembers.hookedQueueMethods.contains(allMethodsName)) {
|
|
||||||
isAlreadyHook = true
|
|
||||||
YukiHookedMembers.hookedQueueMethods[allMethodsName]?.forEach { e -> it.add(e) }
|
|
||||||
return@also
|
|
||||||
}
|
|
||||||
if (YukiHookBridge.hasXposedBridge.not()) return@also
|
|
||||||
XposedBridge.hookAllMethods(hookClass, methodName, callback.compat()).takeIf { e -> e.isNotEmpty() }
|
|
||||||
?.forEach { e -> it.add(YukiMemberHook.Unhook.wrapper(e, allMethodsName)) }
|
|
||||||
YukiHookedMembers.hookedQueueMethods[allMethodsName] = it
|
|
||||||
}
|
|
||||||
return Pair(hookedMembers, isAlreadyHook)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook 当前 [hookClass] 所有构造方法
|
|
||||||
*
|
|
||||||
* 对接 [XposedBridge.hookAllConstructors]
|
|
||||||
* @param hookClass 当前 Hook 的 [Class]
|
|
||||||
* @param callback 回调
|
|
||||||
* @return [Pair] - ([HashSet] 成功 Hook 的 [YukiMemberHook.Unhook] 数组,[Boolean] 是否已经 Hook)
|
|
||||||
*/
|
|
||||||
internal fun hookAllConstructors(hookClass: Class<*>?, callback: YukiHookCallback): Pair<HashSet<YukiMemberHook.Unhook>, Boolean> {
|
|
||||||
var isAlreadyHook = false
|
|
||||||
val hookedMembers = HashSet<YukiMemberHook.Unhook>().also {
|
|
||||||
val allConstructorsName = "$hookClass<init>"
|
|
||||||
if (YukiHookedMembers.hookedQueueConstructors.contains(allConstructorsName)) {
|
|
||||||
isAlreadyHook = true
|
|
||||||
YukiHookedMembers.hookedQueueConstructors[allConstructorsName]?.forEach { e -> it.add(e) }
|
|
||||||
return@also
|
|
||||||
}
|
|
||||||
if (YukiHookBridge.hasXposedBridge.not()) return@also
|
|
||||||
XposedBridge.hookAllConstructors(hookClass, callback.compat()).takeIf { e -> e.isNotEmpty() }
|
|
||||||
?.forEach { e -> it.add(YukiMemberHook.Unhook.wrapper(e, allConstructorsName)) }
|
|
||||||
YukiHookedMembers.hookedQueueConstructors[allConstructorsName] = it
|
|
||||||
}
|
|
||||||
return Pair(hookedMembers, isAlreadyHook)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行原始 [Member]
|
* 执行原始 [Member]
|
||||||
*
|
*
|
||||||
@@ -185,14 +125,10 @@ internal object YukiHookHelper {
|
|||||||
* @param args 参数实例
|
* @param args 参数实例
|
||||||
* @return [Any] or null
|
* @return [Any] or null
|
||||||
*/
|
*/
|
||||||
internal fun invokeOriginalMember(member: Member, instance: Any?, vararg args: Any?): Any? {
|
internal fun invokeOriginalMember(member: Member, instance: Any?, vararg args: Any?) =
|
||||||
val isHookedMember = YukiHookedMembers.hookedMembers.any { it.member.toString() == member.toString() }
|
if (YukiHookBridge.hasXposedBridge && YukiHookedMembers.hookedMembers.any { it.member.toString() == member.toString() })
|
||||||
val isQueueMethod = YukiHookedMembers.hookedQueueMethods.any { it.value.any { e -> e.member.toString() == member.toString() } }
|
|
||||||
val isQueueConstructor = YukiHookedMembers.hookedQueueConstructors.any { it.value.any { e -> e.member.toString() == member.toString() } }
|
|
||||||
return if (YukiHookBridge.hasXposedBridge && (isHookedMember || isQueueMethod || isQueueConstructor))
|
|
||||||
XposedBridge.invokeOriginalMethod(member, instance, args)
|
XposedBridge.invokeOriginalMethod(member, instance, args)
|
||||||
else null
|
else null
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 兼容对接 Hook 回调接口
|
* 兼容对接 Hook 回调接口
|
||||||
@@ -263,19 +199,17 @@ internal abstract class YukiMemberHook(override val priority: Int = YukiHookPrio
|
|||||||
/**
|
/**
|
||||||
* 已经 Hook 且可被解除 Hook 的 [Member] 实现类
|
* 已经 Hook 且可被解除 Hook 的 [Member] 实现类
|
||||||
* @param instance 对接 [XC_MethodHook.Unhook]
|
* @param instance 对接 [XC_MethodHook.Unhook]
|
||||||
* @param tag 标识多个 [Member] Hook 的标签 - 例如 [YukiHookHelper.hookAllMethods]、[YukiHookHelper.hookAllConstructors]
|
|
||||||
*/
|
*/
|
||||||
internal class Unhook private constructor(private val instance: XC_MethodHook.Unhook, private val tag: String) {
|
internal class Unhook private constructor(private val instance: XC_MethodHook.Unhook) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从 [XC_MethodHook.Unhook] 创建 [Unhook] 实例
|
* 从 [XC_MethodHook.Unhook] 创建 [Unhook] 实例
|
||||||
* @param instance [XC_MethodHook.Unhook] 实例
|
* @param instance [XC_MethodHook.Unhook] 实例
|
||||||
* @param tag 标识多个 [Member] Hook 的标签 - 默认空
|
|
||||||
* @return [Unhook]
|
* @return [Unhook]
|
||||||
*/
|
*/
|
||||||
internal fun wrapper(instance: XC_MethodHook.Unhook, tag: String = "") = Unhook(instance, tag)
|
internal fun wrapper(instance: XC_MethodHook.Unhook) = Unhook(instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -284,37 +218,11 @@ internal abstract class YukiMemberHook(override val priority: Int = YukiHookPrio
|
|||||||
*/
|
*/
|
||||||
internal val member: Member? get() = instance.hookedMethod
|
internal val member: Member? get() = instance.hookedMethod
|
||||||
|
|
||||||
/**
|
/** 解除 [instance] 的 Hook 并从 [YukiHookedMembers.hookedMembers] 缓存数组中移除 */
|
||||||
* 解除 Hook 并从
|
|
||||||
* [YukiHookedMembers.hookedMembers]、
|
|
||||||
* [YukiHookedMembers.hookedQueueMethods]、
|
|
||||||
* [YukiHookedMembers.hookedQueueConstructors]
|
|
||||||
* 缓存数组中移除
|
|
||||||
*/
|
|
||||||
internal fun remove() {
|
internal fun remove() {
|
||||||
if (tag.isNotBlank()) runCatching {
|
|
||||||
when {
|
|
||||||
YukiHookedMembers.hookedQueueMethods.contains(tag) -> {
|
|
||||||
YukiHookedMembers.hookedQueueMethods[tag]?.takeIf { it.isNotEmpty() }?.forEach { it.unhook(isNeedRemove = false) }
|
|
||||||
YukiHookedMembers.hookedQueueMethods.remove(tag)
|
|
||||||
}
|
|
||||||
YukiHookedMembers.hookedQueueConstructors.contains(tag) -> {
|
|
||||||
YukiHookedMembers.hookedQueueConstructors[tag]?.takeIf { it.isNotEmpty() }?.forEach { it.unhook(isNeedRemove = false) }
|
|
||||||
YukiHookedMembers.hookedQueueConstructors.remove(tag)
|
|
||||||
}
|
|
||||||
else -> unhook()
|
|
||||||
}
|
|
||||||
} else unhook()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 解除 [instance] 的 Hook
|
|
||||||
* @param isNeedRemove 是否需要从 [YukiHookedMembers.hookedMembers] 中移除
|
|
||||||
*/
|
|
||||||
private fun unhook(isNeedRemove: Boolean = true) {
|
|
||||||
if (YukiHookBridge.hasXposedBridge.not()) return
|
if (YukiHookBridge.hasXposedBridge.not()) return
|
||||||
instance.unhook()
|
instance.unhook()
|
||||||
if (isNeedRemove) runCatching { YukiHookedMembers.hookedMembers.remove(this) }
|
runCatching { YukiHookedMembers.hookedMembers.remove(this) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user