aeon is meant to be a sensory organ, reasoning sandbox, and execution environment for autonomous AI agents, without any bloat from human-aimed tooling.
In this repository, that idea is applied to ARM64 ELF analysis. The workspace provides a reusable Rust analysis core plus thin agent-facing frontends that load binaries, lift instructions into AeonIL, run Datalog analyses, and expose the results through strict JSON interfaces.
The repository includes a small sample ARM64 ELF at samples/hello_aarch64.elf for smoke tests and examples.
- Agent-native first - interfaces are machine-oriented and JSON-based
- Sensory surface over UX surface - the system exposes bytes, strings, asm, IL, CFGs, xrefs, and behavioral search primitives directly
- Reasoning sandbox - a binary is loaded once into a persistent session, then queried repeatedly through narrow tool calls
- Execution environment - CLI, MCP, and HTTP frontends give autonomous agents a concrete place to run analysis actions
- No human-tooling bloat - no dashboards, no TUI layer, no analyst workflow scaffolding
- ARM64 ELF ingestion - parses ELF images and discovers functions from
.eh_frame - AeonIL lifting - lifts ARM64 instructions into a BNIL-style intermediate representation
- ECS-backed program model - stores instruction facts and relationships in
bevy_ecs - Datalog analysis - computes CFG edges, reachability, terminal blocks, and cross-references with
ascent - Behavioral crypto search - detects RC4 KSA and PRGA patterns structurally rather than by signature
- Raw memory inspection - reads bytes, data regions, and null-terminated strings from virtual addresses
- Agent-facing transport layers - exposes the same session through CLI, MCP over stdio, and a stateful HTTP API
crates/aeon-eval- evaluation corpus, task, claim, and evidence modelscrates/aeonil- standalone AeonIL cratecrates/aeon- reusable analysis librarycrates/aeon-frontend- CLI, MCP, and HTTP frontendscrates/survey- standalone opcode survey utility
cargo build --releaseThis produces:
target/release/aeontarget/release/aeon-evaltarget/release/aeon-mcptarget/release/aeon-httptarget/release/survey
The CLI is intentionally small and machine-friendly. It prints JSON and supports three direct modes:
# Search for RC4 implementations
aeon rc4 samples/hello_aarch64.elf
# Report IL lift coverage
aeon coverage samples/hello_aarch64.elf
# Inspect the function containing a specific address
aeon func samples/hello_aarch64.elf 0x7d8aeon-mcp exposes the analysis session as JSON-RPC 2.0 over stdio for agent runtimes that speak MCP.
The project root includes .mcp.json for local auto-discovery in Claude Code. It runs the server through cargo run --release, so it does not depend on a machine-specific binary path.
aeon-http exposes the same stateful session over HTTP:
aeon-http 127.0.0.1:8787Example calls:
curl -s http://127.0.0.1:8787/call \
-H 'content-type: application/json' \
-d '{"name":"load_binary","arguments":{"path":"samples/hello_aarch64.elf"}}'
curl -s http://127.0.0.1:8787/call \
-H 'content-type: application/json' \
-d '{"name":"get_function_at","arguments":{"addr":"0x7d8"}}'
curl -s http://127.0.0.1:8787/call \
-H 'content-type: application/json' \
-d '{"name":"get_il","arguments":{"addr":"0x7d8"}}'Useful endpoints:
GET /health- loaded or unloaded state plus session summaryGET /tools- tool schemasPOST /call- execute{ "name": "...", "arguments": { ... } }
The core crate can also be embedded directly in Rust tooling:
[dependencies]
aeon = { path = "/path/to/aeon/crates/aeon" }
serde_json = "1.0"use aeon::AeonSession;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let session = AeonSession::load("samples/hello_aarch64.elf")?;
let functions = session.list_functions(0, 10, None);
println!("{}", serde_json::to_string_pretty(&functions)?);
Ok(())
}Lower-level modules remain public for callers that want direct access to ELF parsing, lifting, IL types, engine internals, or RC4 search logic.
survey is a generic opcode survey tool for any ELF that aeon can parse:
survey samples/hello_aarch64.elf --limit 20
survey samples/hello_aarch64.elf --jsonaeon-eval runs reproducible capability checks and emits evidence-bearing JSON:
aeon-eval constructor-layout libUnreal.so 0x05e66990These tools are exposed by the MCP and HTTP frontends:
Generated from crates/aeon-frontend/src/service.rs via cargo run -p aeon-frontend --bin aeon_docgen.
| Tool | Description |
|---|---|
load_binary |
Load an ELF binary for analysis. Must be called before other tools. |
list_functions |
List functions discovered from .eh_frame unwind tables. Supports pagination and name filtering. |
set_analysis_name |
Backwards-compatible alias for rename_symbol. Attaches or overwrites a semantic symbol on an address. |
rename_symbol |
Attach or overwrite a semantic symbol name on an address. |
define_struct |
Attach or overwrite a structure definition on an address. |
add_hypothesis |
Record a semantic hypothesis on an address. Duplicate notes are ignored. |
search_analysis_names |
Search analysis names attached to addresses using a regex pattern. |
get_il |
Get the lifted AeonIL intermediate language listing for the function containing a given address. |
get_function_il |
Backwards-compatible alias for get_il. |
get_function_cfg |
Get the Control Flow Graph for a function. Returns adjacency list, terminal blocks, and reachability from Datalog analysis. |
get_xrefs |
Get cross-references for an address: outgoing calls from the function, and incoming calls from other functions. |
get_bytes |
Read raw bytes from the binary at a virtual address. Returns hex-encoded string. |
search_rc4 |
Search for RC4 cipher implementations using Datalog behavioral subgraph isomorphism. Detects KSA (swap+256+mod256) and PRGA (swap+keystream XOR) patterns. |
get_coverage |
Get IL lift coverage statistics: proper IL vs intrinsic vs nop vs decode errors. |
get_asm |
Disassemble ARM64 instructions between two virtual addresses. Returns asm only, without AeonIL. |
get_function_at |
Find the function containing a given address. Returns function metadata by default, and can optionally attach asm and/or AeonIL listings. |
get_string |
Read a null-terminated string at any virtual address (works across all ELF segments, not just .text). |
get_data |
Read raw bytes at any virtual address (works across all ELF segments). Returns hex + ASCII. |
ELF binary
-> bad64 decode
-> AeonIL lifting
-> bevy_ecs fact store
-> ascent Datalog analysis
-> CLI / MCP / HTTP agent interface
| File | Purpose |
|---|---|
crates/aeon-eval/src/lib.rs |
Evaluation corpus, task, and evidence models |
crates/aeonil/src/lib.rs |
AeonIL data types and expression helpers |
crates/aeon/src/api.rs |
High-level session API |
crates/aeon/src/elf.rs |
ELF parsing and function discovery |
crates/aeon/src/lifter.rs |
ARM64 to AeonIL lifting |
crates/aeon/src/il.rs |
Compatibility re-export of aeonil |
crates/aeon/src/object_layout.rs |
Constructor object-layout recovery for pointer fields |
crates/aeon/src/components.rs |
ECS components for lifted facts |
crates/aeon/src/analysis.rs |
Datalog rules for CFG and reachability |
crates/aeon/src/rc4_search.rs |
Behavioral RC4 detection |
crates/aeon/src/engine.rs |
Session orchestration and analysis internals |
crates/aeon-frontend/src/service.rs |
Shared stateful tool dispatch |
crates/aeon-frontend/src/mcp.rs |
MCP frontend |
crates/aeon-frontend/src/http.rs |
HTTP frontend |