mirror of
https://github.com/HighCapable/YukiHookAPI.git
synced 2025-09-04 09:45:19 +08:00
Merge document file
This commit is contained in:
@@ -22,9 +22,9 @@
|
||||
|
||||
- [点击这里](https://fankes.github.io/YukiHookAPI) 前往文档页面查看更多详细教程和内容。
|
||||
|
||||
> 你或许可能会遇到浏览器缓存造成文档不是最新版本的问题,若已经查看过一次文档,请手动在每个页面上刷新,以获取最新版本或清除浏览器缓存。
|
||||
> 你大概率会遇到浏览器缓存造成文档不是最新版本的问题,若已经查看过一次文档,请手动在每个页面上刷新一次以同步最新版本,或清除浏览器缓存。
|
||||
|
||||
最新版本更新时间:2022-04-15 04:57
|
||||
最新版本更新时间:2022-04-15 14:56
|
||||
|
||||
## Contacts
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
- 方便移植 快速上手
|
||||
|
||||
<font size=3 style="opacity: 0.6">`更新时间 2022-04-15 04:57`</font>
|
||||
<font size=3 style="opacity: 0.6">`更新时间 2022-04-15 14:56`</font>
|
||||
|
||||
[GitHub](https://github.com/fankes/YukiHookAPI)
|
||||
[Get Started](#介绍)
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* [快速开始](guide/quick-start)
|
||||
* [用法示例](guide/example)
|
||||
* [特色功能](guide/special-feature)
|
||||
* [从 Xposed API 迁移](guide/move-to-new-api)
|
||||
|
||||
* 配置
|
||||
* [API 基本配置](config/api-example)
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* [快速开始](guide/quick-start)
|
||||
* [用法示例](guide/example)
|
||||
* [特色功能](guide/special-feature)
|
||||
* [从 Xposed API 迁移](guide/move-to-new-api)
|
||||
|
||||
* 配置
|
||||
* [API 基本配置](config/api-example)
|
||||
|
@@ -359,17 +359,38 @@ method {
|
||||
|
||||
<b>异常原因</b>
|
||||
|
||||
使用 `ModuleApplication` 时调用了 `appContext` 功能但是 APP 可能已经被销毁或没有正确启动。
|
||||
> 第一种情况
|
||||
|
||||
在被 Hook 的宿主内调用了 `ModuleApplication` 的 `appContext`。
|
||||
|
||||
> 示例如下
|
||||
|
||||
```kotlin
|
||||
encase {
|
||||
// 调用了此变量
|
||||
ModuleApplication.appContext...
|
||||
}
|
||||
```
|
||||
|
||||
> 第二种情况
|
||||
|
||||
使用 `ModuleApplication` 时调用了 `appContext` 但是 APP 可能已经被销毁或没有正确启动。
|
||||
|
||||
> 示例如下
|
||||
|
||||
```kotlin
|
||||
// 调用了此变量但是 APP 可能已被销毁或没有正确启动
|
||||
ModuleApplication.appContext
|
||||
ModuleApplication.appContext...
|
||||
```
|
||||
|
||||
<b>解决方案</b>
|
||||
|
||||
> 第一种情况
|
||||
|
||||
你只能在模块内使用 `ModuleApplication` 的 `appContext`,在宿主内请使用 `PackageParam` 中的 `appContext`,请确认你使用的是否正确。
|
||||
|
||||
> 第二种情况
|
||||
|
||||
这种情况基本不存在,由于 `appContext` 是在 `onCreate` 中被赋值的,除非遇到多进程并发启动或 APP 没有启动完成前被反射调用了父类的 `onCreate` 方法。
|
||||
|
||||
!> `IllegalStateException` YukiHookModulePrefs not allowed in Custom Hook API
|
||||
|
@@ -8,18 +8,18 @@
|
||||
|
||||
## Proguard
|
||||
|
||||
> 如果你仍然在使用 `Proguard`,你需要做一些规则配置。
|
||||
> ~~如果你仍然在使用 `Proguard`,你需要做一些规则配置。~~
|
||||
|
||||
在 `proguard-rules.pro` 添加如下代码即可。
|
||||
~~在 `proguard-rules.pro` 添加如下代码即可。~~
|
||||
|
||||
> 示例如下
|
||||
> ~~示例如下~~
|
||||
|
||||
```proguard
|
||||
-keep class com.highcapable.yukihookapi.hook.xposed.YukiHookModuleStatus {*;}
|
||||
-keep class 这里填你的 HookEntryClass 入口类完整包名_YukiHookXposedInit {*;}
|
||||
```
|
||||
|
||||
!> 自从 Android Gradle Plugin 4.2 后,拥有 Android Jetpack 套件最新版本的混淆处理程序默认均为 `R8`,基本可以不需要考虑混淆的问题。
|
||||
!> Proguard 规则已被弃用,请不要再使用,自从 Android Gradle Plugin 4.2 后,拥有 Android Jetpack 套件最新版本的混淆处理程序默认均为 `R8`,基本可以不需要考虑混淆的问题。
|
||||
|
||||
若要在任何版本下启用 `R8`,请在 `gradle.properties` 文件中加入如下规则,Android Gradle Plugin 7.0 及以上版本无需任何配置。
|
||||
|
||||
|
221
docs/guide/move-to-new-api.md
Normal file
221
docs/guide/move-to-new-api.md
Normal file
@@ -0,0 +1,221 @@
|
||||
# 从 Xposed API 迁移
|
||||
|
||||
> 若你熟悉 Xposed API,你可以参考下方的相同点将自己的 API 快速迁移到 `YukiHookAPI`。
|
||||
|
||||
## 迁移 Hook 入口点
|
||||
|
||||
> 从 `XC_LoadPackage.LoadPackageParam` 迁移至 `PackageParam`。
|
||||
|
||||
`YukiHookAPI` 对 `PackageParam` 实现了 `lambda` 方法体 `this` 用法,在 `encase` 方法体内即可全局得到 `PackageParam` 对象。
|
||||
|
||||
> API 功能差异对比如下
|
||||
|
||||
<!-- tabs:start -->
|
||||
|
||||
#### **Yuki Hook API**
|
||||
|
||||
```kotlin
|
||||
override fun onHook() = encase {
|
||||
// 得到当前 Hook 的包名
|
||||
packageName
|
||||
// 得到当前 Hook 的 ApplicationInfo
|
||||
appInfo
|
||||
// 得到宿主 Application 生命周期
|
||||
appContext
|
||||
// 创建 Hook
|
||||
findClass("com.demo.Test").hook {
|
||||
injectMember {
|
||||
method {
|
||||
name = "test"
|
||||
param(BooleanType)
|
||||
}
|
||||
afterHook {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### **Xposed API**
|
||||
|
||||
```kotlin
|
||||
override fun handleLoadPackage(lpparam: XC_LoadPackage.LoadPackageParam) {
|
||||
// 得到当前 Hook 的包名
|
||||
lpparam.packageName
|
||||
// 得到当前 Hook 的 ApplicationInfo
|
||||
lpparam.applicationInfo
|
||||
// 得到宿主 Application 生命周期
|
||||
AndroidAppHelper.currentApplication()
|
||||
// 创建 Hook
|
||||
XposedHelpers.findAndHookMethod("com.demo.Test", lpparam.classLoader, "test", Boolean::class.java, object : XC_MethodHook() {
|
||||
override fun afterHookedMethod(param: MethodHookParam) {
|
||||
// ...
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
<!-- tabs:end -->
|
||||
|
||||
## 迁移 Hook 方法体
|
||||
|
||||
> 从 `XC_MethodHook.MethodHookParam` 迁移至 `HookParam`。
|
||||
|
||||
### Before/After Hook
|
||||
|
||||
`YukiHookAPI` 同样对 `HookParam` 实现了 `lambda` 方法体 `this` 用法,在 `beforeHook`、`afterHook` 等方法体内即可全局得到 `HookParam` 对象。
|
||||
|
||||
> API 功能差异对比如下
|
||||
|
||||
<!-- tabs:start -->
|
||||
|
||||
#### **Yuki Hook API**
|
||||
|
||||
```kotlin
|
||||
afterHook {
|
||||
// 得到当前 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()
|
||||
// 执行未经 Hook 的原始方法
|
||||
method.invokeOriginal(...)
|
||||
}
|
||||
```
|
||||
|
||||
#### **Xposed API**
|
||||
|
||||
```kotlin
|
||||
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
|
||||
// 执行未经 Hook 的原始方法
|
||||
XposedBridge.invokeOriginalMethod(param.method, param.thisObject, ...)
|
||||
}
|
||||
```
|
||||
|
||||
<!-- tabs:end -->
|
||||
|
||||
### Replace Hook
|
||||
|
||||
`replaceHook` 方法比较特殊,`YukiHookAPI` 为它做出了多种形式以供选择。
|
||||
|
||||
> API 功能差异对比如下
|
||||
|
||||
<!-- tabs:start -->
|
||||
|
||||
#### **Yuki Hook API**
|
||||
|
||||
无返回值的方法 `void`。
|
||||
|
||||
```kotlin
|
||||
replaceUnit {
|
||||
// 直接在这里实现被替换的逻辑
|
||||
}
|
||||
```
|
||||
|
||||
有返回值的方法。
|
||||
|
||||
```kotlin
|
||||
replaceAny {
|
||||
// 在这里实现被替换的逻辑
|
||||
// ...
|
||||
// 需要返回方法对应的返回值,无需写 return,只需将参数放到最后一位
|
||||
// 假设这个方法的返回值是 Int,我们只需要保证最后一位是我们需要的返回值即可
|
||||
0
|
||||
}
|
||||
```
|
||||
|
||||
有些方法我们只需替换其返回值,则有如下实现。
|
||||
|
||||
```kotlin
|
||||
// 替换为你需要的返回值
|
||||
replaceTo(...)
|
||||
// 替换为 Boolean 类型的返回值
|
||||
replaceToTrue()
|
||||
// 拦截返回值
|
||||
intercept()
|
||||
```
|
||||
|
||||
!> 直接替换返回值的方法传入的参数是固定不变的,若想实现动态替换返回值请使用 `replaceAny` 方法体。
|
||||
|
||||
#### **Xposed API**
|
||||
|
||||
无返回值的方法 `void`。
|
||||
|
||||
```kotlin
|
||||
override fun replaceHookedMethod(param: MethodHookParam): Any? {
|
||||
// 直接在这里实现被替换的逻辑
|
||||
return null
|
||||
}
|
||||
```
|
||||
|
||||
有返回值的方法。
|
||||
|
||||
```kotlin
|
||||
override fun replaceHookedMethod(param: MethodHookParam): Int {
|
||||
// 在这里实现被替换的逻辑
|
||||
// ...
|
||||
// 假设这个方法的返回值是 Int
|
||||
return 0
|
||||
}
|
||||
```
|
||||
|
||||
有些方法我们只需替换其返回值,则有如下实现。
|
||||
|
||||
```kotlin
|
||||
// 替换为你需要的返回值
|
||||
override fun replaceHookedMethod(param: MethodHookParam) = ...
|
||||
// 替换为 Boolean 类型的返回值
|
||||
override fun replaceHookedMethod(param: MethodHookParam) = true
|
||||
// 拦截返回值
|
||||
override fun replaceHookedMethod(param: MethodHookParam) = null
|
||||
```
|
||||
|
||||
<!-- tabs:end -->
|
||||
|
||||
## 迁移其它功能
|
||||
|
||||
`YukiHookAPI` 对 Xposed API 进行了完全重写,你可以参考 [API 文档](api/home) 以及 [特色功能](guide/special-feature) 来决定一些功能性的迁移和使用。
|
@@ -112,6 +112,8 @@ class MainHook : YukiHookXposedInitProxy {
|
||||
|
||||
有关作为 Xposed 模块使用的相关配置详细内容,你可以 [点击这里](config/xposed-using) 继续阅读。
|
||||
|
||||
若你目前正在使用 Xposed API,你可以参考 [从 Xposed API 迁移](guide/move-to-new-api)。
|
||||
|
||||
## 作为 Hook API 使用
|
||||
|
||||
### 集成方式
|
||||
|
Reference in New Issue
Block a user