Menu

How to develop plug-in modules

Module Plugin Usage Scenarios

Primarily used to inject custom code into specified applications in the cloud machine, allowing modifications to the Java layer or native layer.

Supported Features

Automatic injection of DEX files

Automatic injection of SO files

Built-in Java layer Hook framework: LspLant

Built-in native layer Hook framework: Dobby

Module Example Download

dplus_demo code
dplus_demo

Module Installation

Open the project in Android Studio. After compilation, obtain the module file app-debug.apk.

Upload this file to the cloud machine, for example, to the path /sdcard/Download/app-debug.apk.

Use the following commands for installation and viewing:

Copy
// First connect to the cloud machine
adb connect xx.xx.xx.xx

// Enter the cloud machine terminal
adb shell

// Then install the module
dplus install patch:/sdcard/Download/app-debug.apk

// After successful installation, view the module
dplus dump

// Uninstall and delete the module by module name
dplus uninstall dplus_demo

Module Development Introduction

The module source code structure is as shown in the figure below.

The config.json file is used to configure the module.

native-lib.cpp implements examples of Dobby hooks.

Entry.java serves as the entry point for Java layer hooks.

Config Configuration Explanation

This file is primarily used to describe the module and guide the injection process. Sample data is as follows:

Copy
{
    "name": "dplus_demo",   // Module name, used during uninstallation
    "package":"com.example.dplus_demo",  // Module package name
    "desc": "module",       // Module description
    "type": "user",         // Module type, mainly "system" or "user"
    "libs": "libdplus_demo.so",  // SO files to inject; can be omitted or configured with multiple entries separated by ';'
    "pattern": [
        "com.android.settings"   // Package names where the module takes effect
    ]
}

Dobby Example

The following demonstrates a simple hook on the openat function to output logs:

Copy
int (*source_openat)(int fd, const char *path, int oflag, int mode) = nullptr;

int MyOpenAt(int fd, const char *pathname, int flags, int mode) {
    LOGI("MyOpenAt  pathname %s",pathname);
    return source_openat(fd, pathname, flags, mode);
}

void HookOpenAt() {
    // Resolve function address
    void *__openat =
            DobbySymbolResolver("libc.so", "__openat");

    if (__openat == nullptr) {
        LOGI("__openat null ");
        return;
    }

    LOGI("Got __openat address ");
    
    // Replace original function with Dobby
    if (DobbyHook((void *) __openat,
                  (void *) MyOpenAt,
                  (void **) &source_openat) == 0) {
        LOGI("DobbyHook __openat success");
    }
}

jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {

    LOGI("Test JNI_OnLoad starting load");
    HookOpenAt();
    return JNI_VERSION_1_6;
}

Java Layer Example

The init function serves as an entry point after the application starts. Execute relevant logic here. The LspLant-related code has been slightly modified, so some classes and functions may not use their original names.

Copy
public class Entry {

    public String TAG="demo_Entry";

    public void init(Application app){
        DPLog.i(TAG,"enter init");
        LSPHelpers.findAndHookMethod("java.util.HashMap", app.getClassLoader(), "put",Object.class,Object.class, new LSP_MethodH() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);
                Log.i(TAG,"enter HashMap.put key:"+param.args[0]+",value:"+param.args[1]);
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
                Log.i(TAG,"leave HashMap.put");
            }
        });
    }

}

Effects After Module Injection

This module tests the Settings application. When the Settings app is closed and reopened, the relevant logs are as shown in the figure below.

Previous
How to Pass Google Verification
Last modified: 2025-10-20Powered by