Yes, you can call Java methods (non-native) from a class resolved using vm.resolveClass()
in unidbg, as long as the method exists in the APK's DEX file and is not marked native
.
DvmClassclazz = vm.resolveClass("Lcom/example/MyClass;"); DvmObject<?> result = clazz.callStaticJniMethodObject(emulator, "getValue()Ljava/lang/String;"); System.out.println("Result: " + result.getValue());
For instance methods:
DvmObject<?> instance = clazz.newObject(null); DvmObject<?> result = instance.callJniMethodObject(emulator, "sayHello()Ljava/lang/String;");
The method must not be native
It must exist in the APK's DEX file
You need to use the correct JNI signature (e.g. ()Ljava/lang/String;
)
If the method uses Android system APIs, you may need to override or mock behavior via the JNI interface.
Assumptions:
You have an APK with a class: com.example.MyClass
Inside that class, there’s a static method:
Example Code
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.arm.backend.BackendFactory;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.dvm.*;
import java.io.File;
public class CallJavaMethod {
public static void main(String[] args) {
// Create emulator instance
AndroidEmulator emulator = AndroidEmulatorBuilder.for32Bit()
.setProcessName("com.example")
.addBackendFactory(BackendFactory.create(false)) // disable Unicorn logging
.build();
// Create Dalvik VM
File apkFile = new File("path/to/your.apk"); // Replace with real APK path
DalvikVM vm = emulator.createDalvikVM(apkFile);
vm.setVerbose(true); // Optional: logs method calls
// Load class from DEX
DvmClass clazz = vm.resolveClass("Lcom/example/MyClass;");
// Call static method: public static String getGreeting()
DvmObject<?> result = clazz.callStaticJniMethodObject(emulator, "getGreeting()Ljava/lang/String;");
// Print result
System.out.println("Returned: " + result.getValue());
emulator.close();
}
}