Reverse Engineering as Evidence, Not Guesswork
REA—short for “Reverse Engineer Anything”—is a local CLI and MCP system for investigating software whose source is unavailable or insufficient. It connects an AI coding agent to analysis of native binaries, JavaScript and Electron applications, .NET assemblies, websites, packages, and selected runtime behavior. This opening chapter asks a simple question: what does REA add beyond a decompiler or a collection of inspection commands? The answer is a way to move from a feature someone wants to understand to a defensible body of evidence, while keeping the limits of that evidence visible.
That distinction matters because reverse engineering begins with an asymmetry. A person can see a search box, an offline mode, a file format, or a native interface behaving in a particular way. They may have the executable or application bundle, but not the source code, build settings, design notes, or original names. The visible feature is an outcome; the implementation that produced it is hidden behind layers of code, resources, metadata, dispatch, and runtime state. A readable fragment of pseudocode can offer a clue, but it does not automatically identify the whole feature, prove that the routine runs on the observed path, or tell us which parts of the result are stable enough to recreate.
The gap is larger than “source code versus no source code.” A feature may be distributed across a user-interface resource, a controller, a storage layer, a native library, and a remote service. Names may be stripped or misleading. A call may be direct in one build and indirect in another. A package may contain several components with different identities. Runtime behavior may depend on inputs that a static artifact never records. The first plausible explanation therefore competes with other explanations. Reverse engineering is not only a decoding task; it is a process of deciding which relationships the available evidence actually supports.
REA is designed around that gap. Its subject is not one disassembler and not a promise that every application can be recovered. It is the investigation system that places different analysis capabilities behind a shared, evidence-bearing interface. That makes the practical problem more precise: how can an agent investigate a target deeply enough to explain a feature, without quietly converting partial observations into certainty?
The feature is visible; the mechanism is not
Imagine asking an agent to understand how search works in a desktop Notes application and then build a comparable version with TypeScript and SQLite. The useful answer is not a list of strings containing “search.” It needs a path from a clue to the code and data relationships that make the feature possible. REA’s documented investigation model therefore moves through several kinds of work: identify the target, locate promising strings or procedures, follow cross-references, reconstruct callers and callees, inspect control flow, and decompile the routines that remain relevant. The agent then uses those findings in its normal coding environment to implement a version adapted to a different product and stack.
Each step reduces a different uncertainty. A string search can suggest vocabulary but usually produces many candidates. A cross-reference can show where a value is used, but not necessarily why. Callers and callees expose context, while a function dossier or pseudocode view can make one portion of the path readable. A graph can reveal that several pieces are connected, yet still leave a dynamic dispatch or runtime condition unresolved. The investigation becomes reliable when these observations agree around a specific question and when their disagreements remain visible.
The division of labor is important. REA handles the analysis stages: opening a target, asking providers for observations, connecting those observations, and returning the evidence that supports them. The agent performs the product-specific reconstruction. It decides how to translate an observed behavior into new requirements, data structures, tests, and code. REA does not automatically clone the application, and it does not claim to recover the original source. Its output may include pseudocode, assembly, symbols, strings, metadata, graphs, and runtime observations, but those are materials for reasoning rather than a time machine back to the source repository.
This also explains why a tool catalog alone is not enough. An analyst needs to know what question each operation answers and how its result can be combined with the next one. A search operation finds candidates; a reference operation connects a candidate to code; a function or graph operation gives structure to that code; a decompilation operation offers a more readable representation. The value emerges from the relationship among those observations. A good investigation narrows uncertainty step by step instead of treating the first plausible output as the conclusion.
The same logic applies outside native binaries. A JavaScript application may be understood through modules, imports, routes, IPC channels, storage relationships, and static semantic links. A web page may be inspected through a bounded browser observation. A managed assembly may expose metadata and CIL without being executed. A package or firmware image may need to be inventoried before a contained component is analyzed. The target changes, but the question remains: which observation can support the next claim, and what does it leave unresolved?
Decompile, understand, recreate
REA describes its investigation as three connected activities: decompile, understand, and recreate. They should not be collapsed into one.
Decompile means recovering readable representations and structural clues from an artifact. For a native program, that may include instructions, strings, names, references, and pseudocode. For a JavaScript application, it may mean reconstructing a graph of modules and relationships without running the extracted code. For a managed artifact, it may mean reading metadata and CIL directly from the bytes. Decompilation and decoding make hidden structure more approachable, but their output is shaped by the provider, the target format, available metadata, and the parts of the artifact that can be resolved.
A readable representation is therefore a working surface, not a guarantee about the original. A decompiler may simplify control flow, assign names, or leave an indirect relationship unresolved. A managed reconstruction may resemble a source-language method while remaining a derived representation of metadata and CIL. A JavaScript graph may identify a unique static target while saying nothing about whether a user ever reached it. REA’s useful contribution is to keep the representation tied to the artifact and producer that generated it, so later reasoning does not lose the conditions under which it was obtained.
Understand means relating those clues to a question. A routine that mentions a database API is not necessarily the routine that implements the feature of interest. An apparent call edge may be ambiguous or statically resolved without ever being executed. A module may contain a route or literal while the runtime chooses another path. Understanding requires following relationships and testing alternative explanations against the evidence. It is the stage where provenance, coverage, and unknowns become as important as readability.
Recreate means using the resulting model to build something new. That model may be strong enough to guide a compatible feature, document an undocumented format, write migration notes, or design differential tests. It is still an adaptation. A new implementation has its own architecture, constraints, and product decisions. REA can show how far the original behavior has been understood; it cannot certify that a reconstruction is identical merely because the pseudocode looks persuasive.
The separation is practical, not philosophical. If an agent treats decompiled text as original source, it may copy provider mistakes, miss a native or dynamic boundary, or encode an inference as a requirement. If it treats a static path as proof of execution, it may build around a code path that the application never reaches in the relevant scenario. If it treats missing output as evidence that a feature does not exist, it may confuse limited coverage with absence. A reconstruction can still be useful under uncertainty, but the uncertainty must shape the tests and the claims.
One investigation, many authorities
REA’s central promise is therefore not that every provider speaks with one voice. It is that different authorities can participate in one investigation without being falsely merged. A target is opened with an identity and a declared analysis context. A selected provider or auxiliary reader contributes observations. Shared workflows connect them. The resulting records retain the producer, the locations or identities it observed, the confidence and coverage of the result, and the limitations that qualify it.
That model gives an agent a better handoff than an opaque answer. Evidence-producing MCP tools return the result together with a complete Evidence record, and the same record can remain available in the session for a later trace or comparison. Missing evidence is treated as unknown rather than silently converted into an empty list or a negative conclusion. Derived relationships are kept distinct from directly observed facts. In other words, the system tries to preserve the difference between “the bytes decode to this,” “these structures support this relationship,” and “this separately authorized run observed this event.”
A claim is also shaped by its authority. Static artifact inspection can establish properties of bytes, metadata, or recovered structure. Passive browser observation can report what was visible in a selected target during a bounded attachment window. A controlled process capture can compare the behavior of a declared run, but it does not become a sandbox merely because it records terminal and filesystem evidence. These authorities can be related, but correlation is not automatically causation. A strong investigation names the transition from one kind of evidence to another instead of hiding it.
The architecture preview follows from that requirement. The CLI and MCP server are two entry points into shared application workflows. A session layer routes requests to providers, while contracts and domain models carry provider-neutral identities and evidence states. Some providers overlap: multiple deep engines may be able to analyze the same native target. Others are disjoint: an artifact reader, browser observer, managed-code parser, or firmware adapter answers a different kind of question. The former need an explicit selection policy; the latter can contribute alongside the selected deep provider while retaining their own provenance.
This is why REA’s practical implication extends beyond reverse engineering. It offers a way for an AI agent to work with incomplete technical knowledge without hiding the incompleteness. The agent can ask a narrower question, switch to an authority that can answer it, compare two authenticated observations, or stop and mark the missing evidence. The result is not certainty by automation. It is a more disciplined path from a visible behavior to an explanation that can be inspected, challenged, and improved.
The rest of this series develops that path. It first examines what REA’s Evidence model actually lets a reader claim. It then follows the investigation lifecycle and the architecture that keeps CLI, MCP, sessions, and providers aligned. From there, it turns to deterministic provider choice, native feature tracing, application graphs, browser observation, managed and packaged artifacts, and controlled behavioral comparisons. The practical judgment throughout is the same: before using an analysis result to build, compare, or decide, identify what was observed, who produced it, what conditions shaped it, and what remains unknown.