Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
unidbg — Permite emular una librería nativa de Android, y una emulación experimental de iOS. | Kitploit
Herramientas/GitHubGitHub/zhkl0228/unidbg
Seguridad AndroidAnálisis Dinámico (Sandboxing)Seguridad iOSIngeniería InversaDepuradoresAnálisis de BinariosAprendizaje y EducaciónReversing Asistido por IA
GitHubzhkl0228/unidbg

unidbg

Permite emular una librería nativa de Android, y una emulación experimental de iOS.

Ver Repositorio
5.1k1.2khace 14 díasRevisado por Kitploit

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

unidbg

Permite emular una librería nativa de Android, además de una emulación experimental de iOS.

Este es un proyecto educativo para aprender más sobre el formato de archivo ELF/MachO y el ensamblador ARM.

¡Úsalo bajo tu propio riesgo!

Características

  • Soporte de MCP (Model Context Protocol) para depuración asistida por IA con Cursor y otras herramientas de IA.
  • Emulación de la API de invocación JNI para que se pueda llamar a JNI_OnLoad.
  • Soporta JavaVM y JNIEnv.
  • Emulación de la instrucción syscalls.
  • Soporta ARM32 y ARM64.
  • Hook en línea, gracias a Dobby.
  • Hook de importaciones de Android, gracias a xHook.
  • Hooks de iOS con fishhook, substrate y whale.
  • El backend unicorn admite un depurador de consola simple, stub de gdb, traza de instrucciones y traza de lectura/escritura de memoria.
  • Soporta el runtime de objc y swift de iOS.
  • Soporta el backend rápido dynarmic.
  • Soporta el hipervisor de Apple M1, el backend ARM64 más rápido.
  • Soporta el backend Linux KVM con Raspberry Pi B4.
  • Detección de fugas de memoria para código nativo emulado con backtrace del invitado y stack trace del anfitrión.

Depurador MCP (Integración con IA)

unidbg es compatible con Model Context Protocol (MCP) para la depuración asistida por IA. Cuando el depurador está activo, escribe mcp en la consola para iniciar un servidor MCP al que las herramientas de IA (p. ej., Cursor) puedan conectarse.

Inicio rápido

El MCP de unidbg tiene dos modos de funcionamiento:

Modo 1: Depuración con puntos de interrupción — Adjunta el depurador y ejecuta tu código. Cuando se alcanza un punto de interrupción, Breaker.debug() pausa el emulador: escribe mcp en la consola para iniciar el servidor MCP y deja que la IA ayude con el análisis. Todas las herramientas de depuración están disponibles (registros, memoria, desensamblado, ejecución paso a paso, trazado, etc.). Tras reanudar, si se alcanza otro punto de interrupción, el depurador se pausa de nuevo. Cuando la ejecución finaliza sin alcanzar ningún punto de interrupción, el proceso termina y MCP se cierra.

root@kitploit:~
Debugger debugger = emulator.attach();
debugger.addBreakPoint(address);
// run your emulation logic — debugger pauses when breakpoint is hit

Modo 2: Herramientas personalizadas (repetibles) — Usa McpToolkit para registrar herramientas personalizadas y deja que la IA vuelva a ejecutar las funciones objetivo con diferentes parámetros. La librería nativa se carga una sola vez; después de cada ejecución, el proceso permanece vivo y MCP sigue activo para la siguiente ejecución.

root@kitploit:~
McpToolkit toolkit = new McpToolkit();
toolkit.addTool(new McpTool() {
    @Override public String name() { return "encrypt"; }
    @Override public String description() { return "Run encryption"; }
    @Override public String[] paramNames() { return new String[]{"input"}; }
    @Override public void execute(String[] params) {
        String input = params.length > 0 ? params[0] : "default";
        // call encryption with input
    }
});
toolkit.run(emulator.attach());

Cuando el depurador se detenga, escribe mcp (o mcp 9239 para especificar el puerto) en la consola. A continuación, añádelo a la configuración de MCP de Cursor:

root@kitploit:~
{
  "mcpServers": {
    "unidbg-mcp-server": {
      "url": "http://localhost:9239/sse"
    }
  }
}

Herramientas MCP disponibles

Estado e información

Registros y desensamblado

Memoria

Puntos de interrupción y ejecución

Trazado

