
What in x86-64 assembly actually gives away a function's purpose? Notes from training a model to name stripped functions
I've been building asmsense, a dataset and a small model that looks at a function from a stripped x86-64 binary and suggests a name (think `FUN_00401a30` → `adler32_update`). Ground truth comes from compiling permissively licensed C projects with clang at -O0/-O1/-O2/-O3/-Os and stripping them. The test set is 28 little-known projects, so models cant just recall famous code.
A few things the error analysis showed about the assembly itself:
- String literals are by far the strongest signal. The fine-tuned model gets name F1 0.299 on functions with string constants and 0.093 on functions without.
- Magic constants help alot when they exist: `cmp rdx, 0xfff1` (65521) is practically a signature for Adler-32.
- -O2 is consistently harder than -O0, for every model i tested.
- Thin wrappers (a function that only calls another internal function) scored 0 for every model, even when i added the callee's full assembly to the input.
- Large LLMs look much better on famous code than they realy are. With reasoning, one model's exact matches on zlib went from 9 to 28, but on unfamiliar projects from 4 to 3. Alot of it is recall, not reading the assembly.
Where it stands: Qwen3-8B + LoRA reaches name F1 0.124 on the fixed test sample, while the best large model with call context gets 0.167. Not there yet.
Question for people who read asm by hand: when you open an unknown function in a stripped binary, what do you look at first? Is there anything youd expect a model to miss?
Code and data: https://github.com/krxi/asmsense