Skip to content

Getting stuck at debugger breakpoint when calling JNI methods #744

@nitanmarcel

Description

@nitanmarcel

Context

I'm trying to emulate a third-party native library (security/protection library) using unidbg. The library loads successfully, but when I call JNI methods on it, I get stuck at a debugger breakpoint.

Typing 'c' to continue just brings me back to the same breakpoint immediately. This creates an infinite loop and I can never get past this point.

Setup

  • Unidbg version: 0.9.8
  • Using Unicorn2Factory
  • Real third-party ARM64 library
  • Library loads successfully, issue is only with JNI method calls

Questions

  1. How can I disable these automatic breakpoints? I just want the method to execute normally.

  2. Why does 'c' (continue) not work? It should advance execution past the breakpoint.

  3. Is there a way to skip problematic functions? The init() method seems to be required for other methods to work.

  4. Are there alternative approaches? Different backends or configuration that avoid this issue?

What I've tried

  • Setting various system properties (no effect)
  • Different Unicorn2Factory parameters (no effect)
  • Not calling emulator.attach() (still breaks automatically)

Code

package com.example;

import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.arm.backend.Unicorn2Factory;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;

import java.io.File;

public class TestEmulator extends AbstractJni {
    
    private final AndroidEmulator emulator;
    private final VM vm;
    private final DvmClass targetClass;
    private final DvmObject<?> instance;

    public TestEmulator(String libraryPath) {
        try {
            emulator = AndroidEmulatorBuilder.for64Bit()
                .setProcessName("com.example.app")
                .addBackendFactory(Unicorn2Factory(true))
                .build();
            
            emulator.getMemory().setLibraryResolver(new AndroidResolver(28));
            
            vm = emulator.createDalvikVM();
            vm.setJni(this);
            vm.setVerbose(false);
            
            // Load real third-party library (e.g., security/protection lib)
            vm.loadLibrary(new File(libraryPath), false).callJNI_OnLoad(emulator);
            
            targetClass = vm.resolveClass("com/thirdparty/SecurityLib");
            instance = targetClass.newObject(null);
            
        } catch (Exception e) {
            throw new RuntimeException("Failed to initialize", e);
        }
    }
    
    // This method gets stuck at debugger breakpoint
   // In the original code this is also called in a separate thread.
    public void initSecurity() {
        System.out.println("Calling native initialization...");
        
        // This hits a persistent breakpoint that won't continue
        instance.callJniMethod(emulator, "init()V");
        
        System.out.println("Init completed");  // Never reaches here
    }
    
    // This method needs init() to be called first
    public String generateToken(String data) {
        DvmObject<String> result = instance.callJniMethodObject(emulator,
            "generateToken(Ljava/lang/String;)Ljava/lang/String;", data);
        return result.getValue();
    }
}

The library works fine in a real Android environment, but I can't get past this debugger issue in unidbg. Any help would be appreciated!

debugger break at: 0x120001060 @ Runnable|Function64 address=0x120001060, arguments=[unidbg@0xfffe1640, 1847362549]
>>> x0=0xfffe1640(-125376) x1=0x6e1a4375 x2=0x0 x3=0x0 x4=0x0 x5=0x0 x6=0x0 x7=0x0 x8=0x0 x9=0x0 x10=0x0 x11=0x0 x12=0x0 x13=0x0 x14=0x0
>>> x15=0x0 x16=0x0 x17=0x0 x18=0x0 x19=0x0 x20=0x0 x21=0x0 x22=0x0 x23=0x0 x24=0x0 x25=0x0 x26=0x0 x27=0x0 x28=0x0 fp=0x0
>>> q0=0x0(0.0) q1=0x0(0.0) q2=0x0(0.0) q3=0x0(0.0) q4=0x0(0.0) q5=0x0(0.0) q6=0x0(0.0) q7=0x0(0.0) q8=0x0(0.0) q9=0x0(0.0) q10=0x0(0.0) q11=0x0(0.0) q12=0x0(0.0) q13=0x0(0.0) q14=0x0(0.0) q15=0x0(0.0)
>>> q16=0x0(0.0) q17=0x0(0.0) q18=0x0(0.0) q19=0x0(0.0) q20=0x0(0.0) q21=0x0(0.0) q22=0x0(0.0) q23=0x0(0.0) q24=0x0(0.0) q25=0x0(0.0) q26=0x0(0.0) q27=0x0(0.0) q28=0x0(0.0) q29=0x0(0.0) q30=0x0(0.0) q31=0x0(0.0)
LR=unidbg@0x7ffff0000
SP=0xe4fff700
PC=RX@0x120001060[libsecurity.so]0x1060
nzcv: N=0, Z=1, C=0, V=0, EL0, use SP_EL0
Java_com_thirdparty_SecurityLib_init + 0x0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions