| name | reverse-rust-malware |
| description | Use this skill when analyzing stripped or static-linked Rust malware or suspicious Rust ELF binaries. Focus on string recovery, panic-path reconstruction, module-tree building, command-dispatch discovery, and protocol recovery. |
Reverse Rust Malware
Use this skill for Rust-heavy reverse engineering workflows, especially when the sample is stripped, static-linked, or hard to analyze with default string/symbol views.
Minimum command set
Start with:
file sample.bin
sha256sum sample.bin
strings -a -n 6 sample.bin | rg -i "panic|thread 'panicked|::|\\.rs:|tokio|reqwest|serde|ring|rustls|openssl|cmd|/bin/sh"
binwalk sample.bin
Then inspect object and import context:
readelf -h -S sample.bin 2>/dev/null | head -200
objdump -x sample.bin 2>/dev/null | head -200
Aggressive string recovery (don't skip this)
IDA's default string window and strings(1) both under-count Rust
binaries because Rust stores strings as (pointer, length) slices packed
into .rodata, not NUL-terminated. The bundled scanner walks .rodata
byte-by-byte and recovers panic paths, crate versions, and command words
that never show up in the UI:
python3 scripts/rodata_scanner.py sample.bin --min 6 > rodata.strings
wc -l rodata.strings
python3 scripts/rodata_scanner.py sample.bin --grep 'panic|\.rs:'
Chain the scanner into the other helpers:
python3 scripts/rodata_scanner.py sample.bin \
| python3 scripts/panic_path_extractor.py --stdin-text --tree
python3 scripts/rodata_scanner.py sample.bin \
| python3 scripts/rust_fingerprint.py --stdin-text
python3 scripts/mem_peer_extractor.py dump.bin
Treat the typo output from rust_fingerprint.py --typos-only as your
highest-value global-search pivot: a misspelled word in a log message is
almost always a unique fingerprint across VT + GitHub + google.
If ida-pro-mcp is connected, use:
find_regex for panic strings, crate paths, command words, and URLs
xrefs_to on high-signal strings or imports
decompile likely dispatchers and large branch-heavy handlers
callgraph from the top dispatcher candidate before bulk renaming
py_eval to port rodata_scanner.py into IDA so the results are
anchored to addresses you can xref from (see reverse-ida-mcp-driver
for the ready-to-paste py_eval payload)
Core assumptions
For Rust samples, assume:
- standard string views may be incomplete
- function boundaries may be noisy
- source paths may leak through panic-related strings
- crate names and file paths are high-value clues
- enum-based dispatch and layered decode/dispatch flows are common
Primary goals
Produce:
- Rust-focused binary triage
- recovered string inventory
- reconstructed module tree
- likely dispatcher map
- protocol and command hypotheses with confidence labels
Workflow
Phase 1: Rust triage
Identify:
- strongest evidence the sample is Rust
- whether it is static-linked
- whether symbols are stripped
- likely crates or subsystems
- likely networking / crypto stack
Phase 2: aggressive string recovery
Prioritize:
.rodata printable spans
- UTF-8 candidate strings
- source file paths
- panic-related strings
- command words
- key / crypto / network markers
Do not dump raw strings without clustering.
Cluster into:
- source paths
- crate names
- commands
- protocol words
- crypto material
- environment / file paths
- unique fingerprints
Phase 3: reconstruct module structure
Use recovered file paths and panic paths to build:
- likely workspace root
- crate boundaries
- top-level modules
- priority files for manual review
Highlight files that likely correspond to:
- dispatch
- protocol
- key handling
- networking
- persistence / update
- file or shell utilities
Phase 4: locate dispatch
Use command-like strings and xrefs to find:
- dispatcher candidates
- branch-heavy handlers
- match/switch-like control flow
- decode-then-dispatch clusters
Build a command map with confidence labels.
If ida-pro-mcp is connected, prioritize:
find_regex for command words, JSON keys, panic paths, and protocol strings
xrefs_to from those hits
decompile the narrowest branch-heavy callers first
rename only after the command map is stable
Phase 5: protocol sketch
Try to recover:
- transport assumptions
- message boundaries
- serialization / deserialization points
- encryption boundaries
- request/response or peer-to-peer behavior
Never invent exact field semantics.
Prefer neutral placeholders like:
- field_1
- len
- nonce
- cmd_id
- pubkey_candidate
If protocol detail becomes the main question, hand off to reverse-protocol-reconstruction.
If build paths, wallets, cloud relays, or operator traces emerge, hand off to reverse-operator-attribution.
Minimum artifact bundle:
- Rust-identifying strings or paths
- crate or module clues
- dispatcher shortlist
- protocol or command clues
- MCP exports only if they actually ran
Required response structure
Rust Malware Analysis Summary
Executive Summary
[2-5 sentences]
Facts
Inferences
Unknowns
Reconstructed Module Tree
Command / Dispatcher Candidates
Protocol Notes
Recommended Next Actions