mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-06 10:45:47 +08:00
Modify almost code, update version to 1.0.2
This commit is contained in:
@@ -70,7 +70,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
|
|||||||
* @return [Class]
|
* @return [Class]
|
||||||
* @throws IllegalStateException 如果当前 [Class] 未被正确装载
|
* @throws IllegalStateException 如果当前 [Class] 未被正确装载
|
||||||
*/
|
*/
|
||||||
val thisClass
|
val instanceClass
|
||||||
get() = hookClass.instance ?: error("Cannot get hook class \"${hookClass.name}\" cause ${hookClass.throwable?.message}")
|
get() = hookClass.instance ?: error("Cannot get hook class \"${hookClass.name}\" cause ${hookClass.throwable?.message}")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -138,7 +138,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
|
|||||||
/**
|
/**
|
||||||
* 手动指定要 Hook 的方法、构造类
|
* 手动指定要 Hook 的方法、构造类
|
||||||
*
|
*
|
||||||
* 你可以调用 [thisClass] 来手动查询要 Hook 的方法
|
* 你可以调用 [instanceClass] 来手动查询要 Hook 的方法
|
||||||
*/
|
*/
|
||||||
var member: Member? = null
|
var member: Member? = null
|
||||||
|
|
||||||
@@ -180,11 +180,11 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
|
|||||||
if (hookClass.instance == null) return MethodFinder(hookInstance = this).failure(hookClass.throwable)
|
if (hookClass.instance == null) return MethodFinder(hookInstance = this).failure(hookClass.throwable)
|
||||||
hookAllMembers = HookAllMembers.HOOK_NONE
|
hookAllMembers = HookAllMembers.HOOK_NONE
|
||||||
isHookMemberSetup = true
|
isHookMemberSetup = true
|
||||||
return MethodFinder(hookInstance = this, hookClass.instance).apply(initiate).build()
|
return MethodFinder(hookInstance = this, hookClass.instance).apply(initiate).build(isBind = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找 [hookClass] 需要 Hook 的构造类
|
* 查找 [hookClass] 需要 Hook 的构造方法
|
||||||
*
|
*
|
||||||
* 你只能使用一次 [method] 或 [constructor] 方法 - 否则结果会被替换
|
* 你只能使用一次 [method] 或 [constructor] 方法 - 否则结果会被替换
|
||||||
* @param initiate 方法体
|
* @param initiate 方法体
|
||||||
@@ -194,17 +194,35 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
|
|||||||
if (hookClass.instance == null) return ConstructorFinder(hookInstance = this).failure(hookClass.throwable)
|
if (hookClass.instance == null) return ConstructorFinder(hookInstance = this).failure(hookClass.throwable)
|
||||||
hookAllMembers = HookAllMembers.HOOK_NONE
|
hookAllMembers = HookAllMembers.HOOK_NONE
|
||||||
isHookMemberSetup = true
|
isHookMemberSetup = true
|
||||||
return ConstructorFinder(hookInstance = this, hookClass.instance).apply(initiate).build()
|
return ConstructorFinder(hookInstance = this, hookClass.instance).apply(initiate).build(isBind = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找 [Field]
|
* 使用当前 [hookClass] 查找并得到 [Field]
|
||||||
* @param initiate 方法体
|
* @param initiate 方法体
|
||||||
* @return [FieldFinder.Result]
|
* @return [FieldFinder.Result]
|
||||||
*/
|
*/
|
||||||
fun field(initiate: FieldFinder.() -> Unit) =
|
fun HookParam.field(initiate: FieldFinder.() -> Unit) =
|
||||||
if (hookClass.instance == null) FieldFinder(hookInstance = this).failure(hookClass.throwable)
|
if (hookClass.instance == null) FieldFinder(hookInstance = this@MemberHookCreater).failure(hookClass.throwable)
|
||||||
else FieldFinder(hookInstance = this, hookClass.instance).apply(initiate).build()
|
else FieldFinder(hookInstance = this@MemberHookCreater, hookClass.instance).apply(initiate).build()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用当前 [hookClass] 查找并得到方法
|
||||||
|
* @param initiate 方法体
|
||||||
|
* @return [MethodFinder.Result]
|
||||||
|
*/
|
||||||
|
fun HookParam.method(initiate: MethodFinder.() -> Unit) =
|
||||||
|
if (hookClass.instance == null) MethodFinder(hookInstance = this@MemberHookCreater).failure(hookClass.throwable)
|
||||||
|
else MethodFinder(hookInstance = this@MemberHookCreater, hookClass.instance).apply(initiate).build()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用当前 [hookClass] 查找并得到构造方法
|
||||||
|
* @param initiate 方法体
|
||||||
|
* @return [ConstructorFinder.Result]
|
||||||
|
*/
|
||||||
|
fun HookParam.constructor(initiate: ConstructorFinder.() -> Unit) =
|
||||||
|
if (hookClass.instance == null) ConstructorFinder(hookInstance = this@MemberHookCreater).failure(hookClass.throwable)
|
||||||
|
else ConstructorFinder(hookInstance = this@MemberHookCreater, hookClass.instance).apply(initiate).build()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在方法执行完成前 Hook
|
* 在方法执行完成前 Hook
|
||||||
@@ -418,7 +436,7 @@ class YukiHookCreater(private val packageParam: PackageParam, private val hookCl
|
|||||||
* Hook 过程中开启了 [YukiHookAPI.Configs.isDebug] 输出调试信息
|
* Hook 过程中开启了 [YukiHookAPI.Configs.isDebug] 输出调试信息
|
||||||
* @param msg 调试日志内容
|
* @param msg 调试日志内容
|
||||||
*/
|
*/
|
||||||
internal fun onHookLogMsg(msg: String) {
|
private fun onHookLogMsg(msg: String) {
|
||||||
if (YukiHookAPI.Configs.isDebug) loggerI(msg = msg)
|
if (YukiHookAPI.Configs.isDebug) loggerI(msg = msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,14 +25,13 @@
|
|||||||
*
|
*
|
||||||
* This file is Created by fankes on 2022/2/4.
|
* This file is Created by fankes on 2022/2/4.
|
||||||
*/
|
*/
|
||||||
@file:Suppress("unused", "EXPERIMENTAL_API_USAGE", "MemberVisibilityCanBePrivate")
|
@file:Suppress("unused", "EXPERIMENTAL_API_USAGE", "MemberVisibilityCanBePrivate", "UNCHECKED_CAST")
|
||||||
|
|
||||||
package com.highcapable.yukihookapi.hook.core.finder
|
package com.highcapable.yukihookapi.hook.core.finder
|
||||||
|
|
||||||
import android.os.SystemClock
|
|
||||||
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
||||||
import com.highcapable.yukihookapi.hook.core.YukiHookCreater
|
import com.highcapable.yukihookapi.hook.core.YukiHookCreater
|
||||||
import com.highcapable.yukihookapi.hook.log.loggerE
|
import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder
|
||||||
import com.highcapable.yukihookapi.hook.log.loggerW
|
import com.highcapable.yukihookapi.hook.log.loggerW
|
||||||
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
||||||
import com.highcapable.yukihookapi.hook.utils.runBlocking
|
import com.highcapable.yukihookapi.hook.utils.runBlocking
|
||||||
@@ -42,17 +41,23 @@ import java.lang.reflect.Constructor
|
|||||||
* [Constructor] 查找类
|
* [Constructor] 查找类
|
||||||
*
|
*
|
||||||
* 可通过指定类型查找指定构造方法
|
* 可通过指定类型查找指定构造方法
|
||||||
* @param hookInstance 当前 Hook 实例
|
* @param hookInstance 当前 Hook 实例 - 填写后将自动设置 [YukiHookCreater.MemberHookCreater.member]
|
||||||
* @param hookClass 当前被 Hook 的 [Class]
|
* @param classSet 当前需要查找的 [Class] 实例
|
||||||
*/
|
*/
|
||||||
class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>? = null) {
|
class ConstructorFinder(
|
||||||
|
override val hookInstance: YukiHookCreater.MemberHookCreater? = null,
|
||||||
|
override val classSet: Class<*>? = null
|
||||||
|
) : BaseFinder(tag = "Constructor", hookInstance, classSet) {
|
||||||
|
|
||||||
|
/** 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater] */
|
||||||
|
private var isBindToHooker = false
|
||||||
|
|
||||||
|
/** 当前重查找结果回调 */
|
||||||
|
private var remedyPlansCallback: (() -> Unit)? = null
|
||||||
|
|
||||||
/** [Constructor] 参数数组 */
|
/** [Constructor] 参数数组 */
|
||||||
private var params: Array<out Class<*>>? = null
|
private var params: Array<out Class<*>>? = null
|
||||||
|
|
||||||
/** 是否使用了 [RemedyPlan] */
|
|
||||||
private var isUsingRemedyPlan = false
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Constructor] 参数
|
* [Constructor] 参数
|
||||||
*
|
*
|
||||||
@@ -73,8 +78,18 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
|||||||
*/
|
*/
|
||||||
private val result
|
private val result
|
||||||
get() = if (params != null)
|
get() = if (params != null)
|
||||||
ReflectionUtils.findConstructorExact(hookClass, *params!!)
|
ReflectionUtils.findConstructorExact(classSet, *params!!)
|
||||||
else ReflectionUtils.findConstructorExact(hookClass)
|
else ReflectionUtils.findConstructorExact(classSet)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置实例
|
||||||
|
* @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater]
|
||||||
|
* @param constructor 当前找到的 [Constructor]
|
||||||
|
*/
|
||||||
|
private fun setInstance(isBind: Boolean, constructor: Constructor<*>) {
|
||||||
|
memberInstance = constructor
|
||||||
|
if (isBind) hookInstance?.member = constructor
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 得到构造方法结果
|
* 得到构造方法结果
|
||||||
@@ -83,11 +98,12 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
|||||||
* @return [Result]
|
* @return [Result]
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun build() = try {
|
override fun build(isBind: Boolean) = try {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
hookInstance.member = result
|
isBindToHooker = isBind
|
||||||
|
setInstance(isBind, result)
|
||||||
}.result {
|
}.result {
|
||||||
hookInstance.onHookLogMsg(msg = "Find Constructor [${hookInstance.member}] takes ${it}ms [${hookInstance.tag}]")
|
onHookLogMsg(msg = "Find Constructor [${memberInstance}] takes ${it}ms [${hookTag}]")
|
||||||
}
|
}
|
||||||
Result()
|
Result()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
@@ -103,22 +119,7 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
|||||||
* @return [Result]
|
* @return [Result]
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
|
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
|
||||||
|
|
||||||
/**
|
|
||||||
* 发生错误时输出日志
|
|
||||||
* @param msg 消息日志
|
|
||||||
* @param throwable 错误
|
|
||||||
* @param isAlwaysPrint 忽略条件每次都打印错误
|
|
||||||
*/
|
|
||||||
private fun onFailureMsg(msg: String = "", throwable: Throwable? = null, isAlwaysPrint: Boolean = false) {
|
|
||||||
fun print() = loggerE(msg = "NoSuchConstructor happend in [$hookClass] $msg [${hookInstance.tag}]", e = throwable)
|
|
||||||
if (isAlwaysPrint) print()
|
|
||||||
else Thread {
|
|
||||||
SystemClock.sleep(10)
|
|
||||||
if (hookInstance.isNotIgnoredHookingFailure && !isUsingRemedyPlan) print()
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Constructor] 重查找实现类
|
* [Constructor] 重查找实现类
|
||||||
@@ -139,7 +140,7 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
|||||||
* @param initiate 方法体
|
* @param initiate 方法体
|
||||||
*/
|
*/
|
||||||
fun constructor(initiate: ConstructorFinder.() -> Unit) =
|
fun constructor(initiate: ConstructorFinder.() -> Unit) =
|
||||||
Result().apply { remedyPlans.add(Pair(ConstructorFinder(hookInstance, hookClass).apply(initiate), this)) }
|
Result().apply { remedyPlans.add(Pair(ConstructorFinder(hookInstance, classSet).apply(initiate), this)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始重查找
|
* 开始重查找
|
||||||
@@ -154,13 +155,14 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
|||||||
remedyPlans.forEachIndexed { p, it ->
|
remedyPlans.forEachIndexed { p, it ->
|
||||||
runCatching {
|
runCatching {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
hookInstance.member = it.first.result
|
setInstance(isBindToHooker, it.first.result)
|
||||||
}.result {
|
}.result {
|
||||||
hookInstance.onHookLogMsg(msg = "Find Constructor [${hookInstance.member}] takes ${it}ms [${hookInstance.tag}]")
|
onHookLogMsg(msg = "Find Constructor [${memberInstance}] takes ${it}ms [${hookTag}]")
|
||||||
}
|
}
|
||||||
isFindSuccess = true
|
isFindSuccess = true
|
||||||
it.second.onFindCallback?.invoke(hookInstance.member as Constructor<*>)
|
it.second.onFindCallback?.invoke(memberInstance as Constructor<*>)
|
||||||
hookInstance.onHookLogMsg(msg = "Constructor [${hookInstance.member}] trying ${p + 1} times success by RemedyPlan [${hookInstance.tag}]")
|
remedyPlansCallback?.invoke()
|
||||||
|
onHookLogMsg(msg = "Constructor [${memberInstance}] trying ${p + 1} times success by RemedyPlan [${hookTag}]")
|
||||||
return@run
|
return@run
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
lastError = it
|
lastError = it
|
||||||
@@ -175,7 +177,7 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
|||||||
)
|
)
|
||||||
remedyPlans.clear()
|
remedyPlans.clear()
|
||||||
}
|
}
|
||||||
} else loggerW(msg = "RemedyPlan is empty,forgot it? [${hookInstance.tag}]")
|
} else loggerW(msg = "RemedyPlan is empty,forgot it? [${hookTag}]")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -212,6 +214,27 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
|||||||
*/
|
*/
|
||||||
fun result(initiate: Result.() -> Unit) = apply(initiate)
|
fun result(initiate: Result.() -> Unit) = apply(initiate)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得 [Constructor] 实例处理类
|
||||||
|
*
|
||||||
|
* - ❗在 [memberInstance] 结果为空时使用此方法将无法获得对象
|
||||||
|
* - ❗若你设置了 [remedys] 请使用 [wait] 回调结果方法
|
||||||
|
* @return [Instance]
|
||||||
|
*/
|
||||||
|
fun get() = Instance()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得 [Constructor] 实例处理类
|
||||||
|
*
|
||||||
|
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
|
||||||
|
* - ❗若你没有设置 [remedys] 此方法将不会被回调
|
||||||
|
* @param initiate 回调 [Instance]
|
||||||
|
*/
|
||||||
|
fun wait(initiate: Instance.() -> Unit) {
|
||||||
|
if (memberInstance != null) initiate(get())
|
||||||
|
else remedyPlansCallback = { initiate(get()) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建构造方法重查找功能
|
* 创建构造方法重查找功能
|
||||||
*
|
*
|
||||||
@@ -238,5 +261,39 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
|||||||
if (isNoSuch) initiate(e ?: Throwable())
|
if (isNoSuch) initiate(e ?: Throwable())
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Constructor] 实例处理类
|
||||||
|
*
|
||||||
|
* 调用与创建目标实例类对象
|
||||||
|
*/
|
||||||
|
inner class Instance {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行构造方法创建目标实例
|
||||||
|
* @param param 构造方法参数
|
||||||
|
* @return [Any] or null
|
||||||
|
*/
|
||||||
|
private fun baseCall(vararg param: Any?) =
|
||||||
|
if (param.isNotEmpty())
|
||||||
|
(memberInstance as? Constructor<*>?)?.newInstance(*param)
|
||||||
|
else (memberInstance as? Constructor<*>?)?.newInstance()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行构造方法创建目标实例 - 不指定目标实例类型
|
||||||
|
* @param param 构造方法参数
|
||||||
|
* @return [Any] or null
|
||||||
|
*/
|
||||||
|
fun call(vararg param: Any?) = baseCall(*param)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行构造方法创建目标实例 - 指定 [T] 目标实例类型
|
||||||
|
* @param param 构造方法参数
|
||||||
|
* @return [T] or null
|
||||||
|
*/
|
||||||
|
fun <T> newInstance(vararg param: Any?) = baseCall(*param) as? T?
|
||||||
|
|
||||||
|
override fun toString() = "[${(memberInstance as? Constructor<*>?)?.name ?: "<empty>"}]"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -32,6 +32,7 @@ package com.highcapable.yukihookapi.hook.core.finder
|
|||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
||||||
import com.highcapable.yukihookapi.hook.core.YukiHookCreater
|
import com.highcapable.yukihookapi.hook.core.YukiHookCreater
|
||||||
|
import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder
|
||||||
import com.highcapable.yukihookapi.hook.log.loggerE
|
import com.highcapable.yukihookapi.hook.log.loggerE
|
||||||
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
||||||
import com.highcapable.yukihookapi.hook.utils.runBlocking
|
import com.highcapable.yukihookapi.hook.utils.runBlocking
|
||||||
@@ -42,19 +43,12 @@ import java.lang.reflect.Field
|
|||||||
*
|
*
|
||||||
* 可通过执行类型查找指定变量
|
* 可通过执行类型查找指定变量
|
||||||
* @param hookInstance 当前 Hook 实例
|
* @param hookInstance 当前 Hook 实例
|
||||||
* @param hookClass 当前被 Hook 的 [Class]
|
* @param classSet 当前需要查找的 [Class] 实例
|
||||||
*/
|
*/
|
||||||
class FieldFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>? = null) {
|
class FieldFinder(
|
||||||
|
override val hookInstance: YukiHookCreater.MemberHookCreater? = null,
|
||||||
/** 当前找到的 [Field] */
|
override val classSet: Class<*>? = null
|
||||||
private var fieldInstance: Field? = null
|
) : BaseFinder(tag = "Field", hookInstance, classSet) {
|
||||||
|
|
||||||
/**
|
|
||||||
* [Field] 所在的 [Class]
|
|
||||||
*
|
|
||||||
* 不填默认为当前的 [hookClass]
|
|
||||||
*/
|
|
||||||
var classSet = hookClass
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Field] 名称
|
* [Field] 名称
|
||||||
@@ -74,30 +68,30 @@ class FieldFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, p
|
|||||||
* 得到变量处理结果
|
* 得到变量处理结果
|
||||||
*
|
*
|
||||||
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
|
* @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater]
|
||||||
* @return [Result]
|
* @return [Result]
|
||||||
* @throws IllegalStateException 如果 [name] 没有被设置
|
* @throws IllegalStateException 如果 [name] 没有被设置
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun build() = when {
|
override fun build(isBind: Boolean) = when {
|
||||||
name.isBlank() -> {
|
name.isBlank() -> {
|
||||||
loggerE(msg = "Field name cannot be empty in Class [$classSet] [${hookInstance.tag}]")
|
loggerE(msg = "Field name cannot be empty in Class [$classSet] [${hookTag}]")
|
||||||
Result(isNoSuch = true)
|
Result(isNoSuch = true)
|
||||||
}
|
}
|
||||||
else -> try {
|
else -> try {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
fieldInstance =
|
memberInstance =
|
||||||
if (type != null)
|
if (type != null)
|
||||||
ReflectionUtils.findFieldIfExists(classSet, type?.name, name)
|
ReflectionUtils.findFieldIfExists(classSet, type?.name, name)
|
||||||
else classSet?.getDeclaredField(name)?.apply { isAccessible = true }
|
else classSet?.getDeclaredField(name)?.apply { isAccessible = true }
|
||||||
}.result {
|
}.result {
|
||||||
hookInstance.onHookLogMsg(msg = "Find Field [${fieldInstance}] takes ${it}ms [${hookInstance.tag}]")
|
onHookLogMsg(msg = "Find Field [${memberInstance}] takes ${it}ms [${hookTag}]")
|
||||||
}
|
}
|
||||||
Result()
|
Result()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
Thread {
|
Thread {
|
||||||
SystemClock.sleep(10)
|
SystemClock.sleep(10)
|
||||||
if (hookInstance.isNotIgnoredHookingFailure)
|
if (isNotIgnoredHookingFailure) loggerE(msg = "NoSuchField happend in [$classSet] [${hookTag}]", e = e)
|
||||||
loggerE(msg = "NoSuchField happend in [$classSet] [${hookInstance.tag}]", e = e)
|
|
||||||
}.start()
|
}.start()
|
||||||
Result(isNoSuch = true, e)
|
Result(isNoSuch = true, e)
|
||||||
}
|
}
|
||||||
@@ -111,12 +105,11 @@ class FieldFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, p
|
|||||||
* @return [Result]
|
* @return [Result]
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
|
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Field] 查找结果实现类
|
* [Field] 查找结果实现类
|
||||||
*
|
*
|
||||||
* 可在这里处理找到的 [fieldInstance]
|
|
||||||
* @param isNoSuch 是否没有找到变量 - 默认否
|
* @param isNoSuch 是否没有找到变量 - 默认否
|
||||||
* @param e 错误信息
|
* @param e 错误信息
|
||||||
*/
|
*/
|
||||||
@@ -147,7 +140,7 @@ class FieldFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, p
|
|||||||
* 得到变量本身
|
* 得到变量本身
|
||||||
* @return [Field] or null
|
* @return [Field] or null
|
||||||
*/
|
*/
|
||||||
fun give() = fieldInstance
|
fun give() = memberInstance as? Field?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听找不到变量时
|
* 监听找不到变量时
|
||||||
@@ -189,7 +182,8 @@ class FieldFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, p
|
|||||||
/** 设置变量实例为 null */
|
/** 设置变量实例为 null */
|
||||||
fun setNull() = set(null)
|
fun setNull() = set(null)
|
||||||
|
|
||||||
override fun toString() = "[${self?.javaClass?.name ?: ""}] in [${instance?.javaClass?.name ?: ""}] value \"$self\""
|
override fun toString() =
|
||||||
|
"[${self?.javaClass?.name ?: "<empty>"}] in [${instance?.javaClass?.name ?: "<empty>"}] value \"$self\""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -25,13 +25,13 @@
|
|||||||
*
|
*
|
||||||
* This file is Created by fankes on 2022/2/4.
|
* This file is Created by fankes on 2022/2/4.
|
||||||
*/
|
*/
|
||||||
@file:Suppress("unused", "MemberVisibilityCanBePrivate", "EXPERIMENTAL_API_USAGE")
|
@file:Suppress("unused", "MemberVisibilityCanBePrivate", "EXPERIMENTAL_API_USAGE", "UNCHECKED_CAST")
|
||||||
|
|
||||||
package com.highcapable.yukihookapi.hook.core.finder
|
package com.highcapable.yukihookapi.hook.core.finder
|
||||||
|
|
||||||
import android.os.SystemClock
|
|
||||||
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
||||||
import com.highcapable.yukihookapi.hook.core.YukiHookCreater
|
import com.highcapable.yukihookapi.hook.core.YukiHookCreater
|
||||||
|
import com.highcapable.yukihookapi.hook.core.finder.base.BaseFinder
|
||||||
import com.highcapable.yukihookapi.hook.log.loggerE
|
import com.highcapable.yukihookapi.hook.log.loggerE
|
||||||
import com.highcapable.yukihookapi.hook.log.loggerW
|
import com.highcapable.yukihookapi.hook.log.loggerW
|
||||||
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
||||||
@@ -42,17 +42,23 @@ import java.lang.reflect.Method
|
|||||||
* [Method] 查找类
|
* [Method] 查找类
|
||||||
*
|
*
|
||||||
* 可通过指定类型查找指定方法
|
* 可通过指定类型查找指定方法
|
||||||
* @param hookInstance 当前 Hook 实例
|
* @param hookInstance 当前 Hook 实例 - 填写后将自动设置 [YukiHookCreater.MemberHookCreater.member]
|
||||||
* @param hookClass 当前 Hook 的 Class
|
* @param classSet 当前需要查找的 [Class] 实例
|
||||||
*/
|
*/
|
||||||
class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>? = null) {
|
class MethodFinder(
|
||||||
|
override val hookInstance: YukiHookCreater.MemberHookCreater? = null,
|
||||||
|
override val classSet: Class<*>? = null
|
||||||
|
) : BaseFinder(tag = "Method", hookInstance, classSet) {
|
||||||
|
|
||||||
|
/** 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater] */
|
||||||
|
private var isBindToHooker = false
|
||||||
|
|
||||||
|
/** 当前重查找结果回调 */
|
||||||
|
private var remedyPlansCallback: (() -> Unit)? = null
|
||||||
|
|
||||||
/** [Method] 参数数组 */
|
/** [Method] 参数数组 */
|
||||||
private var params: Array<out Class<*>>? = null
|
private var params: Array<out Class<*>>? = null
|
||||||
|
|
||||||
/** 是否使用了 [RemedyPlan] */
|
|
||||||
private var isUsingRemedyPlan = false
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Method] 名称
|
* [Method] 名称
|
||||||
*
|
*
|
||||||
@@ -88,29 +94,44 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
|||||||
*/
|
*/
|
||||||
private val result
|
private val result
|
||||||
get() = if (params != null)
|
get() = if (params != null)
|
||||||
ReflectionUtils.findMethodBestMatch(hookClass, returnType, name, *params!!)
|
ReflectionUtils.findMethodBestMatch(classSet, returnType, name, *params!!)
|
||||||
else ReflectionUtils.findMethodNoParam(hookClass, returnType, name)
|
else ReflectionUtils.findMethodNoParam(classSet, returnType, name)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置实例
|
||||||
|
* @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater]
|
||||||
|
* @param method 当前找到的 [Method]
|
||||||
|
*/
|
||||||
|
private fun setInstance(isBind: Boolean, method: Method) {
|
||||||
|
memberInstance = method
|
||||||
|
if (isBind) hookInstance?.member = method
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 得到方法结果
|
* 得到方法结果
|
||||||
*
|
*
|
||||||
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
|
* @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater]
|
||||||
* @return [Result]
|
* @return [Result]
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun build() = if (name.isBlank()) {
|
override fun build(isBind: Boolean) = when {
|
||||||
loggerE(msg = "Method name cannot be empty in Class [$hookClass] [${hookInstance.tag}]")
|
name.isBlank() -> {
|
||||||
Result(isNoSuch = true)
|
loggerE(msg = "Method name cannot be empty in Class [$classSet] [${hookTag}]")
|
||||||
} else try {
|
Result(isNoSuch = true)
|
||||||
runBlocking {
|
}
|
||||||
hookInstance.member = result
|
else -> try {
|
||||||
}.result {
|
runBlocking {
|
||||||
hookInstance.onHookLogMsg(msg = "Find Method [${hookInstance.member}] takes ${it}ms [${hookInstance.tag}]")
|
isBindToHooker = isBind
|
||||||
|
setInstance(isBind, result)
|
||||||
|
}.result {
|
||||||
|
onHookLogMsg(msg = "Find Method [${memberInstance}] takes ${it}ms [${hookTag}]")
|
||||||
|
}
|
||||||
|
Result()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
onFailureMsg(throwable = e)
|
||||||
|
Result(isNoSuch = true, e)
|
||||||
}
|
}
|
||||||
Result()
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
onFailureMsg(throwable = e)
|
|
||||||
Result(isNoSuch = true, e)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -121,22 +142,7 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
|||||||
* @return [Result]
|
* @return [Result]
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
|
override fun failure(throwable: Throwable?) = Result(isNoSuch = true, throwable)
|
||||||
|
|
||||||
/**
|
|
||||||
* 发生错误时输出日志
|
|
||||||
* @param msg 消息日志
|
|
||||||
* @param throwable 错误
|
|
||||||
* @param isAlwaysPrint 忽略条件每次都打印错误
|
|
||||||
*/
|
|
||||||
private fun onFailureMsg(msg: String = "", throwable: Throwable? = null, isAlwaysPrint: Boolean = false) {
|
|
||||||
fun print() = loggerE(msg = "NoSuchMethod happend in [$hookClass] $msg [${hookInstance.tag}]", e = throwable)
|
|
||||||
if (isAlwaysPrint) print()
|
|
||||||
else Thread {
|
|
||||||
SystemClock.sleep(10)
|
|
||||||
if (hookInstance.isNotIgnoredHookingFailure && !isUsingRemedyPlan) print()
|
|
||||||
}.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Method] 重查找实现类
|
* [Method] 重查找实现类
|
||||||
@@ -158,7 +164,7 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
|||||||
* @return [Result] 结果
|
* @return [Result] 结果
|
||||||
*/
|
*/
|
||||||
fun method(initiate: MethodFinder.() -> Unit) =
|
fun method(initiate: MethodFinder.() -> Unit) =
|
||||||
Result().apply { remedyPlans.add(Pair(MethodFinder(hookInstance, hookClass).apply(initiate), this)) }
|
Result().apply { remedyPlans.add(Pair(MethodFinder(hookInstance, classSet).apply(initiate), this)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 开始重查找
|
* 开始重查找
|
||||||
@@ -173,13 +179,14 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
|||||||
remedyPlans.forEachIndexed { p, it ->
|
remedyPlans.forEachIndexed { p, it ->
|
||||||
runCatching {
|
runCatching {
|
||||||
runBlocking {
|
runBlocking {
|
||||||
hookInstance.member = it.first.result
|
setInstance(isBindToHooker, it.first.result)
|
||||||
}.result {
|
}.result {
|
||||||
hookInstance.onHookLogMsg(msg = "Find Method [${hookInstance.member}] takes ${it}ms [${hookInstance.tag}]")
|
onHookLogMsg(msg = "Find Method [${memberInstance}] takes ${it}ms [${hookTag}]")
|
||||||
}
|
}
|
||||||
isFindSuccess = true
|
isFindSuccess = true
|
||||||
it.second.onFindCallback?.invoke(hookInstance.member as Method)
|
it.second.onFindCallback?.invoke(memberInstance as Method)
|
||||||
hookInstance.onHookLogMsg(msg = "Method [${hookInstance.member}] trying ${p + 1} times success by RemedyPlan [${hookInstance.tag}]")
|
remedyPlansCallback?.invoke()
|
||||||
|
onHookLogMsg(msg = "Method [${memberInstance}] trying ${p + 1} times success by RemedyPlan [${hookTag}]")
|
||||||
return@run
|
return@run
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
lastError = it
|
lastError = it
|
||||||
@@ -194,7 +201,7 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
|||||||
)
|
)
|
||||||
remedyPlans.clear()
|
remedyPlans.clear()
|
||||||
}
|
}
|
||||||
} else loggerW(msg = "RemedyPlan is empty,forgot it? [${hookInstance.tag}]")
|
} else loggerW(msg = "RemedyPlan is empty,forgot it? [${hookTag}]")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -231,6 +238,29 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
|||||||
*/
|
*/
|
||||||
fun result(initiate: Result.() -> Unit) = apply(initiate)
|
fun result(initiate: Result.() -> Unit) = apply(initiate)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得 [Method] 实例处理类
|
||||||
|
*
|
||||||
|
* - ❗在 [memberInstance] 结果为空时使用此方法将无法获得对象
|
||||||
|
* - ❗若你设置了 [remedys] 请使用 [wait] 回调结果方法
|
||||||
|
* @param instance 所在实例
|
||||||
|
* @return [Instance]
|
||||||
|
*/
|
||||||
|
fun get(instance: Any? = null) = Instance(instance)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得 [Method] 实例处理类
|
||||||
|
*
|
||||||
|
* - ❗若你设置了 [remedys] 必须使用此方法才能获得结果
|
||||||
|
* - ❗若你没有设置 [remedys] 此方法将不会被回调
|
||||||
|
* @param instance 所在实例
|
||||||
|
* @param initiate 回调 [Instance]
|
||||||
|
*/
|
||||||
|
fun wait(instance: Any? = null, initiate: Instance.() -> Unit) {
|
||||||
|
if (memberInstance != null) initiate(get(instance))
|
||||||
|
else remedyPlansCallback = { initiate(get(instance)) }
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建方法重查找功能
|
* 创建方法重查找功能
|
||||||
*
|
*
|
||||||
@@ -256,8 +286,42 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
|||||||
* @return [Result] 可继续向下监听
|
* @return [Result] 可继续向下监听
|
||||||
*/
|
*/
|
||||||
fun onNoSuchMethod(initiate: (Throwable) -> Unit): Result {
|
fun onNoSuchMethod(initiate: (Throwable) -> Unit): Result {
|
||||||
if (isNoSuch) initiate(e ?: Throwable())
|
if (isNoSuch) initiate(e ?: Throwable("Initialization Error"))
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Method] 实例处理类
|
||||||
|
* @param instance 当前 [Method] 所在类的实例对象
|
||||||
|
*/
|
||||||
|
inner class Instance(private val instance: Any?) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行方法
|
||||||
|
* @param param 方法参数
|
||||||
|
* @return [Any] or null
|
||||||
|
*/
|
||||||
|
private fun baseCall(vararg param: Any?) =
|
||||||
|
if (param.isNotEmpty())
|
||||||
|
(memberInstance as? Method?)?.invoke(instance, *param)
|
||||||
|
else (memberInstance as? Method?)?.invoke(instance)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行方法 - 不指定返回值类型
|
||||||
|
* @param param 方法参数
|
||||||
|
* @return [Any] or null
|
||||||
|
*/
|
||||||
|
fun call(vararg param: Any?) = baseCall(*param)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行方法 - 指定 [T] 返回值类型
|
||||||
|
* @param param 方法参数
|
||||||
|
* @return [T] or null
|
||||||
|
*/
|
||||||
|
fun <T> invoke(vararg param: Any?) = baseCall(*param) as? T?
|
||||||
|
|
||||||
|
override fun toString() =
|
||||||
|
"[${(memberInstance as? Method?)?.name ?: "<empty>"}] in [${instance?.javaClass?.name ?: "<empty>"}]"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -0,0 +1,110 @@
|
|||||||
|
/*
|
||||||
|
* 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/18.
|
||||||
|
*/
|
||||||
|
package com.highcapable.yukihookapi.hook.core.finder.base
|
||||||
|
|
||||||
|
import android.os.SystemClock
|
||||||
|
import com.highcapable.yukihookapi.YukiHookAPI
|
||||||
|
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
||||||
|
import com.highcapable.yukihookapi.hook.core.YukiHookCreater
|
||||||
|
import com.highcapable.yukihookapi.hook.log.loggerE
|
||||||
|
import com.highcapable.yukihookapi.hook.log.loggerI
|
||||||
|
import java.lang.reflect.Member
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 这是查找类功能的基本类实现
|
||||||
|
* @param tag 当前查找类的标识
|
||||||
|
* @param hookInstance 当前 Hook 实例
|
||||||
|
* @param classSet 当前需要查找的 [Class] 实例
|
||||||
|
*/
|
||||||
|
abstract class BaseFinder(
|
||||||
|
private val tag: String,
|
||||||
|
open val hookInstance: YukiHookCreater.MemberHookCreater? = null,
|
||||||
|
open val classSet: Class<*>? = null
|
||||||
|
) {
|
||||||
|
|
||||||
|
/** 是否使用了重查找功能 */
|
||||||
|
internal var isUsingRemedyPlan = false
|
||||||
|
|
||||||
|
/** 当前找到的 [Member] */
|
||||||
|
internal var memberInstance: Member? = null
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前使用的 TAG
|
||||||
|
* @return [String] 使用的 TAG
|
||||||
|
*/
|
||||||
|
internal val hookTag get() = hookInstance?.tag ?: "FinderMode"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否没有设置 Hook 过程中的任何异常拦截
|
||||||
|
* @return [Boolean] 没有设置任何异常拦截
|
||||||
|
*/
|
||||||
|
internal val isNotIgnoredHookingFailure get() = hookInstance?.isNotIgnoredHookingFailure ?: true
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发生错误时输出日志
|
||||||
|
* @param msg 消息日志
|
||||||
|
* @param throwable 错误
|
||||||
|
* @param isAlwaysPrint 忽略条件每次都打印错误
|
||||||
|
*/
|
||||||
|
internal fun onFailureMsg(msg: String = "", throwable: Throwable? = null, isAlwaysPrint: Boolean = false) {
|
||||||
|
fun print() = loggerE(msg = "NoSuch$tag happend in [$classSet] $msg [${hookTag}]", e = throwable)
|
||||||
|
if (isAlwaysPrint) print()
|
||||||
|
else Thread {
|
||||||
|
SystemClock.sleep(10)
|
||||||
|
if (isNotIgnoredHookingFailure && !isUsingRemedyPlan) print()
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook 过程中开启了 [YukiHookAPI.Configs.isDebug] 输出调试信息
|
||||||
|
* @param msg 调试日志内容
|
||||||
|
*/
|
||||||
|
internal fun onHookLogMsg(msg: String) {
|
||||||
|
if (YukiHookAPI.Configs.isDebug) loggerI(msg = msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到结果
|
||||||
|
*
|
||||||
|
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
|
* @param isBind 是否将结果设置到目标 [YukiHookCreater.MemberHookCreater]
|
||||||
|
* @return [Any]
|
||||||
|
*/
|
||||||
|
@DoNotUseMethod
|
||||||
|
abstract fun build(isBind: Boolean = false): Any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个异常结果
|
||||||
|
*
|
||||||
|
* - ❗此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
|
* @param throwable 异常
|
||||||
|
* @return [Any]
|
||||||
|
*/
|
||||||
|
@DoNotUseMethod
|
||||||
|
abstract fun failure(throwable: Throwable?): Any
|
||||||
|
}
|
@@ -30,9 +30,10 @@
|
|||||||
package com.highcapable.yukihookapi.hook.factory
|
package com.highcapable.yukihookapi.hook.factory
|
||||||
|
|
||||||
import com.highcapable.yukihookapi.hook.bean.HookClass
|
import com.highcapable.yukihookapi.hook.bean.HookClass
|
||||||
|
import com.highcapable.yukihookapi.hook.core.finder.ConstructorFinder
|
||||||
|
import com.highcapable.yukihookapi.hook.core.finder.FieldFinder
|
||||||
|
import com.highcapable.yukihookapi.hook.core.finder.MethodFinder
|
||||||
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
||||||
import java.lang.reflect.Constructor
|
|
||||||
import java.lang.reflect.Method
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Class] 转换为 [HookClass]
|
* [Class] 转换为 [HookClass]
|
||||||
@@ -86,53 +87,46 @@ fun String.hasClass(loader: ClassLoader?) = try {
|
|||||||
*/
|
*/
|
||||||
fun Class<*>.hasMethod(name: String, vararg paramType: Class<*>, returnType: Class<*>? = null): Boolean =
|
fun Class<*>.hasMethod(name: String, vararg paramType: Class<*>, returnType: Class<*>? = null): Boolean =
|
||||||
try {
|
try {
|
||||||
method(name, *paramType, returnType = returnType)
|
if (paramType.isNotEmpty())
|
||||||
|
ReflectionUtils.findMethodBestMatch(this, returnType, name, *paramType)
|
||||||
|
else ReflectionUtils.findMethodNoParam(this, returnType, name)
|
||||||
true
|
true
|
||||||
} catch (_: Throwable) {
|
} catch (_: Throwable) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找并得到方法
|
* 查找构造方法是否存在
|
||||||
* @param name 方法名称
|
|
||||||
* @param paramType params
|
* @param paramType params
|
||||||
* @param returnType 返回类型 - 不填默认模糊
|
* @return [Boolean] 是否存在
|
||||||
* @return [Method] or null
|
|
||||||
* @throws NoSuchMethodError
|
|
||||||
*/
|
*/
|
||||||
fun Class<*>.method(name: String, vararg paramType: Class<*>, returnType: Class<*>? = null): Method? =
|
fun Class<*>.hasConstructor(vararg paramType: Class<*>): Boolean =
|
||||||
if (paramType.isNotEmpty())
|
try {
|
||||||
ReflectionUtils.findMethodBestMatch(this, returnType, name, *paramType)
|
if (paramType.isNotEmpty())
|
||||||
else ReflectionUtils.findMethodNoParam(this, returnType, name)
|
ReflectionUtils.findConstructorExact(this, *paramType)
|
||||||
|
else ReflectionUtils.findConstructorExact(this)
|
||||||
|
true
|
||||||
|
} catch (_: Throwable) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找并得到变量
|
||||||
|
* @param initiate 查找方法体
|
||||||
|
* @return [FieldFinder.Result]
|
||||||
|
*/
|
||||||
|
fun Class<*>.field(initiate: FieldFinder.() -> Unit) = FieldFinder(classSet = this).apply(initiate).build()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找并得到方法
|
||||||
|
* @param initiate 查找方法体
|
||||||
|
* @return [MethodFinder.Result]
|
||||||
|
*/
|
||||||
|
fun Class<*>.method(initiate: MethodFinder.() -> Unit) = MethodFinder(classSet = this).apply(initiate).build()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找并得到构造类
|
* 查找并得到构造类
|
||||||
* @param paramType params
|
* @param initiate 查找方法体
|
||||||
* @return [Constructor] or null
|
* @return [ConstructorFinder.Result]
|
||||||
* @throws NoSuchMethodError
|
|
||||||
*/
|
*/
|
||||||
fun Class<*>.constructor(vararg paramType: Class<*>): Constructor<out Any>? =
|
fun Class<*>.constructor(initiate: ConstructorFinder.() -> Unit) = ConstructorFinder(classSet = this).apply(initiate).build()
|
||||||
if (paramType.isNotEmpty())
|
|
||||||
ReflectionUtils.findConstructorExact(this, *paramType)
|
|
||||||
else ReflectionUtils.findConstructorExact(this)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行静态方法
|
|
||||||
* @param param 方法参数
|
|
||||||
* @return [T] or null
|
|
||||||
*/
|
|
||||||
inline fun <reified T> Method.callStatic(vararg param: Any?) =
|
|
||||||
if (param.isNotEmpty())
|
|
||||||
invoke(null, *param) as? T?
|
|
||||||
else invoke(null) as? T?
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行方法
|
|
||||||
* @param instance 目标对象
|
|
||||||
* @param param 方法参数
|
|
||||||
* @return [T] or null
|
|
||||||
*/
|
|
||||||
inline fun <reified T> Method.call(instance: Any?, vararg param: Any?) =
|
|
||||||
if (param.isNotEmpty())
|
|
||||||
invoke(instance, *param) as? T?
|
|
||||||
else invoke(instance) as? T?
|
|
||||||
|
@@ -192,10 +192,23 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook 方法、构造类
|
* Hook 方法、构造类
|
||||||
|
*
|
||||||
|
* - ❗为防止任何字符串都被当做 [Class] 进行 Hook - 推荐优先使用 [findClass]
|
||||||
* @param initiate 方法体
|
* @param initiate 方法体
|
||||||
*/
|
*/
|
||||||
fun Class<*>.hook(initiate: YukiHookCreater.() -> Unit) =
|
fun String.hook(initiate: YukiHookCreater.() -> Unit) = findClass(name = this).hook(initiate)
|
||||||
YukiHookCreater(packageParam = thisParam, hookClass = hookClass.bind()).apply(initiate).hook()
|
|
||||||
|
/**
|
||||||
|
* Hook 方法、构造类
|
||||||
|
* @param initiate 方法体
|
||||||
|
*/
|
||||||
|
fun Class<*>.hook(initiate: YukiHookCreater.() -> Unit) = hookClass.hook(initiate)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook 方法、构造类
|
||||||
|
* @param initiate 方法体
|
||||||
|
*/
|
||||||
|
fun VariousClass.hook(initiate: YukiHookCreater.() -> Unit) = hookClass.hook(initiate)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook 方法、构造类
|
* Hook 方法、构造类
|
||||||
@@ -204,13 +217,6 @@ open class PackageParam(private var wrapper: PackageParamWrapper? = null) {
|
|||||||
fun HookClass.hook(initiate: YukiHookCreater.() -> Unit) =
|
fun HookClass.hook(initiate: YukiHookCreater.() -> Unit) =
|
||||||
YukiHookCreater(packageParam = thisParam, hookClass = bind()).apply(initiate).hook()
|
YukiHookCreater(packageParam = thisParam, hookClass = bind()).apply(initiate).hook()
|
||||||
|
|
||||||
/**
|
|
||||||
* Hook 方法、构造类
|
|
||||||
* @param initiate 方法体
|
|
||||||
*/
|
|
||||||
fun VariousClass.hook(initiate: YukiHookCreater.() -> Unit) =
|
|
||||||
YukiHookCreater(packageParam = thisParam, hookClass = hookClass).apply(initiate).hook()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [VariousClass] 转换为 [HookClass] 并绑定到 [appClassLoader]
|
* [VariousClass] 转换为 [HookClass] 并绑定到 [appClassLoader]
|
||||||
* @return [HookClass]
|
* @return [HookClass]
|
||||||
|
Reference in New Issue
Block a user