Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
unidbg — Permet d'émuler une bibliothèque native Android, ainsi qu'une émulation iOS expérimentale. | Kitploit
Outils/GitHubGitHub/zhkl0228/unidbg
Sécurité AndroidAnalyse Dynamique (Sandboxing)Sécurité iOSRétro-ingénierieDébogueursAnalyse de BinairesApprentissage et ÉducationRétro-Ingénierie Assistée par IA
GitHubzhkl0228/unidbg

unidbg

Permet d'émuler une bibliothèque native Android, ainsi qu'une émulation iOS expérimentale.

Voir le dépôt
5.1k1.2kil y a 13 joursVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

unidbg

Permet d'émuler une bibliothèque native Android, ainsi qu'une émulation iOS expérimentale.

Ceci est un projet pédagogique pour en apprendre davantage sur les formats de fichiers ELF/MachO et l'assembleur ARM.

À utiliser à vos risques et périls !

Fonctionnalités

  • Prise en charge de MCP (Model Context Protocol) pour le débogage assisté par IA avec Cursor et d'autres outils d'IA.
  • Émulation de l'API JNI Invocation afin que JNI_OnLoad puisse être appelé.
  • Prise en charge de JavaVM, JNIEnv.
  • Émulation de l'instruction syscalls.
  • Prise en charge d'ARM32 et ARM64.
  • Hook inline, grâce à Dobby.
  • Hook des imports Android, grâce à xHook.
  • Hooks iOS fishhook, substrate et whale.
  • Backend unicorn avec débogueur console simple, stub gdb, trace d'instructions, trace de lectures/écritures mémoire.
  • Prise en charge du runtime iOS objc et swift.
  • Prise en charge du backend rapide dynarmic.
  • Prise en charge de l'hyperviseur Apple M1, le backend ARM64 le plus rapide.
  • Prise en charge du backend Linux KVM avec Raspberry Pi B4.
  • Détection de fuites mémoire pour le code natif émulé avec backtrace invitée et trace de pile hôte.

Débogueur MCP (Intégration IA)

unidbg prend en charge le Model Context Protocol (MCP) pour le débogage assisté par IA. Lorsque le débogueur est actif, tapez mcp dans la console pour démarrer un serveur MCP auquel les outils d'IA (ex. Cursor) peuvent se connecter.

Démarrage rapide

Le MCP d'unidbg a deux modes de fonctionnement :

Mode 1 : Débogage par point d'arrêt — Attachez le débogueur et exécutez votre code. Lorsqu'un point d'arrêt est atteint, Breaker.debug() met l'émulateur en pause — tapez mcp dans la console pour démarrer le serveur MCP et laisser l'IA vous assister dans l'analyse. Tous les outils de débogage sont disponibles (registres, mémoire, désassemblage, pas à pas, traçage, etc.). Après la reprise, si un autre point d'arrêt est atteint, le débogueur se remet en pause. Une fois l'exécution terminée sans atteindre de point d'arrêt, le processus se termine et le MCP s'arrête.

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

Mode 2 : Outils personnalisés (réutilisables) — Utilisez McpToolkit pour enregistrer des outils personnalisés et laisser l'IA réexécuter les fonctions cibles avec différents paramètres. La bibliothèque native est chargée une seule fois ; après chaque exécution, le processus reste actif et le MCP demeure disponible pour l'exécution suivante.

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());

Lorsque le débogueur s'arrête, tapez mcp (ou mcp 9239 pour spécifier le port) dans la console. Ajoutez ensuite aux paramètres MCP de Cursor :

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

Outils MCP disponibles

Statut et informations

Registres et désassemblage

Mémoire

Points d'arrêt et exécution

Traçage

OutilDescription
trace_codeTracer les instructions avec les valeurs de lecture/écriture des registres (regs_read, prev_write)
trace_read / trace_writeTracer les lectures/écritures mémoire dans une plage d'adresses

Appels de fonctions

OutilDescription
call_functionAppeler une fonction native par adresse avec des arguments typés (hex, chaîne, octets, null). Renvoie la valeur avec résolution de symboles et aperçu mémoire
call_symbolAppeler une fonction exportée par module + nom de symbole, ex. libc.so + malloc

iOS uniquement (disponible lorsque Family=iOS)

Outils MCP personnalisés

Utilisez McpToolkit pour enregistrer des outils personnalisés, chacun implémentant l'interface McpTool. Cela remplace la répartition manuelle if-else par des classes d'outils propres et autonomes. À ce stade, la bibliothèque native est entièrement chargée (JNI_OnLoad / point d'entrée déjà exécutés), donc le code dans le execute() de chaque outil correspond à la logique de la fonction cible à analyser. L'IA peut définir des points d'arrêt et des traces avant de déclencher un outil personnalisé, puis inspecter les résultats d'exécution avec différentes entrées sans redémarrer le processus.

Exemple Android — Voir Utilities64.java pour un exemple JNI Android avec des outils MCP personnalisés :

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());

Exemple iOS — Voir IpaLoaderTest.java pour un exemple de chargement d'IPA iOS avec des outils MCP personnalisés :

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());

