逆向工程 Agent 流水線:整合 morluto/rea 進行二進制分析
Reverse Engineering Agent Pipelines: Integrating morluto/rea for Binary Analysis
作者將 morluto/rea 整合至現有可觀測性流水線,測試其以多 Agent 進行逆向工程和原生二進制分析的能力。Agent 可解析 ELF、PE 和 Mach-O 靜態資料,並在 x86-64 二進制檔案上重建控制流程;分析 50MB 二進制檔案時,串流速度一度達 12,000 tokens/sec,須透過批次緩衝和背壓保持介面流暢。
Reverse Engineering Agent Pipelines: Integrating morluto/rea for Binary Analysis
When evaluating agent frameworks for reverse engineering workflows, most tools force you into either static analysis harnesses or full symbolic execution environments. The morluto/rea repository positions itself as a middle ground: agent-driven introspection that scales from app behavior tracing down to native binary analysis.
I integrated morluto/rea into an existing observability pipeline to validate its claim of "reverse engineer anything with agents." Here's the architectural breakdown and where it breaks.
Agent Architecture and Execution Model
The framework structures reverse engineering as a multi-agent coordination problem. Each agent operates as a specialized probe:
interface ReverseEngineeringAgent {
probe: (target: Target) => Observable<Artifact>;
synthesize: (artifacts: Artifact[]) => Analysis;
coordinate: (peers: Agent[]) => void;
}
The core value is treating analysis as streaming inference rather than batch processing. Agents emit partial artifacts as they discover them, which downstream agents consume in real-time. This maps well to SSE-based observability dashboards.
When wiring morluto/rea into a production topology, the agent coordination layer expects an LLM routing gateway that handles context management and token budgets. For baseline testing, I routed through https://b-lost.com/v1 as the relay endpoint:
const agentConfig = {
baseURL: "https://b-lost.com/v1",
model: "claude-sonnet-3-5",
stream: true,
abortSignal: controller.signal
};
const probeStream = await agent.probe(binaryTarget, agentConfig);
The streaming architecture matters because reverse engineering generates massive intermediate state. Traditional batch analyzers buffer everything in memory, then dump results. morluto/rea's agent design emits discoveries incrementally, which keeps memory pressure manageable when analyzing large binaries.
Binary Introspection Boundaries
The repository's claim of "native binary" support needs qualification. What works:
Static artifact extraction — Agents successfully parse ELF headers, PE sections, Mach-O load commands. The symbol table agent correctly identifies stripped binaries and delegates to heuristic analysis.
Control flow reconstruction — Given a disassembly input, agents build CFG graphs and identify indirect jump tables. This worked reliably on x86-64 binaries compiled with standard toolchains.
What breaks:
Dynamic instrumentation hooks — The framework assumes you're feeding it static artifacts. If your workflow requires runtime tracing (eBPF probes, ptrace hooks), you're writing custom agent adapters. The repo includes no pre-built dynamic analysis agents.
Architecture-specific quirks — ARM64 branch predictor state, RISC-V compressed instructions, or PowerPC function descriptors require manual agent extension. The default agents assume x86-64 semantics.
Streaming UI Integration
For production observability, I needed real-time artifact rendering as agents discovered function boundaries, string references, and cross-references. Using Vercel AI SDK's streaming hooks:
import { useCompletion } from '@ai-sdk/react';
function BinaryAnalysisStream({ binaryId }: { binaryId: string }) {
const { completion, isLoading, error } = useCompletion({
api: '/api/analyze',
body: { binaryId },
onError: (err) => {
// Handle stream cuts during long-running analysis
if (err.message.includes('stream aborted')) {
console.warn('Analysis stream interrupted, reconnecting...');
}
}
});
return (
<pre className="artifact-stream">
{completion || 'Initializing agents...'}
</pre>
);
}
The key operational challenge: morluto/rea's agent runtime can emit artifacts faster than React can reconcile DOM updates. On a 50MB binary with dense symbol tables, the artifact stream peaked at 12,000 tokens/sec. This caused visible UI jank.
Solution: Batched chunk buffering with backpressure signaling:
const artifactBuffer: Artifact[] = [];
const FLUSH_INTERVAL = 100; // ms
probeStream.subscribe({
next: (artifact) => {
artifactBuffer.push(artifact);
if (artifactBuffer.length >= 50) {
flushToUI(artifactBuffer.splice(0));
}
}
});
setInterval(() => {
if (artifactBuffer.length > 0) {
flushToUI(artifactBuffer.splice(0));
}
}, FLUSH_INTERVAL);
This kept the UI responsive while preserving the streaming semantics that make real-time analysis viable.
Hardened Configuration for Production
When integrating morluto/rea into an existing pipeline, these configuration boundaries matter:
Agent timeout policies — Default agents have no execution time limits. A malformed binary can deadlock an agent indefinitely. Wrap agent initialization with AbortController timeouts:
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000);
try {
await agent.probe(target, { signal: controller.signal });
} finally {
clearTimeout(timeoutId);
}
Artifact storage overflow — Long-running analysis generates unbounded artifact logs. The framework doesn't enforce retention policies. We added a rolling window eviction:
const MAX_ARTIFACTS = 10000;
if (artifactStore.size > MAX_ARTIFACTS) {
const oldestKey = artifactStore.keys().next().value;
artifactStore.delete(oldestKey);
}
Model context exhaustion — Complex binaries can exceed LLM context windows during synthesis phases. The framework doesn't chunk artifacts automatically. We partition analysis by address ranges and run parallel agent instances.
Where This Approach Fails
If your reverse engineering workflow relies on theorem provers (Z3, Boolector) or symbolic execution engines (angr, Triton), morluto/rea's agent abstraction is the wrong layer. The framework optimizes for probabilistic heuristic analysis, not formal verification.
For binaries with heavy obfuscation (virtualized instructions, encrypted code sections), the default agents produce low-confidence garbage. You're better off with dedicated deobfuscation passes before feeding artifacts to agents.
Open Engineering Questions
The agent coordination protocol assumes agents converge on a consistent analysis. But what happens when two agents produce conflicting function boundary hypotheses? The current implementation has no conflict resolution mechanism beyond "last write wins."
For teams running this in production: how are you handling agent disagreement? Voting schemes, confidence scoring, or manual adjudication?
來源:DEV Community · dev.to