mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 01:35:17 +08:00
...
This commit is contained in:
@@ -36,8 +36,8 @@ import com.highcapable.yukihookapi.YukiHookAPI.encase
|
||||
import com.highcapable.yukihookapi.annotation.DoNotUseMethod
|
||||
import com.highcapable.yukihookapi.hook.entity.YukiBaseHooker
|
||||
import com.highcapable.yukihookapi.hook.factory.processName
|
||||
import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper
|
||||
import com.highcapable.yukihookapi.hook.param.PackageParam
|
||||
import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper
|
||||
import com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus
|
||||
import de.robv.android.xposed.callbacks.XC_LoadPackage
|
||||
|
||||
@@ -100,7 +100,7 @@ object YukiHookAPI {
|
||||
/**
|
||||
* 装载 Xposed API 回调
|
||||
*
|
||||
* - 装载代码将自动生成 - 你不应该手动使用此方法装载 Xposed 模块事件
|
||||
* - ⚡装载代码将自动生成 - 你不应该手动使用此方法装载 Xposed 模块事件
|
||||
* @param lpparam Xposed [XC_LoadPackage.LoadPackageParam]
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
|
@@ -45,7 +45,7 @@ package com.highcapable.yukihookapi.annotation
|
||||
)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
/**
|
||||
* -️ 警告方法外部调用声明
|
||||
* -️ ⚡警告方法外部调用声明
|
||||
* 此方法除继承和接口外不应该在这里被调用
|
||||
* 如果调用此方法可能会出现错误或 APP 发生异常
|
||||
*/
|
||||
|
@@ -45,7 +45,7 @@ package com.highcapable.yukihookapi.annotation
|
||||
)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
/**
|
||||
* - 警告方法外部调用声明
|
||||
* - ⚡警告方法外部调用声明
|
||||
* 此方法除继承和接口外不应该在这里被调用
|
||||
* 如果调用此方法可能会出现错误或 APP 发生异常
|
||||
*/
|
||||
|
@@ -35,7 +35,7 @@ import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
||||
/**
|
||||
* 标识 YukiHook 注入 Xposed 入口的类注释
|
||||
*
|
||||
* - 你的项目 source 目录必须为 ../src/main/ 后方内容根据你自行喜好定义即可 - 否则编译会报错
|
||||
* - ⚡你的项目 source 目录必须为 ../src/main/ 后方内容根据你自行喜好定义即可 - 否则编译会报错
|
||||
*
|
||||
* - 你的 Hook 入口类(HookEntryClass) 需要按照此格式创建 --> 你的模块APP包名/hook/...可允许子包名存在.../你的入口类
|
||||
*
|
||||
@@ -49,7 +49,7 @@ import com.highcapable.yukihookapi.hook.xposed.proxy.YukiHookXposedInitProxy
|
||||
*
|
||||
* - 若你不喜欢这样创建类 - 没问题 - 请在 [YukiHookAPI.Configs.modulePackageName] 填写模块包名即可 - 但不按照规则定义包名你将会收到编译警告
|
||||
*
|
||||
* - 最后这一点很重要:请不要随意修改项目 ../src/main/assets/xposed_init 中的内容 - 否则可能会导致模块装载发生错误
|
||||
* - ⚡最后这一点很重要:请不要随意修改项目 ../src/main/assets/xposed_init 中的内容 - 否则可能会导致模块装载发生错误
|
||||
*
|
||||
* 你必须将被注释的类继承于 [YukiHookXposedInitProxy] 接口实现 [YukiHookXposedInitProxy.onHook] 方法 - 否则编译会报错
|
||||
*
|
||||
|
@@ -49,10 +49,15 @@ import java.lang.reflect.Member
|
||||
*
|
||||
* 这是一个 API 对接类 - 实现原生对接 [XposedBridge]
|
||||
* @param packageParam 需要传入 [PackageParam] 实现方法调用
|
||||
* @param hookClass 要 Hook 的 [Class]
|
||||
* @param hookClass 要 Hook 的 [Class] - 必须已使用当前 Hook APP 的 [ClassLoader] 装载
|
||||
*/
|
||||
class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Class<*>) {
|
||||
|
||||
/**
|
||||
* Hook 全部方法的标识
|
||||
*/
|
||||
enum class HookAllMembers { HOOK_ALL_METHODS, HOOK_ALL_CONSTRUCTORS, HOOK_NONE }
|
||||
|
||||
/** 设置要 Hook 的方法、构造类 */
|
||||
private var hookMembers = HashMap<String, MemberHookCreater>()
|
||||
|
||||
@@ -69,7 +74,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
||||
/**
|
||||
* Hook 执行入口
|
||||
*
|
||||
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* - ⚡此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @throws IllegalStateException 如果必要参数没有被设置
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
@@ -110,6 +115,12 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
||||
/** 标识是否已经设置了要 Hook 的 [member] */
|
||||
private var isHookMemberSetup = false
|
||||
|
||||
/** 是否 Hook 全部方法以及类型 */
|
||||
private var hookAllMembers = HookAllMembers.HOOK_NONE
|
||||
|
||||
/** 全部方法的名称 */
|
||||
private var allMethodsName = ""
|
||||
|
||||
/**
|
||||
* 手动指定要 Hook 的方法、构造类
|
||||
*
|
||||
@@ -117,6 +128,32 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
||||
*/
|
||||
var member: Member? = null
|
||||
|
||||
/**
|
||||
* Hook [hookClass] 中指定 [name] 的全部方法
|
||||
*
|
||||
* - ⚡警告:无法准确处理每个方法的返回值和 param - 建议使用 [method] 对每个方法单独 Hook
|
||||
*
|
||||
* - ⚡如果 [hookClass] 中没有方法可能会发生错误
|
||||
* @param name 方法名称
|
||||
*/
|
||||
fun allMethods(name: String) {
|
||||
allMethodsName = name
|
||||
hookAllMembers = HookAllMembers.HOOK_ALL_METHODS
|
||||
isHookMemberSetup = true
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook [hookClass] 中的全部构造方法
|
||||
*
|
||||
* - ⚡警告:无法准确处理每个构造方法的 param - 建议使用 [constructor] 对每个构造方法单独 Hook
|
||||
*
|
||||
* - ⚡如果 [hookClass] 中没有构造方法可能会发生错误
|
||||
*/
|
||||
fun allConstructors() {
|
||||
hookAllMembers = HookAllMembers.HOOK_ALL_CONSTRUCTORS
|
||||
isHookMemberSetup = true
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找需要 Hook 的方法
|
||||
*
|
||||
@@ -125,6 +162,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
||||
* @return [MethodFinder.Result]
|
||||
*/
|
||||
fun method(initiate: MethodFinder.() -> Unit): MethodFinder.Result {
|
||||
hookAllMembers = HookAllMembers.HOOK_NONE
|
||||
isHookMemberSetup = true
|
||||
return MethodFinder(hookInstance = this, hookClass).apply(initiate).build()
|
||||
}
|
||||
@@ -137,6 +175,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
||||
* @return [ConstructorFinder.Result]
|
||||
*/
|
||||
fun constructor(initiate: ConstructorFinder.() -> Unit): ConstructorFinder.Result {
|
||||
hookAllMembers = HookAllMembers.HOOK_NONE
|
||||
isHookMemberSetup = true
|
||||
return ConstructorFinder(hookInstance = this, hookClass).apply(initiate).build()
|
||||
}
|
||||
@@ -243,7 +282,7 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
||||
/**
|
||||
* Hook 创建入口
|
||||
*
|
||||
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* - ⚡此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @return [Result]
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
@@ -252,81 +291,103 @@ class YukiHookCreater(private val packageParam: PackageParam, val hookClass: Cla
|
||||
/**
|
||||
* Hook 执行入口
|
||||
*
|
||||
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* - ⚡此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
fun hook() {
|
||||
if (member != null)
|
||||
member.also { member ->
|
||||
runCatching {
|
||||
if (isReplaceHookMode)
|
||||
XposedBridge.hookMethod(member, object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(baseParam: MethodHookParam?): Any? {
|
||||
if (baseParam == null) return null
|
||||
return HookParam(baseParam).let { param ->
|
||||
try {
|
||||
if (replaceHookCallback != null)
|
||||
onHookLogMsg(msg = "Replace Hook Member [${member}] done [$tag]")
|
||||
replaceHookCallback?.invoke(param)
|
||||
} catch (e: Throwable) {
|
||||
onConductFailureCallback?.invoke(param, e)
|
||||
onAllFailureCallback?.invoke(e)
|
||||
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
||||
onHookFailureMsg(e)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
else
|
||||
XposedBridge.hookMethod(member, object : XC_MethodHook() {
|
||||
override fun beforeHookedMethod(baseParam: MethodHookParam?) {
|
||||
if (baseParam == null) return
|
||||
HookParam(baseParam).also { param ->
|
||||
runCatching {
|
||||
beforeHookCallback?.invoke(param)
|
||||
if (beforeHookCallback != null)
|
||||
onHookLogMsg(msg = "Before Hook Member [${member}] done [$tag]")
|
||||
}.onFailure {
|
||||
onConductFailureCallback?.invoke(param, it)
|
||||
onAllFailureCallback?.invoke(it)
|
||||
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
||||
onHookFailureMsg(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterHookedMethod(baseParam: MethodHookParam?) {
|
||||
if (baseParam == null) return
|
||||
HookParam(baseParam).also { param ->
|
||||
runCatching {
|
||||
afterHookCallback?.invoke(param)
|
||||
if (afterHookCallback != null)
|
||||
onHookLogMsg(msg = "After Hook Member [${member}] done [$tag]")
|
||||
}.onFailure {
|
||||
onConductFailureCallback?.invoke(param, it)
|
||||
onAllFailureCallback?.invoke(it)
|
||||
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
||||
onHookFailureMsg(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}.onFailure {
|
||||
onHookingFailureCallback?.invoke(it)
|
||||
onAllFailureCallback?.invoke(it)
|
||||
if (onHookingFailureCallback == null && onAllFailureCallback == null) onHookFailureMsg(it)
|
||||
/** 定义替换回调方法体 */
|
||||
val replaceMent = object : XC_MethodReplacement() {
|
||||
override fun replaceHookedMethod(baseParam: MethodHookParam?): Any? {
|
||||
if (baseParam == null) return null
|
||||
return HookParam(baseParam).let { param ->
|
||||
try {
|
||||
if (replaceHookCallback != null)
|
||||
onHookLogMsg(msg = "Replace Hook Member [${member}] done [$tag]")
|
||||
replaceHookCallback?.invoke(param)
|
||||
} catch (e: Throwable) {
|
||||
onConductFailureCallback?.invoke(param, e)
|
||||
onAllFailureCallback?.invoke(e)
|
||||
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
||||
onHookFailureMsg(e)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
onHookingFailureCallback?.invoke(Throwable())
|
||||
onAllFailureCallback?.invoke(Throwable())
|
||||
}
|
||||
|
||||
/** 定义前后 Hook 回调方法体 */
|
||||
val beforeAfterHook = object : XC_MethodHook() {
|
||||
override fun beforeHookedMethod(baseParam: MethodHookParam?) {
|
||||
if (baseParam == null) return
|
||||
HookParam(baseParam).also { param ->
|
||||
runCatching {
|
||||
beforeHookCallback?.invoke(param)
|
||||
if (beforeHookCallback != null)
|
||||
onHookLogMsg(msg = "Before Hook Member [${member}] done [$tag]")
|
||||
}.onFailure {
|
||||
onConductFailureCallback?.invoke(param, it)
|
||||
onAllFailureCallback?.invoke(it)
|
||||
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
||||
onHookFailureMsg(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterHookedMethod(baseParam: MethodHookParam?) {
|
||||
if (baseParam == null) return
|
||||
HookParam(baseParam).also { param ->
|
||||
runCatching {
|
||||
afterHookCallback?.invoke(param)
|
||||
if (afterHookCallback != null)
|
||||
onHookLogMsg(msg = "After Hook Member [${member}] done [$tag]")
|
||||
}.onFailure {
|
||||
onConductFailureCallback?.invoke(param, it)
|
||||
onAllFailureCallback?.invoke(it)
|
||||
if (onConductFailureCallback == null && onAllFailureCallback == null)
|
||||
onHookFailureMsg(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hookAllMembers == HookAllMembers.HOOK_NONE)
|
||||
if (member != null)
|
||||
member.also { member ->
|
||||
runCatching {
|
||||
if (isReplaceHookMode)
|
||||
XposedBridge.hookMethod(member, replaceMent)
|
||||
else XposedBridge.hookMethod(member, beforeAfterHook)
|
||||
}.onFailure {
|
||||
onHookingFailureCallback?.invoke(it)
|
||||
onAllFailureCallback?.invoke(it)
|
||||
if (onHookingFailureCallback == null && onAllFailureCallback == null) onHookFailureMsg(it)
|
||||
}
|
||||
}
|
||||
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]"
|
||||
)
|
||||
}
|
||||
else runCatching {
|
||||
when (hookAllMembers) {
|
||||
HookAllMembers.HOOK_ALL_METHODS ->
|
||||
if (isReplaceHookMode)
|
||||
XposedBridge.hookAllMethods(hookClass, allMethodsName, replaceMent)
|
||||
else XposedBridge.hookAllMethods(hookClass, allMethodsName, beforeAfterHook)
|
||||
HookAllMembers.HOOK_ALL_CONSTRUCTORS ->
|
||||
if (isReplaceHookMode)
|
||||
XposedBridge.hookAllConstructors(hookClass, replaceMent)
|
||||
else XposedBridge.hookAllConstructors(hookClass, beforeAfterHook)
|
||||
else -> error("Hooked got a no error possible")
|
||||
}
|
||||
}.onFailure {
|
||||
onAllFailureCallback?.invoke(it)
|
||||
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]"
|
||||
)
|
||||
loggerE(msg = "Hooked All Members with an error in Class [$hookClass] [$tag]")
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -52,9 +52,9 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
||||
/**
|
||||
* [Constructor] 参数
|
||||
*
|
||||
* - 无参 [Constructor] 不要使用此方法
|
||||
* - ⚡无参 [Constructor] 不要使用此方法
|
||||
*
|
||||
* - 有参 [Constructor] 必须使用此方法设定参数
|
||||
* - ⚡有参 [Constructor] 必须使用此方法设定参数
|
||||
* @param param 参数数组
|
||||
*/
|
||||
fun param(vararg param: Class<*>) {
|
||||
@@ -75,7 +75,7 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
||||
/**
|
||||
* 得到构造方法结果
|
||||
*
|
||||
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* - ⚡此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @return [Result]
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
@@ -123,7 +123,7 @@ class ConstructorFinder(private val hookInstance: YukiHookCreater.MemberHookCrea
|
||||
/**
|
||||
* 开始重查找
|
||||
*
|
||||
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* - ⚡此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
internal fun build() {
|
||||
|
@@ -51,21 +51,21 @@ class FieldFinder(private val hookInstance: YukiHookCreater.MemberHookCreater, p
|
||||
/**
|
||||
* [Field] 名称
|
||||
*
|
||||
* - 必须设置
|
||||
* - ⚡必须设置
|
||||
*/
|
||||
var name = ""
|
||||
|
||||
/**
|
||||
* [Field] 类型
|
||||
*
|
||||
* - 必须设置
|
||||
* - ⚡必须设置
|
||||
*/
|
||||
var type: Class<*>? = null
|
||||
|
||||
/**
|
||||
* 得到变量处理结果
|
||||
*
|
||||
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* - ⚡此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @return [Result]
|
||||
* @throws IllegalStateException 如果 [name] 没有被设置
|
||||
*/
|
||||
|
@@ -52,7 +52,7 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
||||
/**
|
||||
* [Method] 名称
|
||||
*
|
||||
* - 必须设置
|
||||
* - ⚡必须设置
|
||||
*/
|
||||
var name = ""
|
||||
|
||||
@@ -66,9 +66,9 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
||||
/**
|
||||
* [Method] 参数
|
||||
*
|
||||
* - 无参 [Method] 不要使用此方法
|
||||
* - ⚡无参 [Method] 不要使用此方法
|
||||
*
|
||||
* - 有参 [Method] 必须使用此方法设定参数
|
||||
* - ⚡有参 [Method] 必须使用此方法设定参数
|
||||
* @param param 参数数组
|
||||
*/
|
||||
fun param(vararg param: Class<*>) {
|
||||
@@ -90,7 +90,7 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
||||
/**
|
||||
* 得到方法结果
|
||||
*
|
||||
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* - ⚡此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* @return [Result]
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
@@ -141,7 +141,7 @@ class MethodFinder(private val hookInstance: YukiHookCreater.MemberHookCreater,
|
||||
/**
|
||||
* 开始重查找
|
||||
*
|
||||
* - 此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
* - ⚡此功能交由方法体自动完成 - 你不应该手动调用此方法
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
internal fun build() {
|
||||
|
@@ -73,7 +73,7 @@ abstract class YukiBaseHooker : PackageParam() {
|
||||
/**
|
||||
* 赋值并克隆一个 [PackageParam]
|
||||
*
|
||||
* - 此方法为私有功能性 API - 你不应该手动调用此方法
|
||||
* - ⚡此方法为私有功能性 API - 你不应该手动调用此方法
|
||||
* @param packageParam 需要使用的 [PackageParam]
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
|
@@ -77,8 +77,9 @@ open class PackageParam(private var baseParam: PackageParamWrapper? = null) {
|
||||
|
||||
/**
|
||||
* 赋值并克隆另一个 [PackageParam]
|
||||
*
|
||||
* - ⚡此方法为私有功能性 API - 你不应该手动调用此方法
|
||||
* @param another 另一个 [PackageParam]
|
||||
* - 此方法为私有功能性 API - 你不应该手动调用此方法
|
||||
*/
|
||||
@DoNotUseMethod
|
||||
internal fun baseAssignInstance(another: PackageParam) {
|
||||
@@ -105,7 +106,7 @@ open class PackageParam(private var baseParam: PackageParamWrapper? = null) {
|
||||
/**
|
||||
* 将目标 [Class] 绑定到 [appClassLoader]
|
||||
*
|
||||
* - 请注意未绑定到 [appClassLoader] 的 [Class] 不能被装载 - 调用 [hook] 方法会自动绑定
|
||||
* - ⚡请注意未绑定到 [appClassLoader] 的 [Class] 不能被装载 - 调用 [hook] 方法会自动绑定
|
||||
* @return [Class]
|
||||
* @throws NoClassDefFoundError 如果找不到类会报错
|
||||
*/
|
||||
|
@@ -36,7 +36,7 @@ import com.highcapable.yukihookapi.hook.factory.encase
|
||||
/**
|
||||
* YukiHook 的 Xposed 装载 API 调用接口
|
||||
*
|
||||
* - 请在此类上添加注释 [InjectYukiHookWithXposed] 标记模块 Hook 入口
|
||||
* - ⚡请在此类上添加注释 [InjectYukiHookWithXposed] 标记模块 Hook 入口
|
||||
*
|
||||
* Hook 开始时将自动调用 [onHook] 方法
|
||||
*
|
||||
|
Reference in New Issue
Block a user