Skip to content

yukihook-extension-kavaref ​

Maven CentralMaven metadata URLAndroid Min SDK

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.

Add dependency in your project's gradle/libs.versions.toml.

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.

kotlin
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.

kotlin
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

kotlin
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

kotlin
// 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

kotlin
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()
}
FunctionDescription
invokeOriginalCalls the original method without hooks
*invokeSpecialCalls the method non-virtually, the instance must be set with of first
initializeSpecialInitializes an existing instance non-virtually with the constructor
*createOriginalCreates an instance with the original constructor without hooks
*createSpecialCreates 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

kotlin
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

kotlin
val resolver = AndroidHiddenApiBypassResolver()

"android.app.ActivityThread".toClass()
    .resolve()
    // Set a custom Member resolver.
    .processor(resolver)
    .firstMethod {
        name = "currentActivityThread"
        emptyParameters()
    }.invoke()

Released under the Apache-2.0 License