HerramientaDescripción
trace_codeTraza instrucciones con valores de lectura/escritura de registros (regs_read, prev_write)
trace_read / trace_writeTraza lecturas/escrituras de memoria en un rango de direcciones

Llamadas a funciones

HerramientaDescripción
call_functionLlama a una función nativa por dirección con argumentos tipados (hex, string, bytes, null). Devuelve el valor con resolución de símbolos y vista previa de memoria
call_symbolLlama a una función exportada por módulo + nombre de símbolo, p. ej. libc.so + malloc

Solo iOS (disponible cuando Family=iOS)

Herramientas MCP personalizadas

Usa McpToolkit para registrar herramientas personalizadas, cada una de las cuales implementa la interfaz McpTool. Esto sustituye el despacho manual if-else por clases de herramientas limpias y autocontenidas. En este punto, la librería nativa está completamente cargada (JNI_OnLoad / punto de entrada ya ejecutado), por lo que el código dentro del execute() de cada herramienta es la lógica de la función objetivo que se va a analizar. La IA puede establecer puntos de interrupción y trazas antes de invocar una herramienta personalizada y, a continuación, inspeccionar los resultados de la ejecución con diferentes entradas sin reiniciar el proceso.

Ejemplo de Android — Consulta Utilities64.java para ver un ejemplo de JNI de Android con herramientas MCP personalizadas:

root@kitploit:~
DalvikModule dm = vm.loadLibrary(new File("libtmessages.29.so"), true);
dm.callJNI_OnLoad(emulator);
cUtilities = vm.resolveClass("org/telegram/messenger/Utilities");

McpToolkit toolkit = new McpToolkit();
toolkit.addTool(new McpTool() {
    @Override public String name() { return "aesCbc"; }
    @Override public String description() { return "Run AES-CBC encryption on input data"; }
    @Override public String[] paramNames() { return new String[]{"input"}; }
    @Override public void execute(String[] params) {
        byte[] input = params.length > 0 ? params[0].getBytes() : new byte[16];
        aesCbcEncryptionByteArray(input);
    }
});
toolkit.addTool(new McpTool() {
    @Override public String name() { return "aesCtr"; }
    @Override public String description() { return "Run AES-CTR decryption on input data"; }
    @Override public String[] paramNames() { return new String[]{"input"}; }
    @Override public void execute(String[] params) {
        byte[] input = params.length > 0 ? params[0].getBytes() : new byte[16];
        aesCtrDecryptionByteArray(input);
    }
});
toolkit.addTool(new McpTool() {
    @Override public String name() { return "pbkdf2"; }
    @Override public String description() { return "Run PBKDF2 key derivation"; }
    @Override public String[] paramNames() { return new String[]{"password", "iterations"}; }
    @Override public void execute(String[] params) {
        String password = params.length > 0 ? params[0] : "123456";
        int iterations = params.length > 1 ? Integer.parseInt(params[1]) : 100000;
        pbkdf2(password.getBytes(), iterations);
    }
});
toolkit.run(emulator.attach());

Ejemplo de iOS — Consulta IpaLoaderTest.java para ver un ejemplo de carga de IPA en iOS con herramientas MCP personalizadas:

root@kitploit:~
IpaLoader ipaLoader = new IpaLoader64(ipa, new File("target/rootfs/ipa"));
LoadedIpa loader = ipaLoader.load(this);
emulator = loader.getEmulator();
loader.callEntry();
module = loader.getExecutable();

McpToolkit toolkit = new McpToolkit();
toolkit.addTool(new McpTool() {
    @Override public String name() { return "dumpClass"; }
    @Override public String description() { return "Dump an ObjC class definition by name"; }
    @Override public String[] paramNames() { return new String[]{"className"}; }
    @Override public void execute(String[] params) {
        String className = params.length > 0 ? params[0] : "AppDelegate";
        IClassDumper classDumper = ClassDumper.getInstance(emulator);
        System.out.println("dumpClass(" + className + "):\n" + classDumper.dumpClass(className));
    }
});
toolkit.addTool(new McpTool() {
    @Override public String name() { return "readVersion"; }
    @Override public String description() { return "Read the TelegramCoreVersionString from the executable"; }
    @Override public void execute(String[] params) {
        Symbol sym = module.findSymbolByName("_TelegramCoreVersionString");
        if (sym != null) {
            Pointer pointer = UnidbgPointer.pointer(emulator, sym.getAddress());
            if (pointer != null) {
                System.out.println("_TelegramCoreVersionString=" + pointer.getString(0));
            }
        }
    }
});
toolkit.run(emulator.attach());

