- LLM4Decompile est un projet open source de grands modèles de langage qui ramène des binaires Linux x86_64, aux niveaux d’optimisation GCC O0 à O3, vers du code source C lisible par un humain
- L’approche consiste à convertir le binaire en assembleur avec Objdump, puis à laisser le LLM le décompiler en code C ; une famille LLM4Decompile-Ref est aussi proposée pour affiner le pseudocode produit par Ghidra
- Les modèles sont publiés dans des tailles allant de 1.3B à 22B, et llm4decompile-9b-v2 atteint un taux de réexécutabilité de 64,9 % sur le benchmark Decompile
- La métrique d’évaluation est le taux de réexécutabilité, qui vérifie si le code décompilé s’exécute correctement en passant des tests prédéfinis ; les benchmarks utilisés sont HumanEval-Decompile, avec 164 fonctions C, et ExeBench, avec 2 621 fonctions
- En 2025, le projet a publié decompile-bench et SK²Decompile, et continue de s’étendre avec l’objectif de couvrir davantage d’architectures, de configurations et d’intégrations avec des outils de décompilation
Objectif et périmètre de LLM4Decompile
- LLM4Decompile est un projet open source de grands modèles de langage spécialisé dans la décompilation
- La version actuelle décompile des binaires Linux x86_64 vers du code source C lisible par un humain, pour les niveaux d’optimisation GCC O0 à O3
- Le projet est en cours d’extension pour prendre en charge un éventail plus large d’architectures et de configurations
- Il existe deux principaux modes d’utilisation
- LLM4Decompile-End : une famille de modèles qui décompilent directement les binaires
- LLM4Decompile-Ref : une famille de modèles qui affinent, avec un LLM, le pseudocode décompilé par Ghidra
Flux d’apprentissage et d’évaluation de la décompilation
- Le processus de compilation part du code source C, puis passe par le prétraitement, la compilation, l’assemblage et l’édition de liens pour générer un exécutable
- La décompilation suit ce processus en sens inverse, en reconvertissant le code binaire en fichier source
- Comme les LLM ne peuvent pas traiter directement les données binaires, le binaire doit d’abord être désassemblé en langage assembleur avec Objdump
- Le README explique que le binaire et l’ASM désassemblé sont considérés comme équivalents, puisqu’ils peuvent être convertis l’un vers l’autre
- Lors de l’apprentissage, la perte est calculée entre le code décompilé et le code source original ; lors de l’évaluation, la fonctionnalité est vérifiée en contrôlant le passage des assertions de test
Métriques d’évaluation et benchmarks
- La métrique clé est la Re-executability
- Elle vérifie si le code décompilé s’exécute correctement
- Elle évalue si tous les cas de test prédéfinis sont réussis
- HumanEval-Decompile est un ensemble de 164 fonctions C qui ne dépendent que de la bibliothèque standard C
- ExeBench est un ensemble de 2 621 fonctions issues de projets réels
- Il inclut des fonctions définies par l’utilisateur, des structures et des macros
Modèles publiés et performances
- LLM4Decompile inclut des modèles de 1.3B à 33B paramètres, publiés sur Hugging Face
- Les taux de réexécutabilité des principaux modèles sont les suivants
- llm4decompile-1.3b-v1.5 : 1.3B, 27,3 %
- llm4decompile-6.7b-v1.5 : 6.7B, 45,4 %
- llm4decompile-1.3b-v2 : 1.3B, 46,0 %
- llm4decompile-6.7b-v2 : 6.7B, 52,7 %
- llm4decompile-9b-v2 : 9B, 64,9 %
- llm4decompile-22b-v2 : 22B, 63,6 %
- La série V1.5 a été entraînée sur un jeu de données plus volumineux de 15B tokens, avec une longueur maximale de 4 096 tokens, et indique une amélioration des performances de plus de 100 % par rapport aux modèles précédents
- La série V2 repose sur Ghidra et a été entraînée sur 2B tokens pour affiner le pseudocode de décompilation produit par Ghidra
- Le 22B-V2 indique des performances supérieures de 40,1 % supplémentaires à celles du 6.7B-V1.5
Publications récentes
- Le 4 octobre 2025, SK²Decompile a été publié
- La 1re étape, Structure Recovery, c’est-à-dire l’étape Skeleton, transforme un binaire ou un pseudocode en une représentation intermédiaire obfusquée
- La 2e étape, Identifier Naming, c’est-à-dire l’étape Skin, génère un code source lisible par un humain avec des identifiants significatifs
- Liens des modèles : sk2decompile-struct-6.7b, sk2decompile-ident-6.7
- Le 20 mai 2025, decompile-bench a été publié
- Inclut 2 millions de paires fonction binaire-source pour l’apprentissage
- Inclut 70 000 paires de fonctions pour l’évaluation
- Les détails se trouvent dans le dossier decompile-bench
- Le 17 octobre 2024, decompile-ghidra-100k a été publié
- Inclut 100 000 échantillons d’apprentissage au total, soit 25 000 pour chaque niveau d’optimisation
- Fournit un script d’apprentissage qui s’exécute en environ 3,5 heures sur un seul GPU A100 40G
- Le coût d’une reproduction rapide est inférieur à 20 dollars au total, avec un taux de réexécutabilité de 0,26
- Le 23 septembre 2024, LLM4Decompile-9B-v2 a été publié
- Fine-tuné à partir de Yi-Coder-9B
- Atteint un taux de réexécutabilité de 0,6494 sur le benchmark Decompile
Flux d’utilisation
- Le démarrage rapide consiste à cloner le dépôt, créer un environnement Conda et installer
requirements.txt - L’étape de prétraitement compile le code C en binaire avec GCC, puis extrait les instructions assembleur avec
objdump -d - Le nom de fonction doit être remplacé par le nom de la fonction à décompiler, au lieu de
func0dans l’exemple - L’assembleur d’entrée est attendu sous la forme suivante
<FUNCTION_NAME>:- Puis plusieurs lignes d’instructions assembleur
- L’étape de décompilation charge le modèle Hugging Face avec
AutoTokenizeretAutoModelForCausalLMdetransformers, puis génère du code C à partir du prompt assembleur - L’utilisation de Docker est également possible
- Après avoir construit l’image, le conteneur est exécuté avec les options GPU
- Un flux est fourni pour exécuter
demo.pydans le répertoireghidra
Format des données HumanEval-Decompile
- Les données HumanEval-Decompile sont stockées sous forme de liste JSON dans
llm4decompile/decompile-eval/decompile-eval-executable-gcc-obj.json - Le nombre d’échantillons est de 164*4, soit 164 fonctions multipliées par les niveaux d’optimisation O0, O1, O2 et O3
- Chaque échantillon comporte 5 clés
task_id: ID du problèmetype: niveau d’optimisation parmi O0, O1, O2 ou O3c_func: solution C du problème HumanEvalc_test: assertions de test en Cinput_asm_prompt: instructions assembleur et prompt
- Le script d’évaluation se trouve dans le dossier evaluation
Travaux en cours et licence
- Les travaux en cours incluent des jeux de données d’apprentissage plus volumineux et un processus de nettoyage, la prise en charge de langages, plateformes et configurations populaires, la prise en charge des exécutables, ainsi que l’intégration avec des outils de décompilation comme Ghidra et Rizin
- Les jeux de données d’apprentissage plus volumineux et la prise en charge des exécutables sont indiqués comme terminés le 13 mai 2024
- Le dépôt de code est placé sous MIT License et DeepSeek License
- L’article est disponible sur arXiv:2403.05286, et le projet fournit aussi des ressources Colab et YouTube
1 commentaires
Avis de Hacker News
L’idée est intéressante, mais je me demande si les résultats seront fiables.
Si on recompile, on peut obtenir un autre code machine, ce qui rend difficile l’identification des hallucinations, et je crains surtout des échecs silencieux dans de nouvelles structures qui pourraient être au cœur du code.
Je me demande s’il existe, en mode génératif, une façon pour le LLM de rapporter aussi son niveau de confiance sur certaines sections ; au final, une vérification humaine restera probablement nécessaire.
Après avoir décompilé un binaire en source, puis recompilé ce source en binaire, on devrait retrouver le binaire original, et il suffit d’itérer jusqu’à ce que la perte descende à un niveau acceptable.
L’apprentissage par renforcement convient très bien à ce genre de problème et il est d’ailleurs connu pour être anormalement efficace dans ce type de cas.
Cela peut être une expérience pour explorer le mème actuel du « utilisons juste un LLM », mais l’argument le plus fort contre est que les décompilateurs existants font déjà mieux avec beaucoup moins de calcul.
Ensuite, l’outil de vérification peut confirmer que le résultat est correct selon la preuve fournie par le LLM.
Bien sûr, construire et entraîner un LLM capable de produire de telles preuves serait le plus gros défi, mais cela pourrait être une façon sûre de détecter les hallucinations.
Il suffit donc de ne recompiler que ces quelques fonctions.
Si l’on connaît les développeurs qui ont créé une application, il serait intéressant de voir si l’on peut entraîner un module de décompilation en utilisant leur ancien code comme données d’apprentissage.
Par exemple, Super Mario 64 et Zelda 64 ont été entièrement décompilés, et d’autres jeux N64 sont en cours ; je me demande donc s’il serait possible de cartographier les développeurs ayant travaillé sur ces deux jeux, d’estimer qui a créé quels modules, puis d’utiliser cela pour décompiler d’autres jeux.
Si cela devenait vraiment performant, on pourrait rêver d’une vie où l’on déchiffre tous les blobs binaires de son PC, où l’on publie les pilotes, et où l’on ouvre même les OS.
On peut même imaginer ne pas se contenter de Linux, ressusciter Windows XP, y rétroporter la sécurité moderne et la compatibilité applicative, tout en laissant Windows 11 de Microsoft tel quel.
Si un LLM peut faire la même chose qu’un décompilateur existant, les avocats considéreront probablement cela comme une procédure équivalente.
Le vrai problème n’est pas technique, mais juridique et politique.
Je ne sais pas vraiment si cela a été utile en pratique, mais il est fascinant que le style de codage individuel survive au processus de compilation au point de permettre de distinguer les programmes compilés de différentes personnes.
Le résultat serait très proche de l’original, mais de nombreux éléments de style de code disparaîtraient, et le style qui semblerait subsister relèverait probablement surtout de l’hallucination.
Comme il est facile de créer un grand jeu de données de paires entrée/sortie à partir de code C public, c’est un très bon cas d’usage pour le fine-tuning de LLM.
En général, la qualité des données synthétiques est une grande source d’inquiétude, mais ici le point essentiel est que le code compile.
Si je lis correctement les chiffres de réexécutabilité dans l’image des résultats, l’idée est excellente, mais en pratique elle ne semble pas bien fonctionner.
https://raw.githubusercontent.com/albertan017/LLM4Decompile/...
Pour compléter, la réexécutabilité est une métrique clé pour mesurer l’exactitude sémantique.
Elle évalue si la logique et le comportement du programme sont préservés en recompilant le résultat de la décompilation puis en exécutant des cas de test ; la recompilabilité et la réexécutabilité indiquent respectivement la restauration syntaxique et la préservation sémantique.
Ce problème est intéressant à au moins deux égards.
Premièrement, un décompilateur idéal pourrait affaiblir la portée du code source propriétaire.
Deuxièmement, le code C public est abondant, ce qui permet de créer facilement des jeux de données appariant assembleur et code source, avec une variété de niveaux d’optimisation, de compilateurs et de plateformes.
Cela dit, je me demande pourquoi les auteurs ont fine-tuné DeepSeek-Coder.
Je me demande aussi s’il serait possible d’entraîner un LLM à partir de zéro avec un jeu de données similaire, quelle taille serait nécessaire, et si une exécution locale serait possible.
Même si la tâche souhaitée n’est pas très proche du modèle initial, il est presque toujours préférable de partir d’un modèle préentraîné plutôt que d’une initialisation aléatoire.
Comme le compilateur perd de l’information, il ne peut en un sens jamais exister ; et même avec une lecture généreuse en termes de « compréhension de haut niveau du code résultant », c’est un problème de niveau intelligence artificielle générale dans le domaine de la sécurité informatique.
Personne n’en est encore proche.
Llama2 a été développé avec 2 000 milliards de tokens, alors que ce jeu de données est de l’ordre de 4 milliards de tokens.
Il n’est pas non plus simple de choisir la bonne taille de modèle : dans les expériences, un modèle à 7 milliards de paramètres affiche 21 % d’exécutabilité, tandis qu’un modèle à 1 milliard de paramètres n’atteint que 10 %.
En revanche, leur recompilabilité est assez similaire.
Le modèle à 1 milliard de paramètres nécessite au minimum 2 Go de mémoire GPU, ce qui le rend utilisable sur la plupart des GPU, tandis que le modèle à 7 milliards en demande 14 Go et convient aux séries 3090/4090.
Pour le modèle à 33 milliards, une A100 80 Go est l’option sur une seule carte ; techniquement, ce serait peut-être possible sur un MacBook, mais on n’aurait probablement pas envie de l’utiliser ainsi.
Cela peut aussi être un point de départ pour valider l’idée.
Je travaille à la création d’un décompilateur basé sur les LLM pour le bytecode Python : https://github.com/kukas/deepcompyle
Il ne semble pas y avoir beaucoup de monde sur cette piste de recherche, mais je pense qu’elle pourrait être assez intéressante, surtout maintenant que de longs contextes d’attention deviennent possibles
Si quelqu’un connaît une équipe qui travaille sur ce domaine, je serais intéressé par une collaboration
D’après mon expérience, le bytecode Python est suffisamment haut niveau pour être converti directement en code source
Python dispose d’un vaste écosystème de bibliothèques open source, mais je ne le vois pas comme très utilisé pour des logiciels distribués sous forme binaire
Je ne suis pas non plus sûr que ce soit basé sur un LLM
Il ne semble pas y avoir beaucoup de projets Python compilés en binaire
J’avais prévu d’essayer quelque chose de ce genre
Un jour, quelqu’un finira par percer un pipeline entrée binaire → bon code source en sortie, mais j’ai l’impression qu’il faudra encore quelques années
Je dis ça parce qu’il ne semble pas y avoir une grosse somme d’argent au bout de ce problème, mais je peux me tromper
Une bonne approche provisoire serait de construire un pipeline de décompilation faisant tourner Ghidra en mode headless, et de combiner la rigueur syntaxique du décompilateur avec les capacités intuitives d’un LLM
Comme AlphaGeometry, le décompilateur et le LLM devraient compenser leurs faiblesses respectives : https://deepmind.google/discover/blog/alphageometry-an-olymp...
Il faudrait aussi utiliser quelque chose comme AICI comme colle pour orchestrer la génération de code source C : https://github.com/microsoft/aici
Plutôt que d’utiliser les poids du LLM pour produire du code source C grammaticalement correct, il vaudrait mieux le faire réfléchir aux noms de variables, aux motifs de snippets et aux choix d’architecture, puis laisser des outils comme Ghidra ou LLVM gérer le reste
C’est un commentaire de fauteuil d’un ancien doctorant, avec pas mal de hand-waving, mais c’est formidable que ces chercheurs se soient lancés, et le fait que les auteurs mentionnent l’intégration de Ghidra dans leurs travaux futurs laisse penser que la direction est la bonne
Il est intéressant que le modèle 6 milliards fasse mieux que le modèle 33 milliards
Je me demande si cela signifie que le modèle 33 milliards a besoin de davantage de données d’entraînement
Si l’on compare une préformation sur environ 1 million de programmes C à DeepSeek-Coder entraîné sur des milliers de milliards de tokens, l’écart de quantité de données est de plusieurs ordres de grandeur
Je me demande aussi ce que cela donne face à des solutions qui ne sont pas des LLM
La plupart des LLM sont largement sous-entraînés, et les modèles 7 milliards, étant parmi les moins sous-entraînés des modèles grand public, se sont beaucoup répandus dans la communauté du fine-tuning de LLM
Avec un fine-tuning naïf, c’est-à-dire un simple fine-tuning en suivant la méthode standard telle quelle, l’entraînement de grands modèles est délicat, et les performances finales dépendent non seulement de la quantité de données, mais aussi de tous les facteurs comme le nettoyage des données, le taux d’apprentissage et la décroissance
Pour cela, il faudrait supposer que la taille moyenne de ces programmes C est de plusieurs ordres de grandeur inférieure à 2 millions de tokens ; c’est peut-être vrai en pratique, mais cela me semble une hypothèse assez optimiste
Je me demande si, en cas de succès, cela reviendrait à répliquer à l’identique le code machine du compilateur
Si c’est le cas, cela signifierait que le code complet peut exister dans l’espace latent sous forme de distribution de probabilité
Ou bien, plus probablement, il pourrait s’agir de ne répliquer que la logique puis de la traduire dans le langage cible
Les binaires dont la compilation nécessite une entrée non déterministe, par exemple une clé ou un hash, risquent de casser
C’est vraiment fascinant
Je suis surpris que GPT-4 s’en sorte encore plutôt bien dans la comparaison
Il produit du code compilable bien mieux que ce modèle, mais sa précision pour reproduire du code au comportement correct est plus faible
Cela reste tout de même assez impressionnant
Nous améliorons le modèle, donc continuez à suivre les mises à jour