从其它 Hook API 迁移
此文档可以帮助你快速从你熟悉的 Hook API 迁移到 YukiHookAPI
来熟悉对 YukiHookAPI
的相关写法。
Rovo89 Xposed API
若你熟悉 Rovo89 Xposed API,你可以参考下方的相同点将自己的 API 快速迁移到
YukiHookAPI
。
迁移 Hook 入口点
从
XC_LoadPackage.LoadPackageParam
迁移至PackageParam
。
YukiHookAPI
对 PackageParam
实现了 lambda 方法体 this
用法,在 encase
方法体内即可全局得到 PackageParam
对象。
API 功能差异对比如下
override fun onHook() = encase {
// 得到当前 Hook 的包名
packageName
// 得到当前 Hook 的 ApplicationInfo
appInfo
// 得到系统上下文对象
systemContext
// 得到宿主 Application 生命周期
appContext
// Hook 指定的 APP
loadApp(name = "com.demo.test") {
// Member Hook
"com.demo.test.TestClass".toClass()
.method {
name = "test"
param(BooleanType)
}.hook {
after {
// ...
}
}
// Resources Hook (固定用法)
resources().hook {
injectResource {
conditions {
name = "ic_launcher"
mipmap()
}
replaceToModuleResource(R.mipmap.ic_launcher)
}
}
}
}
private lateinit var moduleResources: XModuleResources
override fun initZygote(sparam: IXposedHookZygoteInit.StartupParam) {
moduleResources = XModuleResources.createInstance(sparam.modulePath, null)
}
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
// 得到当前 Hook 的包名
lpparam.packageName
// 得到当前 Hook 的 ApplicationInfo
lpparam.applicationInfo
// 得到系统上下文对象
// 在 Rovo89 Xposed API 中没有现成的调用方法,你需要自行反射 ActivityThread 来实现
// 得到宿主 Application 生命周期
AndroidAppHelper.currentApplication()
// Class Hook
if(lpparam.packageName == "com.demo.test")
XposedHelpers.findAndHookMethod(
"com.demo.test.TestClass", lpparam.classLoader,
"test", Boolean::class.java,
object : XC_MethodHook() {
override fun afterHookedMethod(param: MethodHookParam) {
// ...
}
}
)
}
override fun handleInitPackageResources(resparam: XC_InitPackageResources.InitPackageResourcesParam) {
// 得到当前 Hook 的包名
resparam.packageName
// Resources Hook
resparam.res.setReplacement(
"com.demo.test", "mipmap","ic_launcher",
moduleResources.fwd(R.mipmap.ic_launcher)
)
}
迁移 Hook 方法体
从
XC_MethodHook.MethodHookParam
迁移至HookParam
。
Before/After Hook
YukiHookAPI
同样对 HookParam
实现了 lambda 方法体 this
用法,在 before
、after
等方法体内即可全局得到 HookParam
对象。
API 功能差异对比如下
after {
// 得到当前 Hook 的实例
instance
// 得到当前 Hook 的 Class 实例
instanceClass
// 得到并 cast 当前 Hook 的实例为指定类型 T
instance<T>()
// 得到方法参数数组
args
// 得到方法参数的第一位 T
args().first().cast<T>()
// 得到方法参数的最后一位 T
args().last().cast<T>()
// 得到方法参数的任意下标 T,这里用 2 举例
args(index = 2).cast<T>()
// 设置方法参数的任意下标,这里用 2 举例
args(index = 2).set(...)
// 得到返回值
result
// 得到返回值并 cast 为 T
result<T>()
// 修改返回值内容
result = ...
// 删除返回值内容
resultNull()
// 获取当前回调方法体范围内的数据存储实例
dataExtra
// 向 Hook APP 抛出异常
Throwable("Fatal").throwToApp()
// 执行未经 Hook 的原始方法并使用原始方法参数调用,泛型可略
callOriginal<Any?>()
// 执行未经 Hook 的原始方法并自定义方法参数调用,泛型可略
invokeOriginal<Any?>(...)
}
override fun afterHookedMethod(param: MethodHookParam) {
// 得到当前 Hook 的实例
param.thisObject
// 得到当前 Hook 的 Class 实例
param.thisObject.javaClass
// 得到并 cast 当前 Hook 的实例为指定类型 T
param.thisObject as T
// 得到方法参数数组
param.args
// 得到方法参数的第一位 T
param.args[0] as T
// 得到方法参数的最后一位 T
param.args[param.args.lastIndex] as T
// 得到方法参数的任意下标 T,这里用 2 举例
param.args[2] as T
// 设置方法参数的任意下标,这里用 2 举例
param.args[2] = ...
// 得到返回值
param.result
// 得到返回值并 cast 为 T
param.result as T
// 修改返回值内容
param.result = ...
// 删除返回值内容
param.result = null
// 获取当前回调方法体范围内的数据存储实例
param.extra
// 向 Hook APP 抛出异常
param.throwable = Throwable("Fatal")
// 执行未经 Hook 的原始方法
XposedBridge.invokeOriginalMethod(param.method, param.thisObject, ...)
}
Replace Hook
replaceHook
方法比较特殊,YukiHookAPI
为它做出了多种形式以供选择。
API 功能差异对比如下
/// 无返回值的方法 void
replaceUnit {
// 直接在这里实现被替换的逻辑
}
/// 有返回值的方法
replaceAny {
// 在这里实现被替换的逻辑
// ...
// 需要返回方法对应的返回值,无需写 return,只需将参数放到最后一位
// 假设这个方法的返回值是 Int,我们只需要保证最后一位是我们需要的返回值即可
0
}
/// 有些方法我们只需替换其返回值,则有如下实现
/// 需要注意的是:直接替换返回值的方法传入的参数是固定不变的,若想实现动态替换返回值请使用上面的 replaceAny 方法体
// 替换为你需要的返回值
replaceTo(...)
// 替换为 Boolean 类型的返回值
replaceToTrue()
// 拦截返回值
intercept()
/// 无返回值的方法 void
override fun replaceHookedMethod(param: MethodHookParam): Any? {
// 直接在这里实现被替换的逻辑
return null
}
/// 有返回值的方法
override fun replaceHookedMethod(param: MethodHookParam): Int {
// 在这里实现被替换的逻辑
// ...
// 假设这个方法的返回值是 Int
return 0
}
/// 有些方法我们只需替换其返回值,则有如下实现
// 替换为你需要的返回值
override fun replaceHookedMethod(param: MethodHookParam) = ...
// 替换为 Boolean 类型的返回值
override fun replaceHookedMethod(param: MethodHookParam) = true
// 拦截返回值
override fun replaceHookedMethod(param: MethodHookParam) = null
迁移更多有关 Hook API 的功能
YukiHookAPI
是一套全新的 Hook API,与其它 Hook API 存在着本质区别,你可以参考 API 文档 以及 特色功能 来决定一些功能性的迁移和使用。