Una vez iniciado el servidor MCP, la IA puede llamar a estas herramientas mediante MCP para ejecutar emulaciones con parámetros personalizados, establecer puntos de interrupción, trazar la ejecución e inspeccionar los resultados, todo ello sin reiniciar el proceso.

API de bajo nivel: También puedes usar Debugger.addMcpTool() + Debugger.run(DebugRunnable) directamente para tener un control total. McpToolkit es un envoltorio de alto nivel que elimina el despacho if-else.

Detección de fugas de memoria

Realiza el seguimiento de las asignaciones de memoria del lado del invitado (mmap/munmap/brk) para detectar fugas en código nativo emulado. Usa try-with-resources: el seguimiento comienza con la creación y el informe de fugas se imprime automáticamente al cerrar.

root@kitploit:~
try (MemoryTracker tracker = emulator.traceMemoryLeaks()) {
    module.callFunction(emulator, "targetFunction", arg1, arg2);
}

Cada bloque con fuga incluye el backtrace ARM del invitado (module+offset+symbol) y el stack trace Java del anfitrión. Salida de ejemplo:

root@kitploit:~
=== Memory Leak Report ===
Tracking duration: 42ms
Total allocations: 5
Total deallocations: 3
Leaked blocks: 2
Total leaked size: 32768 bytes (32.0 KB)

--- Leak #1 ---
Address: 0x40001000, Size: 16384 (16.0 KB), Perms: rw-
Guest Backtrace:
  #0 0x40123456 libexample.so+0x3456 (malloc+0x12)
  #1 0x40124000 libexample.so+0x4000 (doSomething+0x48)
Host Stack Trace:
  com.github.unidbg.linux.AndroidElfLoader.mmap2(AndroidElfLoader.java:785)
  ...

También puedes acceder al informe mediante programación antes de cerrar:

root@kitploit:~
try (MemoryTracker tracker = emulator.traceMemoryLeaks()) {
    module.callFunction(emulator, "targetFunction", arg1, arg2);
    List<AllocationRecord> leaks = tracker.getLeaks();
    assert leaks.isEmpty() : "Memory leak detected!";
}

Pool de workers

Un pool de objetos seguro para hilos que reutiliza instancias del emulador en múltiples hilos, evitando la sobrecarga de la inicialización repetida.

  • Inicialización diferida — Los workers se crean bajo demanda solo cuando el pool está vacío, no por adelantado.
  • Límite máximo — El total de workers vivos (prestados + inactivos) nunca supera el máximo configurado.
  • Limpieza de inactivos — Los workers inactivos durante más tiempo que el timeout (10 minutos por defecto) se destruyen automáticamente mediante el hilo de gestión.
  • Mínimo de inactivos — Siempre se mantiene vivo un número mínimo de workers (1 por defecto), incluso cuando están inactivos.

1. Implementa un Worker

root@kitploit:~
public class MyWorker implements Worker {
    private final AndroidEmulator emulator;

    public MyWorker() {
        emulator = AndroidEmulatorBuilder.for64Bit().build();
        // load .so, call JNI_OnLoad, etc.
    }

    @Override
    public void destroy() {
        emulator.close();
    }

    public byte[] doWork(byte[] input) {
        // call native methods and return the result
    }
}

2. Crea el pool, toma prestado y cierra

root@kitploit:~
// Create a worker pool (max = CPU cores, lazy-initialized)
WorkerPool pool = WorkerPoolFactory.create(MyWorker::new);
// Or specify max workers explicitly
// WorkerPool pool = WorkerPoolFactory.create(MyWorker::new, 4);

// Optional: customize idle timeout (default 10 minutes, minimum 1 minute)
pool.setIdleTimeout(30); // idle workers destroyed after 30 minutes
// Optional: customize minimum kept-alive workers (default 1, minimum 1)
pool.setMinIdle(2); // always keep at least 2 workers alive
// Optional: pre-create workers eagerly (default 0, fully lazy)
pool.setInitialSize(4); // eagerly create 4 workers on startup

