mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
...
This commit is contained in:
@@ -50,6 +50,7 @@ class MainInjecter : YukiHookXposedInitProxy {
|
|||||||
|
|
||||||
override fun onHook() {
|
override fun onHook() {
|
||||||
// 设置模式
|
// 设置模式
|
||||||
|
YukiHookAPI.debugTag = "YukiSuki"
|
||||||
YukiHookAPI.isDebug = true
|
YukiHookAPI.isDebug = true
|
||||||
// 方案 1
|
// 方案 1
|
||||||
// encase(MainHooker(), SecondHooker())
|
// encase(MainHooker(), SecondHooker())
|
||||||
@@ -80,11 +81,11 @@ class MainInjecter : YukiHookXposedInitProxy {
|
|||||||
method {
|
method {
|
||||||
name = "a"
|
name = "a"
|
||||||
param(StringType, StringType)
|
param(StringType, StringType)
|
||||||
returnType = StringType
|
returnType = UnitType
|
||||||
}
|
}
|
||||||
beforeHook {
|
beforeHook {
|
||||||
args(index = 0).set("改了前面的")
|
args(index = 0).set("✌️改了前面的")
|
||||||
args(index = 1).set("改了后面的")
|
args(index = 1).set("✌️改了后面的")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
injectMember {
|
injectMember {
|
||||||
@@ -141,11 +142,9 @@ class MainInjecter : YukiHookXposedInitProxy {
|
|||||||
}.failures {
|
}.failures {
|
||||||
onConductFailure { _, _ -> }
|
onConductFailure { _, _ -> }
|
||||||
onHookingFailure {}
|
onHookingFailure {}
|
||||||
onNoSuchMemberFailure {}
|
|
||||||
onAllFailure {}
|
onAllFailure {}
|
||||||
ignoredConductFailure()
|
ignoredConductFailure()
|
||||||
ignoredHookingFailure()
|
ignoredHookingFailure()
|
||||||
ignoredNoSuchMemberFailure()
|
|
||||||
ignoredAllFailure()
|
ignoredAllFailure()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -49,15 +49,23 @@ import de.robv.android.xposed.callbacks.XC_LoadPackage
|
|||||||
@Keep
|
@Keep
|
||||||
object YukiHookAPI {
|
object YukiHookAPI {
|
||||||
|
|
||||||
/** 全局标识 */
|
/**
|
||||||
const val TAG = "YukiHookAPI"
|
* 这是一个调试日志的全局标识
|
||||||
|
*
|
||||||
|
* 默认文案为 YukiHookAPI
|
||||||
|
*
|
||||||
|
* 你可以修改为你自己的文案
|
||||||
|
*/
|
||||||
|
var debugTag = "YukiHookAPI"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否开启调试模式 - 默认启用
|
* 是否开启调试模式 - 默认启用
|
||||||
*
|
*
|
||||||
* 启用后将交由日志输出管理器打印详细 Hook 日志到控制台
|
* 启用后将交由日志输出管理器打印详细 Hook 日志到控制台
|
||||||
*
|
*
|
||||||
* 请过滤 [TAG] (YukiHookAPI) 即可找到每条日志
|
* 关闭后将只输出 Error 级别的日志
|
||||||
|
*
|
||||||
|
* 请过滤 [debugTag] 即可找到每条日志
|
||||||
*/
|
*/
|
||||||
var isDebug = true
|
var isDebug = true
|
||||||
|
|
||||||
|
@@ -38,7 +38,6 @@ import com.highcapable.yukihookapi.hook.log.loggerE
|
|||||||
import com.highcapable.yukihookapi.hook.log.loggerI
|
import com.highcapable.yukihookapi.hook.log.loggerI
|
||||||
import com.highcapable.yukihookapi.hook.param.HookParam
|
import com.highcapable.yukihookapi.hook.param.HookParam
|
||||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||||
import com.highcapable.yukihookapi.hook.utils.runBlocking
|
|
||||||
import de.robv.android.xposed.XC_MethodHook
|
import de.robv.android.xposed.XC_MethodHook
|
||||||
import de.robv.android.xposed.XC_MethodReplacement
|
import de.robv.android.xposed.XC_MethodReplacement
|
||||||
import de.robv.android.xposed.XposedBridge
|
import de.robv.android.xposed.XposedBridge
|
||||||
@@ -59,15 +58,17 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 注入要 Hook 的方法、构造类
|
* 注入要 Hook 的方法、构造类
|
||||||
|
* @param tag 可设置标签 - 在发生错误时方便进行调试
|
||||||
* @param initiate 方法体
|
* @param initiate 方法体
|
||||||
*/
|
*/
|
||||||
fun injectMember(initiate: MemberHookCreater.() -> Unit) =
|
fun injectMember(tag: String = "Default", initiate: MemberHookCreater.() -> Unit) =
|
||||||
MemberHookCreater().apply(initiate).apply {
|
MemberHookCreater(tag).apply(initiate).apply {
|
||||||
hookMembers[toString()] = this
|
hookMembers[toString()] = this
|
||||||
}.create()
|
}.build()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook 执行入口 - 不可在外部调用
|
* Hook 执行入口
|
||||||
|
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
* @throws IllegalStateException 如果必要参数没有被设置
|
* @throws IllegalStateException 如果必要参数没有被设置
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
@@ -80,8 +81,9 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
* 智能全局方法、构造类查找类实现方法
|
* 智能全局方法、构造类查找类实现方法
|
||||||
*
|
*
|
||||||
* 处理需要 Hook 的方法
|
* 处理需要 Hook 的方法
|
||||||
|
* @param tag 当前设置的标签
|
||||||
*/
|
*/
|
||||||
inner class MemberHookCreater {
|
inner class MemberHookCreater(var tag: String) {
|
||||||
|
|
||||||
/** [beforeHook] 回调 */
|
/** [beforeHook] 回调 */
|
||||||
private var beforeHookCallback: (HookParam.() -> Unit)? = null
|
private var beforeHookCallback: (HookParam.() -> Unit)? = null
|
||||||
@@ -98,17 +100,14 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
/** Hook 开始时出现错误回调 */
|
/** Hook 开始时出现错误回调 */
|
||||||
private var onHookingFailureCallback: ((Throwable) -> Unit)? = null
|
private var onHookingFailureCallback: ((Throwable) -> Unit)? = null
|
||||||
|
|
||||||
/** 当找不到方法、变量时错误回调 */
|
|
||||||
private var onNoSuchMemberCallback: ((Throwable) -> Unit)? = null
|
|
||||||
|
|
||||||
/** 全部错误回调 */
|
/** 全部错误回调 */
|
||||||
private var onAllFailureCallback: ((Throwable) -> Unit)? = null
|
private var onAllFailureCallback: ((Throwable) -> Unit)? = null
|
||||||
|
|
||||||
/** 是否为替换 Hook 模式 */
|
/** 是否为替换 Hook 模式 */
|
||||||
private var isReplaceHookMode = false
|
private var isReplaceHookMode = false
|
||||||
|
|
||||||
/** 是否停止 Hook */
|
/** 标识是否已经设置了要 Hook 的 [member] */
|
||||||
private var isStopHookMode = false
|
private var isHookMemberSetup = false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 手动指定要 Hook 的方法、构造类
|
* 手动指定要 Hook 的方法、构造类
|
||||||
@@ -122,17 +121,12 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
*
|
*
|
||||||
* 你只能使用一次 [method] 或 [constructor] 方法 - 否则结果会被替换
|
* 你只能使用一次 [method] 或 [constructor] 方法 - 否则结果会被替换
|
||||||
* @param initiate 方法体
|
* @param initiate 方法体
|
||||||
|
* @return [MethodFinder.Result]
|
||||||
*/
|
*/
|
||||||
fun method(initiate: MethodFinder.() -> Unit) = runBlocking {
|
fun method(initiate: MethodFinder.() -> Unit): MethodFinder.Result {
|
||||||
runCatching {
|
isHookMemberSetup = true
|
||||||
member = MethodFinder(hookClass).apply(initiate).find()
|
return MethodFinder(hookInstance = this, hookClass).apply(initiate).build()
|
||||||
}.onFailure {
|
}
|
||||||
isStopHookMode = true
|
|
||||||
onNoSuchMemberCallback?.invoke(it)
|
|
||||||
onAllFailureCallback?.invoke(it)
|
|
||||||
if (onNoSuchMemberCallback == null && onAllFailureCallback == null) onHookFailureMsg(it)
|
|
||||||
}
|
|
||||||
}.result { onHookLogMsg(msg = "Find Method [$member] takes ${it}ms") }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找需要 Hook 的构造类
|
* 查找需要 Hook 的构造类
|
||||||
@@ -140,16 +134,10 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
* 你只能使用一次 [method] 或 [constructor] 方法 - 否则结果会被替换
|
* 你只能使用一次 [method] 或 [constructor] 方法 - 否则结果会被替换
|
||||||
* @param initiate 方法体
|
* @param initiate 方法体
|
||||||
*/
|
*/
|
||||||
fun constructor(initiate: ConstructorFinder.() -> Unit) = runBlocking {
|
fun constructor(initiate: ConstructorFinder.() -> Unit): ConstructorFinder.Result {
|
||||||
runCatching {
|
isHookMemberSetup = true
|
||||||
member = ConstructorFinder(hookClass).apply(initiate).find()
|
return ConstructorFinder(hookInstance = this, hookClass).apply(initiate).build()
|
||||||
}.onFailure {
|
}
|
||||||
isStopHookMode = true
|
|
||||||
onNoSuchMemberCallback?.invoke(it)
|
|
||||||
onAllFailureCallback?.invoke(it)
|
|
||||||
if (onNoSuchMemberCallback == null && onAllFailureCallback == null) onHookFailureMsg(it)
|
|
||||||
}
|
|
||||||
}.result { onHookLogMsg(msg = "Find Constructor [$member] takes ${it}ms") }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查找 [Field]
|
* 查找 [Field]
|
||||||
@@ -157,19 +145,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
* @return [FieldFinder.Result]
|
* @return [FieldFinder.Result]
|
||||||
*/
|
*/
|
||||||
fun HookParam.field(initiate: FieldFinder.() -> Unit) =
|
fun HookParam.field(initiate: FieldFinder.() -> Unit) =
|
||||||
try {
|
FieldFinder(hookInstance = this@MemberHookCreater, hookClass).apply(initiate).build()
|
||||||
var result: FieldFinder.Result? = null
|
|
||||||
runBlocking {
|
|
||||||
result = FieldFinder(hookClass).apply(initiate).find()
|
|
||||||
}.result { onHookLogMsg(msg = "Find Field [${result?.give()}] takes ${it}ms") }
|
|
||||||
result!!
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
isStopHookMode = true
|
|
||||||
onNoSuchMemberCallback?.invoke(e)
|
|
||||||
onAllFailureCallback?.invoke(e)
|
|
||||||
if (onNoSuchMemberCallback == null && onAllFailureCallback == null) onHookFailureMsg(e)
|
|
||||||
FieldFinder(hookClass).Result()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在方法执行完成前 Hook
|
* 在方法执行完成前 Hook
|
||||||
@@ -263,80 +239,99 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook 创建入口 - 不可在外部调用
|
* Hook 创建入口
|
||||||
|
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
* @return [Result]
|
* @return [Result]
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun create() = Result()
|
fun build() = Result()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hook 执行入口 - 不可在外部调用
|
* Hook 执行入口
|
||||||
* @throws IllegalStateException 如果必要参数没有被设置
|
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun hook() {
|
fun hook() {
|
||||||
if (isStopHookMode) return
|
if (member != null)
|
||||||
member?.also { member ->
|
member.also { member ->
|
||||||
runCatching {
|
runCatching {
|
||||||
if (isReplaceHookMode)
|
if (isReplaceHookMode)
|
||||||
XposedBridge.hookMethod(member, object : XC_MethodReplacement() {
|
XposedBridge.hookMethod(member, object : XC_MethodReplacement() {
|
||||||
override fun replaceHookedMethod(baseParam: MethodHookParam?): Any? {
|
override fun replaceHookedMethod(baseParam: MethodHookParam?): Any? {
|
||||||
if (baseParam == null) return null
|
if (baseParam == null) return null
|
||||||
return HookParam(baseParam).let { param ->
|
return HookParam(baseParam).let { param ->
|
||||||
try {
|
try {
|
||||||
if (replaceHookCallback != null)
|
if (replaceHookCallback != null)
|
||||||
onHookLogMsg(msg = "Replace Hook Member [${member}] done")
|
onHookLogMsg(msg = "Replace Hook Member [${member}] done [$tag]")
|
||||||
replaceHookCallback?.invoke(param)
|
replaceHookCallback?.invoke(param)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
onConductFailureCallback?.invoke(param, e)
|
onConductFailureCallback?.invoke(param, e)
|
||||||
onAllFailureCallback?.invoke(e)
|
onAllFailureCallback?.invoke(e)
|
||||||
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
||||||
onHookFailureMsg(e)
|
onHookFailureMsg(e)
|
||||||
null
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
else
|
||||||
else
|
XposedBridge.hookMethod(member, object : XC_MethodHook() {
|
||||||
XposedBridge.hookMethod(member, object : XC_MethodHook() {
|
override fun beforeHookedMethod(baseParam: MethodHookParam?) {
|
||||||
override fun beforeHookedMethod(baseParam: MethodHookParam?) {
|
if (baseParam == null) return
|
||||||
if (baseParam == null) return
|
HookParam(baseParam).also { param ->
|
||||||
HookParam(baseParam).also { param ->
|
runCatching {
|
||||||
runCatching {
|
beforeHookCallback?.invoke(param)
|
||||||
beforeHookCallback?.invoke(param)
|
if (beforeHookCallback != null)
|
||||||
if (beforeHookCallback != null)
|
onHookLogMsg(msg = "Before Hook Member [${member}] done [$tag]")
|
||||||
onHookLogMsg(msg = "Before Hook Member [${member}] done")
|
}.onFailure {
|
||||||
}.onFailure {
|
onConductFailureCallback?.invoke(param, it)
|
||||||
onConductFailureCallback?.invoke(param, it)
|
onAllFailureCallback?.invoke(it)
|
||||||
onAllFailureCallback?.invoke(it)
|
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
||||||
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
onHookFailureMsg(it)
|
||||||
onHookFailureMsg(it)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun afterHookedMethod(baseParam: MethodHookParam?) {
|
override fun afterHookedMethod(baseParam: MethodHookParam?) {
|
||||||
if (baseParam == null) return
|
if (baseParam == null) return
|
||||||
HookParam(baseParam).also { param ->
|
HookParam(baseParam).also { param ->
|
||||||
runCatching {
|
runCatching {
|
||||||
afterHookCallback?.invoke(param)
|
afterHookCallback?.invoke(param)
|
||||||
if (afterHookCallback != null)
|
if (afterHookCallback != null)
|
||||||
onHookLogMsg(msg = "After Hook Member [${member}] done")
|
onHookLogMsg(msg = "After Hook Member [${member}] done [$tag]")
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
onConductFailureCallback?.invoke(param, it)
|
onConductFailureCallback?.invoke(param, it)
|
||||||
onAllFailureCallback?.invoke(it)
|
onAllFailureCallback?.invoke(it)
|
||||||
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
||||||
onHookFailureMsg(it)
|
onHookFailureMsg(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
}.onFailure {
|
||||||
}.onFailure {
|
onHookingFailureCallback?.invoke(it)
|
||||||
onHookingFailureCallback?.invoke(it)
|
onAllFailureCallback?.invoke(it)
|
||||||
onAllFailureCallback?.invoke(it)
|
if (onHookingFailureCallback == null && onAllFailureCallback == null) onHookFailureMsg(it)
|
||||||
if (onHookingFailureCallback == null && onAllFailureCallback == null) onHookFailureMsg(it)
|
}
|
||||||
}
|
}
|
||||||
} ?: error("Hook Member cannot be null")
|
else {
|
||||||
|
onHookingFailureCallback?.invoke(Throwable())
|
||||||
|
onAllFailureCallback?.invoke(Throwable())
|
||||||
|
if (onHookingFailureCallback == null && onAllFailureCallback == null)
|
||||||
|
loggerE(
|
||||||
|
msg = if (isHookMemberSetup)
|
||||||
|
"Hooked Member with a finding error in Class [$hookClass] [$tag]"
|
||||||
|
else "Hooked Member cannot be non-null in Class [$hookClass] [$tag]"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook 过程中开启了 [YukiHookAPI.isDebug] 输出调试信息
|
||||||
|
* @param msg 调试日志内容
|
||||||
|
*/
|
||||||
|
internal fun onHookLogMsg(msg: String) {
|
||||||
|
if (YukiHookAPI.isDebug) loggerI(msg = msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -344,17 +339,9 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
* @param throwable 异常信息
|
* @param throwable 异常信息
|
||||||
*/
|
*/
|
||||||
private fun onHookFailureMsg(throwable: Throwable) =
|
private fun onHookFailureMsg(throwable: Throwable) =
|
||||||
loggerE(msg = "Try to hook $hookClass[$member] got an Exception", e = throwable)
|
loggerE(msg = "Try to hook $hookClass[$member] got an Exception [$tag]", e = throwable)
|
||||||
|
|
||||||
/**
|
override fun toString() = "$member$tag#YukiHook"
|
||||||
* Hook 过程中开启了 [YukiHookAPI.isDebug] 输出调试信息
|
|
||||||
* @param msg 调试日志内容
|
|
||||||
*/
|
|
||||||
private fun onHookLogMsg(msg: String) {
|
|
||||||
if (YukiHookAPI.isDebug) loggerI(msg = msg)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString() = "$member#YukiHook"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听 Hook 结果实现类
|
* 监听 Hook 结果实现类
|
||||||
@@ -388,7 +375,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听 Hook 开始时发生错误的回调方法
|
* 监听 Hook 开始时发生错误的回调方法
|
||||||
* @param initiate 回调错误 - ([Throwable] 异常)
|
* @param initiate 回调错误
|
||||||
* @return [Result] 可继续向下监听
|
* @return [Result] 可继续向下监听
|
||||||
*/
|
*/
|
||||||
fun onHookingFailure(initiate: (Throwable) -> Unit): Result {
|
fun onHookingFailure(initiate: (Throwable) -> Unit): Result {
|
||||||
@@ -402,25 +389,9 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
|||||||
*/
|
*/
|
||||||
fun ignoredHookingFailure() = onHookingFailure {}
|
fun ignoredHookingFailure() = onHookingFailure {}
|
||||||
|
|
||||||
/**
|
|
||||||
* 监听 Hook 过程发生找不到方法、变量错误的回调方法
|
|
||||||
* @param initiate 回调错误 - ([Throwable] 异常)
|
|
||||||
* @return [Result] 可继续向下监听
|
|
||||||
*/
|
|
||||||
fun onNoSuchMemberFailure(initiate: (Throwable) -> Unit): Result {
|
|
||||||
onNoSuchMemberCallback = initiate
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 忽略 Hook 过程发生找不到方法、变量的错误
|
|
||||||
* @return [Result] 可继续向下监听
|
|
||||||
*/
|
|
||||||
fun ignoredNoSuchMemberFailure() = onNoSuchMemberFailure {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 监听全部 Hook 过程发生错误的回调方法
|
* 监听全部 Hook 过程发生错误的回调方法
|
||||||
* @param initiate 回调错误 - ([Throwable] 异常)
|
* @param initiate 回调错误
|
||||||
* @return [Result] 可继续向下监听
|
* @return [Result] 可继续向下监听
|
||||||
*/
|
*/
|
||||||
fun onAllFailure(initiate: (Throwable) -> Unit): Result {
|
fun onAllFailure(initiate: (Throwable) -> Unit): Result {
|
||||||
|
@@ -25,27 +25,35 @@
|
|||||||
*
|
*
|
||||||
* This file is Created by fankes on 2022/2/4.
|
* This file is Created by fankes on 2022/2/4.
|
||||||
*/
|
*/
|
||||||
@file:Suppress("unused")
|
@file:Suppress("unused", "EXPERIMENTAL_API_USAGE", "MemberVisibilityCanBePrivate")
|
||||||
|
|
||||||
package com.highcapable.yukihookapi.hook.core.finder
|
package com.highcapable.yukihookapi.hook.core.finder
|
||||||
|
|
||||||
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
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.loggerW
|
||||||
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
||||||
|
import com.highcapable.yukihookapi.hook.utils.runBlocking
|
||||||
import java.lang.reflect.Constructor
|
import java.lang.reflect.Constructor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Constructor] 查找类
|
* [Constructor] 查找类
|
||||||
*
|
*
|
||||||
* 可通过指定类型查找指定构造类
|
* 可通过指定类型查找指定构造方法
|
||||||
|
* @param hookInstance 当前 Hook 实例
|
||||||
* @param hookClass 当前被 Hook 的 [Class]
|
* @param hookClass 当前被 Hook 的 [Class]
|
||||||
*/
|
*/
|
||||||
class ConstructorFinder(private val hookClass: Class<*>) {
|
class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>) {
|
||||||
|
|
||||||
/** 方法参数 */
|
/** 失败尝试次数数组 */
|
||||||
|
private val remedyPlan = HashMap<Long, ConstructorFinder>()
|
||||||
|
|
||||||
|
/** 构造方法参数 */
|
||||||
private var params: Array<out Class<*>>? = null
|
private var params: Array<out Class<*>>? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 方法参数
|
* 构造方法参数
|
||||||
* @param param 参数数组
|
* @param param 参数数组
|
||||||
*/
|
*/
|
||||||
fun param(vararg param: Class<*>) {
|
fun param(vararg param: Class<*>) {
|
||||||
@@ -53,13 +61,135 @@ class ConstructorFinder(private val hookClass: Class<*>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 得到构造类 - 不能在外部调用
|
* 得到构造方法
|
||||||
* @return [Constructor]
|
* @return [Constructor]
|
||||||
* @throws NoSuchMethodError 如果找不到构造类
|
* @throws NoSuchMethodError 如果找不到构造方法
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
private val result
|
||||||
fun find(): Constructor<*> =
|
get() = if (params != null)
|
||||||
if (params != null)
|
|
||||||
ReflectionUtils.findConstructorExact(hookClass, *params!!)
|
ReflectionUtils.findConstructorExact(hookClass, *params!!)
|
||||||
else ReflectionUtils.findConstructorExact(hookClass)
|
else ReflectionUtils.findConstructorExact(hookClass)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到构造方法结果
|
||||||
|
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
|
* @return [Result]
|
||||||
|
*/
|
||||||
|
@DoNotUseMethod
|
||||||
|
fun build() = try {
|
||||||
|
runBlocking {
|
||||||
|
hookInstance.member = result
|
||||||
|
}.result {
|
||||||
|
hookInstance.onHookLogMsg(msg = "Find Constructor [${hookInstance.member}] takes ${it}ms [${hookInstance.tag}]")
|
||||||
|
}
|
||||||
|
Result()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
onFailureMsg(throwable = e)
|
||||||
|
Result(isNoSuch = true, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发生错误时输出日志
|
||||||
|
* @param msg 消息日志
|
||||||
|
* @param throwable 错误
|
||||||
|
*/
|
||||||
|
private fun onFailureMsg(msg: String = "", throwable: Throwable? = null) =
|
||||||
|
loggerE(msg = "NoSuchConstructor happend in [$hookClass] $msg [${hookInstance.tag}]", e = throwable)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Constructor] 重查找实现类
|
||||||
|
*
|
||||||
|
* 可累计失败次数直到查找成功
|
||||||
|
*/
|
||||||
|
inner class RemedyPlan {
|
||||||
|
|
||||||
|
/** 失败尝试次数数组 */
|
||||||
|
private val remedyPlan = HashSet<ConstructorFinder>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建需要重新查找的 [Constructor]
|
||||||
|
*
|
||||||
|
* 你可以添加多个备选构造方法 - 直到成功为止
|
||||||
|
*
|
||||||
|
* 若最后依然失败 - 将停止查找并输出错误日志
|
||||||
|
* @param initiate 方法体
|
||||||
|
*/
|
||||||
|
fun constructor(initiate: ConstructorFinder.() -> Unit) =
|
||||||
|
remedyPlan.add(ConstructorFinder(hookInstance, hookClass).apply(initiate))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始重查找
|
||||||
|
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
|
*/
|
||||||
|
@DoNotUseMethod
|
||||||
|
internal fun build() {
|
||||||
|
if (remedyPlan.isNotEmpty()) run {
|
||||||
|
var isFindSuccess = false
|
||||||
|
var lastError: Throwable? = null
|
||||||
|
remedyPlan.forEachIndexed { p, it ->
|
||||||
|
runCatching {
|
||||||
|
runBlocking {
|
||||||
|
hookInstance.member = it.result
|
||||||
|
}.result {
|
||||||
|
hookInstance.onHookLogMsg(msg = "Find Constructor [${hookInstance.member}] takes ${it}ms [${hookInstance.tag}]")
|
||||||
|
}
|
||||||
|
isFindSuccess = true
|
||||||
|
hookInstance.onHookLogMsg(msg = "Constructor [${hookInstance.member}] trying ${p + 1} times success by RemedyPlan [${hookInstance.tag}]")
|
||||||
|
return@run
|
||||||
|
}.onFailure {
|
||||||
|
lastError = it
|
||||||
|
onFailureMsg(msg = "trying ${p + 1} times by RemedyPlan --> $it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isFindSuccess) {
|
||||||
|
onFailureMsg(
|
||||||
|
msg = "trying ${remedyPlan.size} times and all failure by RemedyPlan",
|
||||||
|
throwable = lastError
|
||||||
|
)
|
||||||
|
remedyPlan.clear()
|
||||||
|
}
|
||||||
|
} else loggerW(msg = "RemedyPlan is empty,forgot it? [${hookInstance.tag}]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Constructor] 查找结果实现类
|
||||||
|
* @param isNoSuch 是否没有找到构造方法 - 默认否
|
||||||
|
* @param e 错误信息
|
||||||
|
*/
|
||||||
|
inner class Result(private val isNoSuch: Boolean = false, private val e: Throwable? = null) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建监听结果事件方法体
|
||||||
|
* @param initiate 方法体
|
||||||
|
* @return [Result] 可继续向下监听
|
||||||
|
*/
|
||||||
|
fun result(initiate: Result.() -> Unit) = apply(initiate)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建构造方法重查找功能
|
||||||
|
*
|
||||||
|
* 当你遇到一种构造方法可能存在不同形式的存在时
|
||||||
|
*
|
||||||
|
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchConstructor] 捕获异常二次查找构造方法
|
||||||
|
* @param initiate 方法体
|
||||||
|
* @return [Result] 可继续向下监听
|
||||||
|
*/
|
||||||
|
fun remedys(initiate: RemedyPlan.() -> Unit): Result {
|
||||||
|
if (isNoSuch) RemedyPlan().apply(initiate).build()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听找不到构造方法时
|
||||||
|
*
|
||||||
|
* 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
|
||||||
|
* @param initiate 回调错误
|
||||||
|
* @return [Result] 可继续向下监听
|
||||||
|
*/
|
||||||
|
fun onNoSuchConstructor(initiate: (Throwable) -> Unit): Result {
|
||||||
|
if (isNoSuch) initiate(e ?: Throwable())
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -30,16 +30,20 @@
|
|||||||
package com.highcapable.yukihookapi.hook.core.finder
|
package com.highcapable.yukihookapi.hook.core.finder
|
||||||
|
|
||||||
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
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.utils.ReflectionUtils
|
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
||||||
|
import com.highcapable.yukihookapi.hook.utils.runBlocking
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Field 查找结果实现类
|
* Field 查找结果实现类
|
||||||
*
|
*
|
||||||
* 可在这里处理找到的 [fieldInstance]
|
* 可在这里处理找到的 [fieldInstance]
|
||||||
|
* @param hookInstance 当前 Hook 实例
|
||||||
* @param hookClass 当前被 Hook 的 [Class]
|
* @param hookClass 当前被 Hook 的 [Class]
|
||||||
*/
|
*/
|
||||||
class FieldFinder(private val hookClass: Class<*>) {
|
class FieldFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>) {
|
||||||
|
|
||||||
/** 当前找到的 [Field] */
|
/** 当前找到的 [Field] */
|
||||||
private var fieldInstance: Field? = null
|
private var fieldInstance: Field? = null
|
||||||
@@ -51,25 +55,42 @@ class FieldFinder(private val hookClass: Class<*>) {
|
|||||||
var type: Class<*>? = null
|
var type: Class<*>? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 得到变量处理结果 - 不能在外部调用
|
* 得到变量处理结果
|
||||||
|
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
* @return [Result]
|
* @return [Result]
|
||||||
* @throws NoSuchFieldError 如果找不到变量
|
* @throws IllegalStateException 如果 [name] 没有被设置
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun find(): Result {
|
fun build() = if (name.isBlank()) {
|
||||||
fieldInstance = when {
|
loggerE(msg = "Field name cannot be empty in Class [$hookClass] [${hookInstance.tag}]")
|
||||||
name.isBlank() -> error("Field name cannot be empty")
|
Result(isNoSuch = true)
|
||||||
else -> ReflectionUtils.findFieldIfExists(hookClass, type?.name, name)
|
} else try {
|
||||||
|
runBlocking {
|
||||||
|
fieldInstance = ReflectionUtils.findFieldIfExists(hookClass, type?.name, name)
|
||||||
|
}.result {
|
||||||
|
hookInstance.onHookLogMsg(msg = "Find Field [${fieldInstance}] takes ${it}ms [${hookInstance.tag}]")
|
||||||
}
|
}
|
||||||
return Result()
|
Result()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
loggerE(msg = "NoSuchField happend in [$hookClass] [${hookInstance.tag}]", e = e)
|
||||||
|
Result(isNoSuch = true, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Field 查找结果实现类
|
* Field 查找结果实现类
|
||||||
*
|
*
|
||||||
* 可在这里处理找到的 [fieldInstance]
|
* 可在这里处理找到的 [fieldInstance]
|
||||||
|
* @param isNoSuch 是否没有找到变量 - 默认否
|
||||||
|
* @param e 错误信息
|
||||||
*/
|
*/
|
||||||
inner class Result {
|
inner class Result(private val isNoSuch: Boolean = false, private val e: Throwable? = null) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建监听结果事件方法体
|
||||||
|
* @param initiate 方法体
|
||||||
|
* @return [Result] 可继续向下监听
|
||||||
|
*/
|
||||||
|
fun result(initiate: Result.() -> Unit) = apply(initiate)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置变量实例
|
* 设置变量实例
|
||||||
@@ -90,5 +111,17 @@ class FieldFinder(private val hookClass: Class<*>) {
|
|||||||
* @return [Field] or null
|
* @return [Field] or null
|
||||||
*/
|
*/
|
||||||
fun give() = fieldInstance
|
fun give() = fieldInstance
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听找不到变量时
|
||||||
|
*
|
||||||
|
* 只会返回第一次和最后一次的错误信息
|
||||||
|
* @param initiate 回调错误
|
||||||
|
* @return [Result] 可继续向下监听
|
||||||
|
*/
|
||||||
|
fun onNoSuchField(initiate: (Throwable) -> Unit): Result {
|
||||||
|
if (isNoSuch) initiate(e ?: Throwable())
|
||||||
|
return this
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -25,21 +25,26 @@
|
|||||||
*
|
*
|
||||||
* This file is Created by fankes on 2022/2/4.
|
* This file is Created by fankes on 2022/2/4.
|
||||||
*/
|
*/
|
||||||
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
|
@file:Suppress("unused", "MemberVisibilityCanBePrivate", "EXPERIMENTAL_API_USAGE")
|
||||||
|
|
||||||
package com.highcapable.yukihookapi.hook.core.finder
|
package com.highcapable.yukihookapi.hook.core.finder
|
||||||
|
|
||||||
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
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.loggerW
|
||||||
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
import com.highcapable.yukihookapi.hook.utils.ReflectionUtils
|
||||||
|
import com.highcapable.yukihookapi.hook.utils.runBlocking
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [Method] 查找类
|
* [Method] 查找类
|
||||||
*
|
*
|
||||||
* 可通过指定类型查找指定方法
|
* 可通过指定类型查找指定方法
|
||||||
* @param hookClass 当前被 Hook 的 [Class]
|
* @param hookInstance 当前 Hook 实例
|
||||||
|
* @param hookClass 当前 Hook 的 Class
|
||||||
*/
|
*/
|
||||||
class MethodFinder(private val hookClass: Class<*>) {
|
class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, private val hookClass: Class<*>) {
|
||||||
|
|
||||||
/** 方法参数 */
|
/** 方法参数 */
|
||||||
private var params: Array<out Class<*>>? = null
|
private var params: Array<out Class<*>>? = null
|
||||||
@@ -59,17 +64,140 @@ class MethodFinder(private val hookClass: Class<*>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 得到方法 - 不能在外部调用
|
* 得到方法
|
||||||
* @return [Method]
|
* @return [Method]
|
||||||
|
* @throws IllegalStateException 如果 [name] 未设置
|
||||||
* @throws NoSuchMethodError 如果找不到方法
|
* @throws NoSuchMethodError 如果找不到方法
|
||||||
*/
|
*/
|
||||||
|
private val result
|
||||||
|
get() = if (params != null)
|
||||||
|
ReflectionUtils.findMethodBestMatch(hookClass, returnType, name, *params!!)
|
||||||
|
else ReflectionUtils.findMethodNoParam(hookClass, returnType, name)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 得到方法结果
|
||||||
|
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
|
* @return [Result]
|
||||||
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
fun find(): Method =
|
fun build() = if (name.isBlank()) {
|
||||||
when {
|
loggerE(msg = "Method name cannot be empty in Class [$hookClass] [${hookInstance.tag}]")
|
||||||
name.isBlank() -> error("Method name cannot be empty")
|
Result(isNoSuch = true)
|
||||||
else ->
|
} else try {
|
||||||
if (params != null)
|
runBlocking {
|
||||||
ReflectionUtils.findMethodBestMatch(hookClass, returnType, name, *params!!)
|
hookInstance.member = result
|
||||||
else ReflectionUtils.findMethodNoParam(hookClass, returnType, name)
|
}.result {
|
||||||
|
hookInstance.onHookLogMsg(msg = "Find Method [${hookInstance.member}] takes ${it}ms [${hookInstance.tag}]")
|
||||||
}
|
}
|
||||||
|
Result()
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
onFailureMsg(throwable = e)
|
||||||
|
Result(isNoSuch = true, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发生错误时输出日志
|
||||||
|
* @param msg 消息日志
|
||||||
|
* @param throwable 错误
|
||||||
|
*/
|
||||||
|
private fun onFailureMsg(msg: String = "", throwable: Throwable? = null) =
|
||||||
|
loggerE(msg = "NoSuchMethod happend in [$hookClass] $msg [${hookInstance.tag}]", e = throwable)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Method] 重查找实现类
|
||||||
|
*
|
||||||
|
* 可累计失败次数直到查找成功
|
||||||
|
*/
|
||||||
|
inner class RemedyPlan {
|
||||||
|
|
||||||
|
/** 失败尝试次数数组 */
|
||||||
|
private val remedyPlan = HashSet<MethodFinder>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建需要重新查找的 [Method]
|
||||||
|
*
|
||||||
|
* 你可以添加多个备选方法 - 直到成功为止
|
||||||
|
*
|
||||||
|
* 若最后依然失败 - 将停止查找并输出错误日志
|
||||||
|
* @param initiate 方法体
|
||||||
|
*/
|
||||||
|
fun method(initiate: MethodFinder.() -> Unit) = remedyPlan.add(MethodFinder(hookInstance, hookClass).apply(initiate))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始重查找
|
||||||
|
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||||
|
*/
|
||||||
|
@DoNotUseMethod
|
||||||
|
internal fun build() {
|
||||||
|
if (remedyPlan.isNotEmpty()) run {
|
||||||
|
var isFindSuccess = false
|
||||||
|
var lastError: Throwable? = null
|
||||||
|
remedyPlan.forEachIndexed { p, it ->
|
||||||
|
runCatching {
|
||||||
|
runBlocking {
|
||||||
|
hookInstance.member = it.result
|
||||||
|
}.result {
|
||||||
|
hookInstance.onHookLogMsg(msg = "Find Method [${hookInstance.member}] takes ${it}ms [${hookInstance.tag}]")
|
||||||
|
}
|
||||||
|
isFindSuccess = true
|
||||||
|
hookInstance.onHookLogMsg(msg = "Method [${hookInstance.member}] trying ${p + 1} times success by RemedyPlan [${hookInstance.tag}]")
|
||||||
|
return@run
|
||||||
|
}.onFailure {
|
||||||
|
lastError = it
|
||||||
|
onFailureMsg(msg = "trying ${p + 1} times by RemedyPlan --> $it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isFindSuccess) {
|
||||||
|
onFailureMsg(
|
||||||
|
msg = "trying ${remedyPlan.size} times and all failure by RemedyPlan",
|
||||||
|
throwable = lastError
|
||||||
|
)
|
||||||
|
remedyPlan.clear()
|
||||||
|
}
|
||||||
|
} else loggerW(msg = "RemedyPlan is empty,forgot it? [${hookInstance.tag}]")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [Method] 查找结果实现类
|
||||||
|
* @param isNoSuch 是否没有找到方法 - 默认否
|
||||||
|
* @param e 错误信息
|
||||||
|
*/
|
||||||
|
inner class Result(private val isNoSuch: Boolean = false, private val e: Throwable? = null) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建监听结果事件方法体
|
||||||
|
* @param initiate 方法体
|
||||||
|
* @return [Result] 可继续向下监听
|
||||||
|
*/
|
||||||
|
fun result(initiate: Result.() -> Unit) = apply(initiate)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建方法重查找功能
|
||||||
|
*
|
||||||
|
* 当你遇到一种方法可能存在不同形式的存在时
|
||||||
|
*
|
||||||
|
* 可以使用 [RemedyPlan] 重新查找它 - 而没有必要使用 [onNoSuchMethod] 捕获异常二次查找方法
|
||||||
|
*
|
||||||
|
* 若第一次查找失败了 - 你还可以在这里继续添加此方法体直到成功为止
|
||||||
|
* @param initiate 方法体
|
||||||
|
* @return [Result] 可继续向下监听
|
||||||
|
*/
|
||||||
|
fun remedys(initiate: RemedyPlan.() -> Unit): Result {
|
||||||
|
if (isNoSuch) RemedyPlan().apply(initiate).build()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 监听找不到方法时
|
||||||
|
*
|
||||||
|
* 只会返回第一次的错误信息 - 不会返回 [RemedyPlan] 的错误信息
|
||||||
|
* @param initiate 回调错误
|
||||||
|
* @return [Result] 可继续向下监听
|
||||||
|
*/
|
||||||
|
fun onNoSuchMethod(initiate: (Throwable) -> Unit): Result {
|
||||||
|
if (isNoSuch) initiate(e ?: Throwable())
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@@ -75,6 +75,7 @@ abstract class YukiBaseHooker : PackageParam() {
|
|||||||
/**
|
/**
|
||||||
* 赋值并克隆一个 [PackageParam]
|
* 赋值并克隆一个 [PackageParam]
|
||||||
* @param packageParam 需要使用的 [PackageParam]
|
* @param packageParam 需要使用的 [PackageParam]
|
||||||
|
* - 此方法为私有功能性 API - 你不应该手动调用此方法
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
internal fun assignInstance(packageParam: PackageParam) {
|
internal fun assignInstance(packageParam: PackageParam) {
|
||||||
|
@@ -36,13 +36,11 @@ import de.robv.android.xposed.XposedBridge
|
|||||||
/**
|
/**
|
||||||
* 向控制台和 [XposedBridge] 打印日志 - D
|
* 向控制台和 [XposedBridge] 打印日志 - D
|
||||||
*
|
*
|
||||||
* 你可以对此方法进行二次封装
|
|
||||||
*
|
|
||||||
* [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg]
|
* [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg]
|
||||||
* @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.TAG]
|
* @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.debugTag]
|
||||||
* @param msg 日志打印的内容
|
* @param msg 日志打印的内容
|
||||||
*/
|
*/
|
||||||
fun loggerD(tag: String = YukiHookAPI.TAG, msg: String) = runCatching {
|
fun loggerD(tag: String = YukiHookAPI.debugTag, msg: String) = runCatching {
|
||||||
Log.d(tag, msg)
|
Log.d(tag, msg)
|
||||||
XposedBridge.log("[$tag][D]--> $msg")
|
XposedBridge.log("[$tag][D]--> $msg")
|
||||||
}
|
}
|
||||||
@@ -50,13 +48,11 @@ fun loggerD(tag: String = YukiHookAPI.TAG, msg: String) = runCatching {
|
|||||||
/**
|
/**
|
||||||
* 向控制台和 [XposedBridge] 打印日志 - I
|
* 向控制台和 [XposedBridge] 打印日志 - I
|
||||||
*
|
*
|
||||||
* 你可以对此方法进行二次封装
|
|
||||||
*
|
|
||||||
* [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg]
|
* [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg]
|
||||||
* @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.TAG]
|
* @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.debugTag]
|
||||||
* @param msg 日志打印的内容
|
* @param msg 日志打印的内容
|
||||||
*/
|
*/
|
||||||
fun loggerI(tag: String = YukiHookAPI.TAG, msg: String) = runCatching {
|
fun loggerI(tag: String = YukiHookAPI.debugTag, msg: String) = runCatching {
|
||||||
Log.i(tag, msg)
|
Log.i(tag, msg)
|
||||||
XposedBridge.log("[$tag][I]--> $msg")
|
XposedBridge.log("[$tag][I]--> $msg")
|
||||||
}
|
}
|
||||||
@@ -64,13 +60,11 @@ fun loggerI(tag: String = YukiHookAPI.TAG, msg: String) = runCatching {
|
|||||||
/**
|
/**
|
||||||
* 向控制台和 [XposedBridge] 打印日志 - W
|
* 向控制台和 [XposedBridge] 打印日志 - W
|
||||||
*
|
*
|
||||||
* 你可以对此方法进行二次封装
|
|
||||||
*
|
|
||||||
* [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg]
|
* [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg]
|
||||||
* @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.TAG]
|
* @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.debugTag]
|
||||||
* @param msg 日志打印的内容
|
* @param msg 日志打印的内容
|
||||||
*/
|
*/
|
||||||
fun loggerW(tag: String = YukiHookAPI.TAG, msg: String) = runCatching {
|
fun loggerW(tag: String = YukiHookAPI.debugTag, msg: String) = runCatching {
|
||||||
Log.w(tag, msg)
|
Log.w(tag, msg)
|
||||||
XposedBridge.log("[$tag][W]--> $msg")
|
XposedBridge.log("[$tag][W]--> $msg")
|
||||||
}
|
}
|
||||||
@@ -78,14 +72,12 @@ fun loggerW(tag: String = YukiHookAPI.TAG, msg: String) = runCatching {
|
|||||||
/**
|
/**
|
||||||
* 向控制台和 [XposedBridge] 打印日志 - E
|
* 向控制台和 [XposedBridge] 打印日志 - E
|
||||||
*
|
*
|
||||||
* 你可以对此方法进行二次封装
|
|
||||||
*
|
|
||||||
* [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg]
|
* [XposedBridge] 中的日志打印风格为 [[tag]]「类型」--> [msg]
|
||||||
* @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.TAG]
|
* @param tag 日志打印的标签 - 建议和自己的模块名称设置成一样的 - 默认为 [YukiHookAPI.debugTag]
|
||||||
* @param msg 日志打印的内容
|
* @param msg 日志打印的内容
|
||||||
* @param e 可填入异常堆栈信息 - 将自动完整打印到控制台
|
* @param e 可填入异常堆栈信息 - 将自动完整打印到控制台
|
||||||
*/
|
*/
|
||||||
fun loggerE(tag: String = YukiHookAPI.TAG, msg: String, e: Throwable? = null) = runCatching {
|
fun loggerE(tag: String = YukiHookAPI.debugTag, msg: String, e: Throwable? = null) = runCatching {
|
||||||
Log.e(tag, msg, e)
|
Log.e(tag, msg, e)
|
||||||
XposedBridge.log("[$tag][E]--> $msg")
|
XposedBridge.log("[$tag][E]--> $msg")
|
||||||
e?.also { XposedBridge.log(it) }
|
e?.also { XposedBridge.log(it) }
|
||||||
|
@@ -89,6 +89,7 @@ open class PackageParam(
|
|||||||
/**
|
/**
|
||||||
* 赋值并克隆另一个 [PackageParam]
|
* 赋值并克隆另一个 [PackageParam]
|
||||||
* @param another 另一个 [PackageParam]
|
* @param another 另一个 [PackageParam]
|
||||||
|
* - 此方法为私有功能性 API - 你不应该手动调用此方法
|
||||||
*/
|
*/
|
||||||
@DoNotUseMethod
|
@DoNotUseMethod
|
||||||
internal fun baseAssignInstance(another: PackageParam) {
|
internal fun baseAssignInstance(another: PackageParam) {
|
||||||
|
@@ -35,7 +35,7 @@ import java.io.Serializable
|
|||||||
* 获得 [Any] 类型
|
* 获得 [Any] 类型
|
||||||
* @return [Class]
|
* @return [Class]
|
||||||
*/
|
*/
|
||||||
val AnyType get() = Any::class.java
|
val AnyType get() = Any::class.javaPrimitiveType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得 [Unit] 类型
|
* 获得 [Unit] 类型
|
||||||
@@ -47,7 +47,7 @@ val UnitType get() = Unit::class.javaPrimitiveType
|
|||||||
* 获得 [Boolean] 类型
|
* 获得 [Boolean] 类型
|
||||||
* @return [Class]
|
* @return [Class]
|
||||||
*/
|
*/
|
||||||
val BooleanType get() = Boolean::class.javaPrimitiveType
|
val BooleanType get() = Boolean::class.java
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得 [Int] 类型
|
* 获得 [Int] 类型
|
||||||
|
@@ -107,18 +107,8 @@ public class ReflectionUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Field findField(Class<?> clazz, String typeName, String fieldName) {
|
public static Field findFieldIfExists(Class<?> clazz, String typeName, String fieldName) throws NoSuchFieldException {
|
||||||
try {
|
String fullFieldName = "name:[" + fieldName + "] type:[" + typeName + "] in Class [" + clazz.getName() + "] by YukiHook#finder";
|
||||||
return findFieldIfExists(clazz, typeName, fieldName);
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
throw new IllegalArgumentException("Can't find field <" + clazz.getName() + "#" + typeName + "#" + fieldName + ">");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Field findFieldIfExists(Class<?> clazz, String typeName, String fieldName)
|
|
||||||
throws NoSuchFieldException {
|
|
||||||
String fullFieldName = clazz.getName() + "#" + fieldName + "#" + typeName;
|
|
||||||
|
|
||||||
if (!fieldCache.containsKey(fullFieldName)) {
|
if (!fieldCache.containsKey(fullFieldName)) {
|
||||||
if (clazz != null && !TextUtils.isEmpty(typeName) && !TextUtils.isEmpty(fieldName)) {
|
if (clazz != null && !TextUtils.isEmpty(typeName) && !TextUtils.isEmpty(fieldName)) {
|
||||||
Class<?> clz = clazz;
|
Class<?> clz = clazz;
|
||||||
@@ -134,7 +124,7 @@ public class ReflectionUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while ((clz = clz.getSuperclass()) != null);
|
} while ((clz = clz.getSuperclass()) != null);
|
||||||
throw new NoSuchFieldException(clazz.getName() + "#" + typeName + " " + fieldName);
|
throw new NoSuchFieldException("Can't find this field --> " + fullFieldName);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user