yukihook-extension-kavaref
This is an extended dependency for KavaRef-related features in YukiHook.
Configure Dependency
You can add this module to your project using the following method.
We recommend that you refer to yukihook-bom first to manage versions with BOM.
Version Catalog (Recommended)
Add dependency in your project's gradle/libs.versions.toml.
[versions]
yukihook-extension-kavaref = "<version>"
kavaref-bom = "<kavaref-version>"
[libraries]
yukihook-extension-kavaref = { module = "com.highcapable.yukihookapi:yukihook-extension-kavaref", version.ref = "yukihook-extension-kavaref" }
kavaref-bom = { module = "com.highcapable.kavaref:kavaref-bom", version.ref = "kavaref-bom" }
kavaref-core = { module = "com.highcapable.kavaref:kavaref-core" }
kavaref-android = { module = "com.highcapable.kavaref:kavaref-android" }
kavaref-extension = { module = "com.highcapable.kavaref:kavaref-extension" }Configure dependency in your project's build.gradle.kts.
implementation(libs.yukihook.extension.kavaref)
implementation(platform(libs.kavaref.bom))
implementation(libs.kavaref.core)
implementation(libs.kavaref.android)
implementation(libs.kavaref.extension)Please change <version> to the version displayed at the top of this document, and change <kavaref-version> to the latest version from here.
Traditional Method
Configure dependency in your project's build.gradle.kts.
implementation("com.highcapable.yukihookapi:yukihook-extension-kavaref:<version>")
implementation(platform("com.highcapable.kavaref:kavaref-bom:<kavaref-version>"))
implementation("com.highcapable.kavaref:kavaref-core")
implementation("com.highcapable.kavaref:kavaref-android")
implementation("com.highcapable.kavaref:kavaref-extension")Please change <version> to the version displayed at the top of this document, and change <kavaref-version> to the latest version from here.
Pay Attention
This module does not add the dependencies of KavaRef automatically, please add KavaRef yourself as shown above.
Function Introduction
You can view the KDoc click here.
This module provides KavaRef extensions that are used in PackageParam. For detailed usage, please refer to here, this will jump to the KavaRef documentation.
Pay Attention
These extensions can only be used in PackageParam. Since there are extensions with the same names in KavaRef, please make sure to import the corresponding functions under com.highcapable.yukihookapi.extension.kavaref.
Hook Usage
You can use hook, hookAll, intercept and interceptAll directly on KavaRef's MemberResolver.
The following example
loadApp("io.github.myapp") {
"$packageName.MainActivity".toClass()
.resolve()
.firstMethod {
name = "onCreate"
parameters(Bundle::class)
}.hook {
// Your code here.
}
}They are used in exactly the same way as on Member, for details please refer to Hook Usage.
You can also use deoptimize and deoptimizeAll, for details please refer to Deoptimize.
Tips
In Module Hot Reload → Retain Values, since a MemberResolver object strongly references the ClassLoader of the module, you cannot cache it directly.
In this case, you can take out its self and use it as below.
The following example
// A single method.
val foo = remember("myapp-foo-v1") {
"$packageName.Demo".toClass()
.resolve()
.optional()
.firstMethodOrNull {
name = "foo"
emptyParameters()
}?.self
}
// A group of methods.
val bar = remember("myapp-bar-v1") {
"$packageName.Demo".toClass()
.resolve()
.optional()
.method {
name = "bar"
parameterCount { it in 0..1 }
}.map { it.self }
}
foo?.hook {
// Your code here.
}
bar.hookAll {
// Your code here.
}Original and Special Calls
You can use KavaRef's MethodResolver and ConstructorResolver to call original methods and constructors without hooks.
The following example
loadApp("io.github.myapp") {
// Suppose this is the instance of the Demo class.
val instance: Any
"$packageName.Demo".toClass()
.resolve()
.firstMethod {
name = "foo"
emptyParameters()
}.of(instance).invokeOriginal()
}| Function | Description |
|---|---|
invokeOriginal | Calls the original method without hooks |
*invokeSpecial | Calls the method non-virtually, the instance must be set with of first |
initializeSpecial | Initializes an existing instance non-virtually with the constructor |
*createOriginal | Creates an instance with the original constructor without hooks |
*createSpecial | Creates a subclass instance with the parent constructor, the subclass constructor is not called |
All the functions above also provide a version with the Quietly suffix, which ignores exceptions during the call and returns null.
Pay Attention
The functions marked with * above require the yukihook-runtime-libxposed base module.
Load Classes from the Host
In PackageParam, the following extensions with the same names load the Class with hostClassLoader by default.
String.toClass()String.toClassOrNull()VariousClass.toClass()VariousClass.toClassOrNull()lazyClass(...)lazyClassOrNull(...)
The following example
val DemoClass by lazyClass("io.github.myapp.Demo")
loadApp("io.github.myapp") {
"$packageName.Demo".toClass()
VariousClass("$packageName.Demo", "$packageName.NewDemo").toClass()
}Hidden API Bypass Resolver
YukiHook provides AndroidHiddenApiBypassResolver, you can use it where you need to reflect hidden system APIs.
It is replicated from AndroidHiddenApiBypassResolver in the KavaRef documentation.
The following example
val resolver = AndroidHiddenApiBypassResolver()
"android.app.ActivityThread".toClass()
.resolve()
// Set a custom Member resolver.
.processor(resolver)
.firstMethod {
name = "currentActivityThread"
emptyParameters()
}.invoke()