Une fois le serveur MCP démarré, l'IA peut appeler ces outils via MCP pour exécuter des émulations avec des paramètres personnalisés, définir des points d'arrêt, tracer l'exécution et inspecter les résultats — le tout sans redémarrer le processus.

API de bas niveau : Vous pouvez également utiliser Debugger.addMcpTool() + Debugger.run(DebugRunnable) directement pour un contrôle total. McpToolkit est une surcouche de plus haut niveau qui élimine la répartition if-else.

Détection de fuites mémoire

Suivez les allocations mémoire côté invité (mmap/munmap/brk) pour détecter les fuites dans le code natif émulé. Utilisez try-with-resources — le suivi démarre à la création, et le rapport de fuites est imprimé automatiquement à la fermeture.

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

Chaque bloc fuyé inclut une backtrace ARM invitée (module+offset+symbole) et une trace de pile Java hôte. Exemple de sortie :

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)
  ...

Vous pouvez également accéder au rapport par programmation avant la fermeture :

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 d'objets thread-safe pour réutiliser des instances d'émulateur sur plusieurs threads, évitant ainsi la surcharge d'une initialisation répétée.

  • Initialisation paresseuse — Les workers ne sont créés à la demande que lorsque le pool est vide, pas à l'avance.
  • Limite maximale — Le nombre total de workers vivants (empruntés + inactifs) ne dépasse jamais le maximum configuré.
  • Nettoyage des inactifs — Les workers inactifs plus longtemps que le délai d'expiration (10 minutes par défaut) sont automatiquement détruits par le thread de gestion.
  • Inactifs minimaux — Un nombre minimal de workers (1 par défaut) est toujours maintenu en vie, même inactif.

1. Implémenter 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. Créer le pool, emprunter et fermer

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

Voir TTEncryptWorker.java pour un exemple complet.

Exemples

Tests simples sous le répertoire src/test :

  • TTEncrypt.java


  • JniDispatch32.java

  • JniDispatch64.java

  • Utilities32.java

  • Utilities64.java

Autres tests :

  • QDReaderJni.java
  • SignUtil.java

Licence

  • unidbg utilise des bibliothèques logicielles de l'Apache Software Foundation.

Remerciements

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

Évolution du nombre d'étoiles

Stargazers over time

Télécharger l’outil
OutilDescription
check_connectionStatut de l'émulateur : famille, architecture, capacités du backend, isRunning, modules chargés
list_modules / get_module_infoLister les modules chargés, obtenir les détails incluant le nombre de symboles exportés et les dépendances
list_exportsLister les symboles exportés/dynamiques d'un module avec filtre optionnel et démangling C++
find_symbolTrouver un symbole par nom ou trouver le symbole le plus proche d'une adresse
get_threadsLister tous les threads/tâches de l'émulateur
OutilDescription
get_registers / get_register / set_registerLire/écrire les registres CPU
disassembleDésassembler les instructions à une adresse (les cibles de branchement sont automatiquement annotées avec les noms de symboles)
assembleAssembler le texte d'une instruction en code machine
get_callstackObtenir la pile d'appels actuelle (backtrace)
OutilDescription
read_memory / write_memoryLire/écrire des octets mémoire bruts
read_string / read_std_stringLire une chaîne C ou une std::string C++ (avec détection SSO)
read_pointerLire une chaîne de pointeurs avec résolution de symboles
read_typedLire la mémoire sous forme de valeurs typées (int8–int64, float, double, pointeur)
search_memoryRechercher des motifs d'octets en mémoire avec filtres de portée/permissions
list_memory_mapLister tous les mappings mémoire avec leurs permissions
allocate_memory / free_memory / list_allocationsAllouer (malloc/mmap) avec données initiales optionnelles, libérer et suivre les blocs mémoire
patchÉcrire des instructions assemblées en mémoire
OutilDescription
add_breakpoint / add_breakpoint_by_symbol / add_breakpoint_by_offsetAjouter des points d'arrêt par adresse, symbole ou module+offset
remove_breakpoint / list_breakpointsSupprimer ou lister les points d'arrêt (avec désassemblage)
continue_executionReprendre l'exécution. Utilisez poll_events pour attendre breakpoint_hit ou execution_completed
step_over / step_into / step_outPas à pas au-dessus, à l'intérieur (N instructions) ou à l'extérieur d'une fonction
next_blockS'arrêter au prochain bloc de base (Unicorn uniquement)
step_until_mnemonicS'arrêter à la prochaine instruction correspondant au mnémonique, ex. bl, ret (Unicorn uniquement)
poll_eventsInterroger les événements breakpoint_hit, execution_completed, trace
OutilDescription
inspect_objc_msgInspecter un appel objc_msgSend : afficher le nom de la classe du récepteur et le sélecteur, ex. -[NSString length]
get_objc_class_nameObtenir le nom de classe ObjC d'un objet à une adresse donnée (pur parsing mémoire, sans changement d'état)
dump_objc_classExtraire la définition d'une classe ObjC (propriétés, méthodes, protocoles, ivars)
dump_gpb_protobufExtraire le schéma d'un message protobuf GPB au format .proto (64 bits uniquement)