LSPosed / LSPlant

A hook framework for Android Runtime (ART)
https://lsposed.org/LSPlant/
GNU Lesser General Public License v3.0
814 stars 203 forks source link
android hook

LSPlant

LSPlant is an Android ART hook library, providing Java method hook/unhook and inline deoptimization.

This project is part of LSPosed framework under GNU Lesser General Public License.

Features

Documentation

https://lsposed.org/LSPlant/namespacelsplant.html

Quick Start

repositories {
    mavenCentral()
}

android {
    buildFeatures {
        prefab true
    }
}

dependencies {
    implementation "org.lsposed.lsplant:lsplant:+"
}

If you don't want to include libc++_shared.so in your APK, you can use lsplant-standalone instead:

dependencies {
    implementation "org.lsposed.lsplant:lsplant-standalone:+"
}

1. Init LSPlant within JNI_OnLoad

Initialize LSPlant for the proceeding hook. It mainly prefetch needed symbols and hook some functions.

bool Init(JNIEnv *env,
          const InitInfo &info);

Returns whether initialization succeed. Behavior is undefined if calling other LSPlant interfaces before initialization or after a fail initialization.

2. Hook

Hook a Java method by providing the target_method together with the context object hooker_object and its callback callback_method.

jobject Hook(JNIEnv *env,
             jobject target_method,
             jobject hooker_object,
             jobject callback_method);

Returns the backup method. You can invoke it by reflection to invoke the original method. null if fails.

This function will automatically generate a stub class for hook. To help debug, you can set the generated class name, its field name, its source name and its method name by setting generated_* in InitInfo.

This function thread safe (you can call it simultaneously from multiple thread) but it's not atomic to the same target_method. That means UnHook or IsUnhook does not guarantee to work properly on the same target_method before it returns. Also, simultaneously call on this function with the same target_method does not guarantee only one will success. If you call this with different hooker_object on the same target_method simultaneously, the behavior is undefined.

3. Check

Check if a Java function is hooked by LSPlant or not.

bool IsHooked(JNIEnv *env,
              jobject method);

Returns whether the method is hooked.

4. Unhook

Unhook a Java function that is previously hooked.

bool UnHook(JNIEnv *env,
            jobject target_method);

Returns whether the unhook succeed.

Calling backup (the return method of Hook()) after unhooking is undefined behavior. Please read Hook()'s note for more details.

5. Deoptimize

Deoptimize a method to avoid hooked callee not being called because of inline.

bool Deoptimize(JNIEnv *env,
                jobject method);

Returns whether the deoptimizing succeed or not.

It is safe to call deoptimizing on a hooked method because the deoptimization will perform on the backup method instead.

Credits

Inspired by the following frameworks: