REA: AI Agents Now Investigate Binaries — But Closed Source Isn't Dead Yet
This article analyzes REA, a toolkit that lets AI agents call reverse engineering tools via CLI/MCP, detailing its architecture, evidence-based approach, cross-layer analysis for Electron and other platforms, runtime observation modules, and why it lowers analysis costs without eliminating closed-source software or legal risks.
What Reverse Engineering Is
Reverse engineering starts from delivered artifacts and observable behavior to deduce a program's structure, interfaces, and implementation logic. Inputs can be executables, assemblies, ASAR, APK, packet captures, crash logs, or a recorded run. Compilation discards information: machine code rarely reveals original variable names, comments, project organization, or developer intent. Decompiler output must be combined with assembly, strings, cross-references, data layout, and runtime behavior. Even readable pseudocode can leave gaps in types, boundaries, and indirect calls.
Therefore, reverse engineering deliverables should center on concrete questions: how a length field is encoded, how a button triggers file I/O, which branch changed in a version. Demanding full source-code recovery expands the target to the original project, build environment, resources, dependencies, and unobserved behavior, making acceptance criteria unbounded.
In traditional workflows, the analyst connects clues: search strings, locate references, inspect functions, revise hypotheses, design experiments. With AI, repetitive queries and cross-file tracing can be delegated to an agent. The analyst still decides which evidence suffices for a conclusion and which unknowns affect subsequent implementation.
A key distinction: "functional explanation" vs. "correct reproduction." A model explaining pseudocode only completes part of the former. An implementation passing a few samples only covers already-observed inputs. Treating limited observations as full equivalence passes an unverified spec to downstream development.
Why REA Gained Attention
REA's popularity stems from two factors: (1) reverse engineering has traditionally had a very high barrier, and Agent + REA lowers it dramatically; (2) the allure of replicating closed-source software with this toolkit feels like breaking a taboo.
REA + Agent solves a critical problem: models can already read code, but engineers still had to manually operate analysis tools for them. Ghidra, Hopper, IDA each have their own databases, APIs, and usage patterns. For Electron, one must also handle ASAR, module loading, preload, and IPC. When a problem crosses technical layers, the analyst must shuttle context between multiple toolchains, judging whether addresses, paths, and symbols refer to the same object.
REA exposes these capabilities via CLI and MCP. Humans can run commands directly; agents can call tools. Results use a unified description of provenance and limits, letting an investigation proceed continuously around a question while reducing manual tool-interaction overhead.
Community expectations have run ahead of reality. Lowering analysis cost is far from economically reproducing a large software product. Interaction details, exception branches, data-format compatibility, and untriggered behaviors all require verification. Stars and demos do not capture that cost.
GitTested's evaluation of REA 6.2.0 provides a constraint: on four stripped native programs ≤264 KB, a baseline toolset scored 74/75 on fact-checking, while REA scored 73/75 but used ~2.5× the tokens. This result applies to a specific version, model, and small programs; it cannot be extrapolated to current overall capability. It does show that adding analysis tools does not automatically yield higher returns.
When selecting tools, keep the baseline. For low-complexity tasks where file reads, search, and objdump already answer the question, loading large tool directories and full graph results may only increase task cost.
How REA Collaborates with Existing Tools
REA's production pipeline has no mandatory built-in general-purpose LLM planner. The model (from Codex, DeepSeek Harness, etc.) proposes the next query; REA provides concrete analysis operations, managing targets, results, and related resources.
Version 6.5.0 declares 207 tool contracts and 6 guided prompts. The native path includes function dossiers, pseudocode, assembly, strings, cross-references, call graphs, and byte/type checks. Decompilation is mainly handled by external engines; REA converts results into a unified representation.
This unification is not identical across engines. Different engines provide different facts; REA preserves unavailability reasons and coverage information rather than filling missing capabilities with empty arrays. Callers must know when an aspect was not observed or a provider simply lacks support.
Engine selection is not hidden. Automatic mode only binds deeply when a single analysis configuration is available; multiple candidates produce an ambiguity report. An explicitly chosen engine that fails will not silently fall back to another while retaining the original provenance note.
This design sacrifices some smoothness for explainable results. If an engine switch occurs mid-analysis, type recovery, function boundaries, and call relations may change. Letting the caller choose is better than hiding differences inside a success response for investigations that require review.
CLI and MCP share the application workflow but differ in lifecycle. CLI typically runs once and exits; MCP can retain target and investigation state. For continuous research on a large target, session reuse and snapshots have value; for a single explicit query, a one-shot command is easier to control.
Cross-Layer Analysis Challenges
Using JavaScript and Electron as an example: a file-import feature may start in the renderer, pass through preload, contextBridge, and IPC to the main process, finally calling a native extension. Searching for button text only yields the entry point; import graphs cannot independently explain cross-process relationships.
REA parses ASTs, establishes scopes, bindings, references, and module origins, then projects them into an application graph and a semantic graph. Aliases, destructuring, member changes, and partial bundling structures all participate in the judgment. A same-named function in code does not prove the call comes from the same module; after local variable shadowing, identical text may correspond to completely different behaviors.
IPC pairing uses conservative conditions: literal channel plus compatible communication pattern plus a unique candidate yields a definite pair. Multiple candidates preserve ambiguity; dynamic channels that cannot be proven remain unpaired. Static association does not automatically upgrade to runtime fact.
This strategy suits answering "where to investigate next." When faced with runtime computation, dynamic loading, or opaque effects, the static graph leaves gaps. Expanding the scan range may not fill them; one may need to switch to directed runtime observation.
Source text → AST → semantic IR → application graph → Evidence increases memory demand. REA runs parsing and analysis in isolated, controlled processes with heap limits, timeouts, and transfer budgets; partial traversals, validations, and summary computations respond to cancellation via cooperative checkpoints.
Separate processes add startup, serialization, and handoff costs, but provide clearer resource boundaries for large bundles. For small text, plain search is lighter; for cross-module origins and Electron boundaries, structured analysis can offset that overhead.
Capabilities Have Boundaries
Other REA modules follow the same specialized division of labor.
.NET path reads PE/CLI metadata, type members, IL method bodies, and managed-native boundaries without running the assembly. Suited for structural investigation, not full C# project recovery.
Android splits into JADX static code, Apktool resource decoding, ADB device operations, and JEB integration, avoiding mixing code viewing with app install/launch in one permission layer.
Package & resource module handles directory, ZIP, ASAR, DMG, and architecture slice manifests, digests, and extraction. Apple specialty further processes plist, Interface Builder, dynamic library parsing, and related metadata. Input identity is established here so later analysis can confirm it reads the same content.
Firmware relies on Binwalk, Unblob, etc., for region identification and extraction; Flutter checks build, ABI, and Dart AOT clues; WASM uses WABT for validation results, structure, and WAT; EVM uses EVMole for selector extraction and interface inference. Their output ranges differ; calling all of them "source recovery" erases important limits.
Go, Rust modules mainly read embedded build or dependency info. SQLite inspects stable databases and WAL private copies. Packet capture and recording modules interpret existing logs. Missing metadata does not prove a dependency is absent; an unobserved request in a window does not prove the feature never accesses the network.
These modules' value depends on the question. When needing to understand dependencies, reading metadata beats launching a decompiler; when explaining a data path, metadata cannot replace function and runtime observation. Before choosing a tool, first determine which fact could change the current judgment.
Evidence Determines Conclusions
REA's Evidence records target digest, provider, analysis configuration, operation parameters, raw and normalized results, location, limits, and linked evidence. It lets a model's explanation trace back to concrete sources rather than remaining a plausible-sounding narrative.
The fields observed, derived, inferred distinguish observation, deduction, and inference — expressing knowledge provenance, not probability. Observing that a decompiler emitted certain pseudocode is not the same as proving that pseudocode accurately describes all behavior.
Evidence IDs are generated from semantic content. The target's display name and local path are excluded, but other parameters, results, or paths within results may still affect the digest. This identity design facilitates saving and exchange, but requires understanding what it proves: digest matching checks content consistency, not engine correctness or interpretation correctness.
Snapshots further bind target, provider, analysis configuration, operation, and parameters. The ability to read live state cannot be disguised by historical cache; queries relying on implicit cursors or documents need extra constraints. Cache hit rates are only discussable after those conditions hold.
Unknown issues have independent versions and states. An issue can be verified resolved, or withdrawn, or excluded from scope. The latter two do not prove the fact is established. For teams delivering analysis conclusions, this distinction should enter review, not stay only in model prompts.
Observation Requires Execution
Key questions left by static analysis need experiments to reduce. REA's browser, Inspector, PTY, LLDB, GDB, and Frida modules provide different observation paths, each with explicit impact scope.
Passively attaching to a page to read info differs from launching an app, clicking a button, or loading an instrumentation script — each involves different state changes. After an action, one must separately confirm whether screenshot, DOM, network, storage, and other collection items succeeded; action success cannot substitute for collection completeness.
Process exit, output close, and cleanup completion each have their own observation conditions. Client timeout may only end the wait; background work may continue. After the process leader exits, descendant processes may persist. PIDs can be reused; a single number cannot confirm termination authority.
REA uses run tokens, process identity, and resource owners to manage these boundaries. During shared startup, one waiter cancelling should not interrupt other callers; when the last waiter leaves, the producer must finish cleanup. Cleanup failure retains the original owner so subsequent retries can address unreleased resources.
This code adds state complexity. Concurrency, cancellation, and final teardown combinations are hard to cover with normal-path tests. But reverse engineering tasks can have high single-run cost; erroneously restarting an analyzer or leaving background processes lets the next investigation inherit an unexplainable environment. Long-session systems must bear this engineering cost.
How to Use REA
Codex, DeepSeek Harness, and REA can combine via MCP. There is no need to implement another agent loop just to integrate reverse engineering capability.
Harness handles model, tool execution, context, session, and plugin lifecycle; REA handles analysis target, engines, and evidence. Both have sessions with different meanings. A model session saving tool results does not mean REA's process and target state are fully persisted.
In Codex, use REA's setup to view registered plans, then confirm the application. Manual method: configure Codex MCP to launch rea mcp and set appropriate call timeouts for native analysis. One can also simply give Codex the GitHub URL and let it install.
Efficiency Must Be Measured Empirically
Larger analysis scale demands distinguishing computation completion from result usability.
Full application graphs and Evidence can be large. MCP carries both text and structured content, constrained by transfer budgets, JSON encoding, and string representation. Feeding the model all results may spend most cost on irrelevant modules.
REA provides summaries, supported paginated views, and evidence export. When exceeding transfer budget, some paths retain full results and return a reference for continued reading. The analysis is not compressed into a smaller fact set; the delivery method changes.
But pagination has a cost. The model may discover a tool, read the summary, fetch several pages, then retry due to a wrong choice. Each reply is smaller, yet total calls, context, and latency for the whole task may increase. REA's own experiment logs record this mixed result: reduced reply bytes did not stably prove lower total tokens or time.
Therefore, performance evaluation should use the complete process of the same question as the unit: can baseline tools answer; does REA improve correctness; how many failures and retries; total tokens, time, and process-family memory. Cold start and session reuse must be separated. Without this controlled comparison, output compression is only a local optimization.
Closed-Source Boundaries Are Shifting
The title's claim needs a discussable scope. Closed source as a distribution and commercial form will persist; user access to original source and the ability to deduce partial implementation logic are gradually separating.
Bytes, resources, interfaces, and runtime behavior delivered locally provide investigation inputs. Agents can continuously exploit these inputs, reducing manual cost of search, query, organization, and local implementation. Functions previously rarely analyzed due to time may enter more people's investigation scope.
This change weakens some advantages built on information asymmetry. For functions that can be independently described with limited I/O, we must re-estimate the cost of understanding and rewriting them. Mere implementation complexity or code invisibility no longer suffices to justify that estimate.
Full products retain different cost structures. Compatibility, exception handling, version evolution, and continuous verification do not complete alongside function explanation. Remote execution, unavailable data, and unobserved paths do not automatically appear from local files. Analysis tools can report boundaries but cannot conjure missing inputs.
From a technical management perspective, we should adjust both ends: when researching external software, tighten investigation questions and acceptance scope; when evaluating our own products, reduce reliance on implementation obscurity, and factor verifiable behavior quality and sustainable maintenance capability into investment decisions.
REA has connected reverse engineering tools, structured evidence, and agent invocation, while preserving failures, ambiguities, and unknowns in code. We can use this capability to shorten investigations, while requiring every functional explanation to trace its source and every reproduction conclusion to state its coverage. Conclusions lacking source or coverage declarations should remain in the investigation phase, not proceed directly to implementation specs or acceptance reports.
However, reverse engineering commercial software may trigger legal risks, and the community has already reported Codex bans due to reverse engineering activities.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architecture and Beyond
Focused on AIGC SaaS technical architecture and tech team management, sharing insights on architecture, development efficiency, team leadership, startup technology choices, large‑scale website design, and high‑performance, highly‑available, scalable solutions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