// Concurrent invocation from multiple threads
ExecutorService executor = Executors.newFixedThreadPool(100);
for (int i = 0; i < 100; i++) {
    executor.submit(() -> {
        try (WorkerLoan<MyWorker> loan = pool.borrow(1, TimeUnit.MINUTES)) {
            if (loan != null) {
                byte[] result = loan.get().doWork(input);
            }
        } // worker is automatically returned to the pool
    });
}

executor.shutdown();
executor.awaitTermination(10, TimeUnit.MINUTES);
pool.close(); // destroy all workers and release resources

Consulta TTEncryptWorker.java para ver un ejemplo completo.

Ejemplos

Pruebas sencillas en el directorio src/test:

  • TTEncrypt.java


  • JniDispatch32.java

  • JniDispatch64.java

  • Utilities32.java

  • Utilities64.java

Más pruebas:

  • QDReaderJni.java
  • SignUtil.java

Licencia

  • unidbg utiliza librerías de software de Apache Software Foundation.

Agradecimientos

  • unicorn
  • dynarmic
  • HookZz
  • xHook
  • AndroidNativeEmu
  • usercorn
  • keystone
  • capstone
  • idaemu
  • jelf
  • whale
  • kaitai_struct
  • fishhook
  • runtime_class-dump
  • mman-win32

Stargazers a lo largo del tiempo

Stargazers over time

Descargar herramienta
HerramientaDescripción
check_connectionEstado del emulador: Family, arquitectura, capacidades del backend, isRunning, módulos cargados
list_modules / get_module_infoLista los módulos cargados y obtén detalles, incluidos el número de símbolos exportados y las dependencias
list_exportsLista los símbolos exportados/dinámicos de un módulo con filtro opcional y demangling de C++
find_symbolBusca un símbolo por nombre o el símbolo más cercano a una dirección
get_threadsLista todos los hilos/tareas del emulador
HerramientaDescripción
get_registers / get_register / set_registerLee/escribe registros de la CPU
disassembleDesensambla instrucciones en una dirección (los destinos de salto se anotan automáticamente con nombres de símbolos)
assembleEnsambla texto de instrucción en código máquina
get_callstackObtén la pila de llamadas actual (backtrace)
HerramientaDescripción
read_memory / write_memoryLee/escribe bytes de memoria en bruto
read_string / read_std_stringLee una cadena C o un std::string de C++ (con detección de SSO)
read_pointerLee la cadena de punteros con resolución de símbolos
read_typedLee memoria como valores tipados (int8–int64, float, double, puntero)
search_memoryBusca en la memoria patrones de bytes con filtros de alcance/permisos
list_memory_mapLista todos los mapeos de memoria con permisos
allocate_memory / free_memory / list_allocationsAsigna (malloc/mmap) con datos iniciales opcionales, libera y realiza el seguimiento de los bloques de memoria
patchEscribe instrucciones ensambladas en memoria
HerramientaDescripción
add_breakpoint / add_breakpoint_by_symbol / add_breakpoint_by_offsetAñade puntos de interrupción por dirección, símbolo o módulo+offset
remove_breakpoint / list_breakpointsElimina o lista puntos de interrupción (con desensamblado)
continue_executionReanuda la ejecución. Usa poll_events para esperar breakpoint_hit o execution_completed
step_over / step_into / step_outPaso por encima, paso hacia dentro (N instrucciones) o paso fuera de una función
next_blockPausa en el siguiente bloque básico (solo Unicorn)
step_until_mnemonicPausa en la siguiente instrucción que coincida con el mnemónico, p. ej. bl, ret (solo Unicorn)
poll_eventsConsulta eventos como breakpoint_hit, execution_completed y trace events
HerramientaDescripción
inspect_objc_msgInspecciona la llamada objc_msgSend: muestra el nombre de la clase receptora y el selector, p. ej. -[NSString length]
get_objc_class_nameObtén el nombre de la clase ObjC de un objeto en una dirección determinada (análisis de memoria puro, sin cambio de estado)
dump_objc_classVuelca la definición de la clase ObjC (propiedades, métodos, protocolos, ivars)
dump_gpb_protobufVuelca el esquema de mensaje GPB protobuf en formato .proto (solo 64 bits)