Industrializing the disassembly of an undocumented processor from a raw binary is a complex challenge that can be broken down into 4 main phases:
- Verify that the binary does not belong to an already known processor.
- Verify that the binary does not correspond to obfuscated, compressed, or encrypted code from a known processor.
- Build an undocumented processor generator.
- Develop the analysis workflow and disassembly generation pipeline.
For the first step of this project, the goal is to evaluate different strategies and identify the most effective approach.
2. Evaluated Strategies
The first strategy aimed to generate a transcodification table (mapping byte sequences to assembly instructions) in order to disassemble the binary both statically and dynamically for a given processor. This process continues until one or more bytes fail to match any known instruction for that processor, or until disassembly completes successfully (note: successful disassembly does not necessarily mean the binary was compiled for that specific processor).
To implement this strategy and build the transcodification table, several approaches were tested:
Ghidra transcodification table generation: Failed.
Native disassembler transcodification table generation: Failed.
Using Gemini to generate the table from raw byte sequences: Successful.
(For a full summary of the tests conducted under Strategy 1, see "Identifying the Processor of a Bare-Metal Binary — Strategy 1".)
The second strategy takes a completely different approach. It consists of using Ghidra to disassemble the binary against a large number of target architectures (177 processors) and then leveraging a Large Language Model (LLM) to analyze the resulting disassembly outputs to determine which processor truly matches the binary.
3. Test Protocol
The local LLMs selected for this benchmark are:
- dolphinMistral24b
- dolphin3-cyber
- gemma4:26b
- qwen3-coder:30b
- qwen2.5-coder
Using a single C source code file and an automated toolchain, test binaries were generated for approximately 30 different processors in both raw bare-metal and standard ELF formats.
Three specific binaries were selected for the evaluation:
- Firmware 1: Target processor is natively supported by Ghidra.
- Firmware 2: Target processor is not supported by Ghidra.
- Firmware 3: An ELF file, explicitly disassembled as a raw bare-metal binary (forcing raw byte parsing).
Disassembly output files were batch-generated using PyGhidra and a custom Java headless script. Each model was then prompted to analyze every generated disassembly file using the exact same system prompt:
Python
SYSTEM_PROMPT = """You are an expert in reverse engineering and processor architectures.
Your task is to verify the consistency of a raw firmware disassembly.
Examine the provided instructions, verify whether the architecture's syntax is valid,
and determine if the instructions appear coherent (absence of repeated invalid instructions, aberrant opcodes, etc.).
Respond strictly in valid JSON format."""
The models were instructed to respond using a strict JSON schema:
JSON
{
"processor_id": "{processor_id}",
"is_valid": true,
"confidence_score": 0.85,
"summary": "Short explanation of the analysis",
"detected_anomalies": ["list of errors or anomalies"]
}
4. Benchmark Results
Firmware 1 (Known Processor)
This firmware was generated for a processor supported by Ghidra.
- qwen2.5-coder: Generated reports for all 177 files. Identified 69 potential candidate processors (including the correct one).
- qwen3-coder:30b: Generated reports for all 177 files. Identified 35 potential candidate processors (including the correct one).
- gemma4:26b: Severe formatting failure — generated a valid report for only 1 disassembly file.
- dolphinMistral24b: Generated reports for all 177 files. Identified 114 potential candidate processors (including the correct one).
- dolphin3-cyber: Generated reports for all 177 files. Identified 168 potential candidate processors (including the correct one).
Firmware 2 (Unknown Processor)
This firmware was generated for a target architecture not supported by Ghidra.
- qwen2.5-coder: Generated reports for all 177 files. Identified 67 potential candidate processors (false positives).
- qwen3-coder:30b: Generated reports for all 177 files. Identified 32 potential candidate processors (false positives).
- gemma4:26b: Failed completely — unable to generate a single report.
- dolphinMistral24b: Generated reports for all 177 files. Identified 105 potential candidate processors (false positives).
- dolphin3-cyber: Generated reports for all 177 files. Identified 172 potential candidate processors (false positives).
Firmware 3 (ELF File Disassembled as Bare Metal)
Given the poor baseline performance of local models, this test was conducted exclusively on qwen3-coder:30b.
qwen3-coder:30b: Generated reports for all 177 files. Identified 42 potential candidate processors (including the correct one).
5. Why Are the Results So Poor?
The empirical results show an exceptionally high rate of false positives: models validated between 35 and 172 candidates out of 177, failing to act as a selective heuristic filter. Several key technical factors explain this shortfall:
A. Root Causes & Hypotheses
Superficial Syntax Validation vs. Semantic Verification:
Most code-focused LLMs evaluate assembly primarily at a syntactic level. When Ghidra forces a disassembly, it outputs valid instruction strings (e.g., MOV R0, R1) according to the target architecture's grammar. The LLMs mistake syntactically valid instructions for semantically logical code, ignoring structural red flags like non-sensical control flow, impossible stack frame allocations, or meaningless register usage.Window-Size Contraint & Contextual Blind Spots (First 50 Instructions):
Limiting context to the first 50 instructions creates a severe bias. In raw bare-metal binaries (and especially ELF files parsed as raw bytes), the offset often starts with interrupt vectors, padding, or raw header metadata (\x7fELF). Disassembling metadata produces random, garbage instructions. The LLM either accepts this garbage as valid initialization code or misses real function prologues (PUSH {LR}, frame setup) located further down in the binary.Hallucination of High Confidence Scores:
Smaller, quantized local models lack calibrated uncertainty. They frequently assign confidence scores between 0.80 and 1.0 to highly improbable disassemblies simply because no explicit .byte unknown directives appeared in the 50-sample window.JSON Schema Inflation and Special Token Leaks:
Models like gemma4:26b failed due to prompt-adherence degradation when handling low-level assembly syntax, leaking internal reasoning/channel tokens (e.g., thought...) into the JSON stream, which corrupted output parsing.
B. Proposed Solutions to Improve Results
To transform this approach into a viable industrial pipeline, several adjustments are required:
Heuristic Pre-Filtering & Metrics Computation (Hybrid Static Analysis + LLM):
Before calling the LLM, compute mathematical heuristics on the disassembly output:Invalid Instruction Ratio: Reject architectures where .byte or ?? directives exceed 5% of the total output.
Control Flow Density: Measure the ratio of control-flow instructions (JMP, CALL, BRANCH) to data movement (MOV, LDR). Random/incorrect disassemblies display abnormally low or erratic jump densities.
Entropy & String Artifacts: Calculate entropy across the binary sections to skip static headers before sampling.
Few-Shot Prompting with Counter-Examples:
Update the system prompt with explicit Few-Shot examples contrasting a valid disassembly (coherent stack operations, standard function prologues, structured loops) with an invalid/garbage disassembly (repetitive opcodes, dead jumps, aberrant immediate values).Dynamic Sample Windowing (Skipping Metadata):
Instead of feeding the first 50 raw instructions, extract 50 instructions starting from detected function entry points (e.g., identified by CALL targets or push/pop entry sequences). For ELF binaries treated as bare metal, automatically skip the initial offset matching known header lengths.Chain-of-Thought (CoT) Reasoning Before JSON Output:
Forcing the LLM to output raw JSON immediately suppresses its internal analytical capabilities. Changing the prompt structure to require a step-by-step reasoning phase before emitting the final JSON object significantly improves accuracy:
Plaintext
1. Analyze control flow coherence...
2. Check register consistency...
3. Identify function entry signatures...
4. Output JSON verdict.
- Cross-Architecture Elimination Tournaments: Instead of asking the LLM "Is Architecture X valid?" in isolation, prompt the model with pairs of disassembly snippets (Architecture A vs. Architecture B) and ask it to select which of the two displays superior architectural coherence.
6. Epilogue
This benchmark highlights the clear limitations of current local LLMs when used out-of-the-box for low-level reverse engineering heuristics. Without statistical pre-filtering, dynamic windowing, and structured chain-of-thought prompting, local models act as overly permissive classifiers.
Can refined prompt engineering, dynamic context sampling, or cloud-grade LLMs bridge this gap to reliably pinpoint unknown architectures? That will be the subject of our next evaluation.
United States
NORTH AMERICA
Related News
Disrupting a Criminal Scam Operation
22h ago

Greatness PhaaS Adds Device Code Phishing to Bypass MFA and Steal Tokens
4h ago

Apple just revealed a clue about its September iPhone event date
4h ago

Today’s Android app deals and freebies: Knight Bewitched, What Lies Underground, Northgard, more
5h ago
Take an extra $100 off your TechCrunch Disrupt 2026 pass: This week only!
5h ago