
Petit modèle de langage qui nomme et décrit les fonctions dans les binaires x86-64 dépouillés, avec un jeu de données ouvert, des baselines et des expériences de fine-tuning LoRA.
Anglais · Turc
Un petit modèle de langage qui examine une fonction dans un binaire dépouillé et lui attribue un nom significatif ainsi qu'une brève description.
Le jeu de données v4 contient 228 177 fonctions issues de 341 projets répartis sur 5 niveaux d'optimisation et est publié sur Hugging Face sous la configuration v4. Le script Ghidra est prêt. Le meilleur petit modèle à ce jour, Qwen3-8B + LoRA entraîné sur les données v5 (description d'abord, puis nom), atteint un F1 de nom de 0,124 sur l'échantillon de test v4 fixe et 0,155 sur eval_115 ; le meilleur grand modèle avec contexte d'appel obtient 0,167 sur le même échantillon de test. Voir Résultats, section 6. Le modèle rédige une description d'une phrase en anglais et en turc ainsi que le nom. L'adaptateur est sur Hugging Face : krxi123/asmsense-qwen3-8b-lora.
Ouvrez un programme dépouillé dans Ghidra ou IDA et vous verrez des centaines de fonctions nommées FUN_00401a30. Une grande partie du reverse engineering consiste à comprendre et à nommer ces fonctions une par une. Ce projet vise à enseigner à un modèle cette première étape :
input (stripped x86-64) target output
───────────────────────────── ──────────────────────────────────────────────
movzx eax, byte ptr [rsi] name: adler32_update
lea rdx, [rdi + rax] description: Computes the Adler-32 checksum
cmp rdx, 0xfff1 ← 65521 over the bytes of a buffer.
... # TR: Tampondaki baytlar üzerinden Adler-32
# sağlama toplamı hesaplar.
Les grands modèles à usage général peuvent traiter cette tâche dans une certaine mesure, mais ils sont lents, coûteux et hébergés dans le cloud. L'objectif est de répondre à cette question :
Un modèle petit entraîné sur des données conçues spécifiquement peut-il égaler, voire surpasser, les grands modèles sur cette tâche—tout en tournant sur un ordinateur portable ?
Trois niveaux sont évalués sur le même jeu de test :
| Niveau | Modèle | Rôle |
|---|---|---|
| Plafond | Grands modèles ouverts (DeepSeek, GLM, MiMo, Gemma, Qwen) | Le meilleur actuellement atteignable avec des modèles prêts à l'emploi |
| Référence | Petit modèle ouvert, avant fine-tuning | Point de départ |
| Ce projet | Le même petit modèle + LoRA sur ce jeu de données | La contribution du projet |
Génération des données (cikar.py): Des projets C open source sont compilés pour x86-64 à différents niveaux d'optimisation (-O0, -O2). L'assembleur de chaque fonction est extrait. La vérité terrain—le nom de la fonction d'origine—provient directement de la source, donc aucun étiquetage manuel n'est nécessaire. projeler.json enregistre le commit et les options du compilateur utilisés pour chaque projet.
Simulation d'un binaire strippé : La sortie ressemble à ce que Ghidra affiche pour une fonction dans un binaire strippé :
sub_01a3, et les données globales deviennent dat_0042 (les numéros sont mélangés, avec des espaces de noms séparés pour -O0 et -O2),loc_1 et loc_2,memcpy, __stack_chk_fail) et les littéraux de chaîne (; -> "out of memory") restent visibles car ils sont également visibles dans un vrai binaire.Si le vrai nom de la fonction apparaît dans son propre assembleur—par exemple, dans un message d'erreur—la ligne est marquée sizinti et exclue du jeu de test.
Évaluation (taban.py): Le modèle reçoit uniquement l'assembleur et doit prédire un nom. Les prédictions sont notées par chevauchement de tokens (F1), de sorte que des réponses proches telles que crc32_update et update_crc reçoivent un crédit partiel.
loc_6:
movzx r9d, byte ptr [rsi + rdx]
add rdi, r9 ← adler32_z (-O2), as the model sees it
add rcx, rdi
inc rdx
cmp rax, rdx
jne loc_6
| Projets | Fonctions (-O0 + -O2) | |
|---|---|---|
| Entraînement | zlib, libpng, sqlite, lua, mbedtls, zstd, libsodium, expat, brotli, jansson, lz4, libyaml, xxhash, cJSON | 16 804 |
| Test (résistant à la mémorisation) | tomlc17, cyaml, mu_json_x, sajs, picomatch | 777 → ensemble d'évaluation 115 |
Le jeu de données est disponible sur Hugging Face : krxi123/asmsense (16 804 exemples d'entraînement, 777 exemples de test, l'ensemble d'évaluation eval_115 et les textes de licence). Il est également disponible en miroir sur Kaggle : krxiii/asmsense.
Des projets C sous licence permissive (MIT, BSD, Apache-2.0, ISC, zlib) sélectionnés sur GitHub avec olcekle.py ont été compilés à -O0/-O1/-O2/-O3/-Os à l'aide de cikar_bin.py (dylib réelle + strip -x). Les scripts de compilation des projets n'ont pas été exécutés ; les fichiers ont été compilés individuellement avec clang, et les fichiers ou projets dont la compilation a échoué ont été ignorés. Les lignes ont été dédupliquées par hachage d'assembleur normalisé. Les lignes dont l'assembleur était identique aux données de validation/test ont été retirées de l'entraînement, tandis que les copies vendored dont les paires (fichier, nom) apparaissaient dans l'entraînement ont été retirées de la validation/test. Chaque ligne possède un champ lisans.
| Split | Projets | Lignes | Fonctions sources uniques |
|---|---|---|---|
| Entraînement | 290 | 196 117 | 72 179 |
| Validation | 23 | 19 770 | 6 667 |
| Test (peu connus, ≤200 étoiles, 2024+) | 28 | 12 290 | 4 685 |
Sur 473 projets, 352 ont produit des lignes et 120 n'ont pas pu être compilés (code noyau, embarqué ou dépendant de la plateforme). Seul clang a été utilisé. Les données sont conservées en dehors de Git et peuvent être régénérées avec python3 aday_bul.py et python3 olcekle.py hepsi.
La séparation entraînement/test est strictement au niveau du projet : aucune fonction d'un projet ne peut apparaître des deux côtés. Les projets de test ont été délibérément choisis parmi les peu connus (2-190 étoiles), et la plupart ont été créés en 2024-2025, ce qui rend bien moins probable que les grands modèles les aient rencontrés pendant leur entraînement qu'une bibliothèque comme zlib. Licences : veri/LISANSLAR.md.
Exception connue : le code vendored. Un audit indépendant des données v6 publiées (rapor/arastirma/V6_VERI_DENETIMI.md, veri_denetim_v6.py) a confirmé qu'aucun projet, id ou (projet, fichier, nom) n'apparaît des deux côtés, mais le projet de test snkv intègre SQLite sous ses propres noms de fichiers tandis que sqlite est un projet d'entraînement. Dans l'échantillon de test fixe de 2 000 lignes, 217 lignes (10,85 %) ont un nom identique à une fonction d'entraînement SQLite. Tous les modèles obtiennent des scores plus faibles sur ces lignes, elles ne gonflent donc pas les résultats ; elles réduisent au contraire l'écart entre petits et grands modèles (voir Résultats, section 6). L'échantillon de validation valid_300 contient 16 lignes similaires (5,3 %).