
Modelo de lenguaje pequeño que nombra y describe funciones en binarios x86-64 despojados, con un conjunto de datos abierto, líneas base y experimentos de ajuste fino con LoRA.
English · Türkçe
Un modelo de lenguaje pequeño que examina una función en un binario sin símbolos y le asigna un nombre significativo y una descripción breve.
El conjunto de datos v4 contiene 228.177 funciones de 341 proyectos en 5 niveles de optimización y está publicado en Hugging Face bajo la configuración v4. El script de Ghidra está listo. El mejor modelo pequeño hasta ahora, Qwen3-8B + LoRA entrenado con los datos v5 (primero la descripción, luego el nombre), alcanza un F1 de nombre de 0,124 en la muestra de prueba fija v4 y 0,155 en eval_115; el mejor modelo grande con contexto de llamadas obtiene 0,167 en la misma muestra de prueba. Véase Resultados, sección 6. El modelo escribe una descripción de una frase en inglés y en turco junto con el nombre. El adaptador está en Hugging Face: krxi123/asmsense-qwen3-8b-lora.
Abre un programa sin símbolos en Ghidra o IDA y verás cientos de funciones llamadas FUN_00401a30. Gran parte de la ingeniería inversa consiste en comprender y nombrar estas funciones una por una. Este proyecto pretende enseñar a un modelo ese primer paso:
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.
Los modelos grandes de propósito general pueden manejar esta tarea hasta cierto punto, pero son lentos, costosos y están alojados en la nube. El objetivo es responder a esta pregunta:
¿Puede un modelo pequeño entrenado con datos creados específicamente igualar o incluso superar a los modelos grandes en esta tarea, mientras se ejecuta en un portátil?
Se evalúan tres niveles sobre el mismo conjunto de prueba:
| Nivel | Modelo | Rol |
|---|---|---|
| Techo | Modelos abiertos grandes (DeepSeek, GLM, MiMo, Gemma, Qwen) | Lo mejor alcanzable actualmente con modelos listos para usar |
| Línea base | Modelo abierto pequeño, antes del ajuste fino | Punto de partida |
| Este proyecto | El mismo modelo pequeño + LoRA sobre este conjunto de datos | La contribución del proyecto |
Generación de datos (cikar.py): Se compilan proyectos C de código abierto para x86-64 con distintos niveles de optimización (-O0, -O2). Se extrae el ensamblador de cada función. La verdad fundamental—el nombre original de la función—proviene directamente del código fuente, por lo que no se necesita etiquetado manual. projeler.json registra el commit y los flags del compilador usados para cada proyecto.
Simulación de un binario sin símbolos: La salida se asemeja a lo que Ghidra muestra para una función en un binario sin símbolos:
sub_01a3, y los datos globales en dat_0042 (los números se mezclan, con espacios de nombres separados para -O0 y -O2),loc_1 y loc_2,memcpy, __stack_chk_fail) y los literales de cadena (; -> "out of memory") permanecen visibles porque también lo están en un binario real.Si el nombre real de la función aparece en su propio ensamblador—por ejemplo, en un mensaje de error—la fila se marca como sizinti y se excluye del conjunto de prueba.
Evaluación (taban.py): El modelo recibe únicamente el ensamblador y se le pide que prediga un nombre. Las predicciones se puntúan por solapamiento de tokens (F1), por lo que respuestas cercanas como crc32_update y update_crc reciben crédito parcial.
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
| Proyectos | Funciones (-O0 + -O2) | |
|---|---|---|
| Entrenamiento | zlib, libpng, sqlite, lua, mbedtls, zstd, libsodium, expat, brotli, jansson, lz4, libyaml, xxhash, cJSON | 16.804 |
| Test (resistente a la memorización) | tomlc17, cyaml, mu_json_x, sajs, picomatch | 777 → conjunto de evaluación 115 |
El conjunto de datos está disponible en Hugging Face: krxi123/asmsense (16.804 ejemplos de entrenamiento, 777 ejemplos de test, el conjunto de evaluación eval_115 y textos de licencias). También está replicado en Kaggle: krxiii/asmsense.
Proyectos C con licencias permisivas (MIT, BSD, Apache-2.0, ISC, zlib) seleccionados de GitHub con olcekle.py fueron compilados en -O0/-O1/-O2/-O3/-Os usando cikar_bin.py (dylib real + strip -x). No se ejecutaron los scripts de compilación de los proyectos; los archivos se compilaron individualmente con clang, y los archivos o proyectos que fallaron al compilar se omitieron. Las filas se deduplicaron por hash de ensamblado normalizado. Las filas cuyo ensamblado era idéntico al de los datos de validación/test se eliminaron del entrenamiento, mientras que las copias vendorizadas cuyos pares (archivo, nombre) aparecían en el entrenamiento se eliminaron de validación/test. Cada fila tiene un campo lisans.
| Split | Proyectos | Filas | Funciones fuente únicas |
|---|---|---|---|
| Entrenamiento | 290 | 196.117 | 72.179 |
| Validación | 23 | 19.770 | 6.667 |
| Test (poco conocidos, ≤200 estrellas, 2024+) | 28 | 12.290 | 4.685 |
De 473 proyectos, 352 produjeron filas y 120 fallaron al compilar (código de kernel, embebido o dependiente de plataforma). Solo se usó clang. Los datos se mantienen fuera de Git y pueden regenerarse con python3 aday_bul.py y python3 olcekle.py hepsi.
La división entrenamiento/test es estrictamente a nivel de proyecto: ninguna función de un proyecto puede aparecer en ambos lados. Los proyectos de test se eligieron deliberadamente poco conocidos (2-190 estrellas), y la mayoría se iniciaron en 2024-2025, lo que hace mucho menos probable que los modelos grandes los hayan encontrado durante su entrenamiento que una biblioteca como zlib. Licencias: veri/LISANSLAR.md.
Excepción conocida: código vendorizado. Una auditoría independiente de los datos v6 publicados (rapor/arastirma/V6_VERI_DENETIMI.md, veri_denetim_v6.py) confirmó que ningún proyecto, id o (proyecto, archivo, nombre) aparece en ambos lados, pero el proyecto de test snkv incorpora SQLite bajo sus propios nombres de archivo mientras que sqlite es un proyecto de entrenamiento. En la muestra fija de test de 2.000 filas, 217 filas (10,85%) tienen un nombre idéntico al de una función de entrenamiento de SQLite. Todos los modelos obtienen puntuaciones más bajas en esas filas, por lo que no inflan los resultados; en cambio, reducen la brecha entre pequeños y grandes (véase Resultados, sección 6). La muestra de validación valid_300 contiene 16 filas similares (5,3%).
F1 de nombre medio (1,0 = coincidencia exacta). En la columna «F1 sin prefijo», el prefijo de nombre común de cada proyecto (cyaml_, mu_, sajs_) se elimina de ambos lados; el modelo no puede inferir este prefijo a partir del ensamblado.