Most people who try to reverse-engineer a binary open it in a hex editor, scroll for twenty minutes, and quit.
They don't know which tool loads the file. They don't know which prompt pulls the logic out. They don't know how to turn a wall of assembly into something they can actually rebuild.
This 11-step course will turn Claude Opus 5.5 into an open-source anything machine.
Follow my Substack to get fresh AI alpha:
Reverse engineering is not about cracking. It is about understanding a thing well enough to build your own.
On October 7, 2026 Amjad Masad, the CEO of Replit, posted a single line:
https://x.com/amasad/status/2107671204639465961
under it, a developer called @morluto replied with the receipt: a set of tools that let agents drive Hopper and Ghidra and go very far.
That project is REA, and it crossed 110,000 GitHub stars in days.

https://github.com/morluto/rea
The claim is not hype. The same week, an open-source project called WordCraft shipped a clean-room rebuild of Microsoft & Adobe in pure Rust:

It was built by observing Word & Adobe behavior and reading public file-format specs, never its code.

This course shows you the whole path from a sealed binary to a rebuild like that, with Opus 5.5 doing the reading.
01. The engine - how an agent reads a binary
Opus 5.5 cannot run a disassembler on its own. It reads text and writes text.
Reverse engineering with an agent works because a tool sits between the model and the binary: it loads the file into a real disassembly engine, exposes the results as callable functions, and lets the model ask questions.

That tool is REA, and the engine underneath is Hopper, Ghidra or IDA.
The loop is simple and it repeats: the model asks REA to inspect the target, REA returns findings with the exact evidence behind them (addresses, bytes, pseudocode, call sites), and the model uses those findings to ask the next question or to write and test a reimplementation.

Everything runs locally on your machine. Nothing is uploaded except the findings the model needs to reason, and every conclusion is tagged as an observation, an inference, or an unknown.
**
02. The install - rea-agents plus one disassembler
Setup registers REA's MCP server with your agent and installs the matching workflow instructions.
One command does it, it shows you every change before writing anything, and it backs up what it touches.

You bring your own disassembler: Hopper on macOS is the easiest path, Ghidra is free and cross-platform, IDA if you already own it.
1# 1. Register REA with your agent (Claude Code, Codex, Cursor, Gemini CLI...)2npx rea-agents setup # shows planned changes, asks before writing34# 2. A deep-analysis provider. Hopper is the smoothest on macOS;5# setup can install it after approval. Ghidra and IDA are bring-your-own.6# 3. Install the rea CLI for terminal use and scripting7npm install --global rea-agents8rea --help910# 4. Restart your agent, then confirm the tools are live11claude12> /mcp13 rea: connected14 open_binary, binary_overview, analyze_function, decompile,15 list_procedures, search, xrefs, trace, inspect_artifact,16 analyze_javascript_application, inspect_managed_artifact ...
Requirements are modest: Node.js 22 or newer and npm. Native analysis needs one of the three engines; static JavaScript and .NET inspection need no engine at all. Keep REA current, because releases ship frequent fixes.
1# Reverse-engineering house rules ( CLAUDE.MD )23## Authority4- Only analyze targets I own or am authorized to examine. State the basis once.5- Every claim is tagged: observation (saw it), inference (deduced it), or unknown.6- Cite the evidence: address, bytes, pseudocode or call site. No unsourced claims.78## Workflow9- Start with the smallest overview, not a full dump. Expand only on a concrete gap.10- Reuse the open session; never re-run an identical analysis.11- Separate static facts from runtime facts. Never imply execution from static reads.1213## Reconstruction14- Build from BEHAVIOR and public specs, never from copied code or assets.15- Keep an obligation ledger: every recovered behavior needs a passing test before "done".
Opus 5.5 ships five effort levels: low, medium, high, xhigh and max. Use:
- Medium to inspect and navigate
- High to annotate ordinary functions
- Max for obfuscated code and anything with heavy pointer math.
Effort is the single biggest quality knob in this whole course.
03. The router - 20 target types, one tool each
The first mistake beginners make is reaching for a disassembler when the target is an Electron app whose JavaScript is sitting right there.
REA routes the target to the right tool, and so should your first prompt. Name the file, name the feature, and let the agent pick the entry tool.

1I want to understand how [FEATURE] works in [APP], which lives at [ABSOLUTE PATH].23First, tell me what kind of target this is (native, Electron/JS, .NET, Go, APK, WASM)4and pick the right REA tool to open it. Do not start deep analysis yet.56Then give me a one-paragraph map: what the app is built with, how big it is, and7where you would look first for [FEATURE]. Keep observations, inferences and unknowns8separate, and cite evidence for anything you claim.
Pointing REA at an Electron app returns modules, imports and IPC boundaries in seconds with no disassembler at all.
Pointing it at a native Mach-O or ELF opens a Hopper database and gives you the harder but deeper native path. Knowing which one you are in saves hours.
https://x.com/_vmlops/status/2106690704244420687
04. Recon - overview, strings and the call graph
Do not open any code yet. First ask REA for a map of the whole file. One command tells you what kind of machine it runs on, how many functions are inside, and all the readable text buried in it.
That text is the fastest clue you have: web addresses, error messages and feature names tell you what the app does before you read a single line of code.
1rea.open_binary { path: "/Applications/Target.app/Contents/MacOS/Target" }2rea.binary_overview {}3 arch: arm644 functions: 1,284 identified5 segments: __TEXT __DATA __LINKEDIT6 entry: _main @ 0x1000051c078rea.search { query: "http" } # strings + code refs9 0x10004a2c0 "https://api.target.app/v3/sync"10 0x10004a300 "Authorization: Bearer "11 0x10004a330 "offline cache miss, falling back"1213rea.xrefs { address: "0x100012ab0" } # who calls this?14 147 references -> core config loader, called everywhere
REA also counts how many times each function gets called (that count is called its cross-references, or xrefs).

A function called 147 times is the heart of the app and deserves your best effort. One called twice is a small helper you can ignore until it matters. Start at the top of that list and work down.
05. Decompile - one function into pseudocode
Now pick one of those busy functions and turn it into something you can read. A decompiler takes the raw machine instructions and rewrites them as code close to C.
It looks rough: names like var_28, tangled logic, casts everywhere. But you can read it, and readable is all Opus 5.5 needs.
Run it from the command line to save the result, or from inside a chat.
1# Decompile one function by address, as JSON you can pipe or save2rea decompile /Applications/Target.app/.../Target 0x100012ab0 \3 --provider hopper --json > fn_config_loader.json45# Or search for a function by name and follow references6rea function /path/to/Target parseConfig --provider hopper --json7rea xrefs /path/to/Target 0x100012ab0 --provider hopper --json8rea trace /path/to/Target "sync" --provider hopper --json
1// 0x100012ab0 xrefs: 1472void sub_100012ab0(void* arg0) {3 void* var_20 = objc_msgSend(cls_NSJSONSerialization,4 sel_JSONObjectWithData_options_error, arg0, 0x0, 0x0);5 if (var_20 != 0x0) {6 void* var_28 = objc_msgSend(var_20, sel_objectForKey, @"endpoints");7 void* var_30 = objc_msgSend(var_20, sel_objectForKey, @"auth_mode");8 void* var_38 = objc_msgSend(var_20, sel_objectForKey, @"retry_count");9 objc_msgSend(g_sharedConfig, sel_setEndpoints, var_28);10 objc_msgSend(g_sharedConfig, sel_setAuthMode, var_30);11 objc_msgSend(g_sharedConfig, sel_setRetryCount,12 objc_msgSend(var_38, sel_intValue));13 }14}
REA's own showcase follows a sound call in the old game DX-Ball down to the helper that decides left-right audio balance, then turns the half-finished pseudocode into C.

The result passes all 3,205 original test cases and reproduces every one of the 63 compiled bytes.

Full walk-through on rea.tools/showcase.
06. Annotate - make Opus name every variable
That rough code is only half the job. Now hand it to Opus 5.5 and ask it to explain and clean it up.
It renames the cryptic variables to real ones, says in a sentence what the function is for, spots the pattern it follows, and even flags bugs the original app left in.
Paste this prompt with the Claude:
1Here is decompiled pseudocode from a function with 147 cross-references.23For this function:41. Rename every variable to a meaningful name based on how it is used.52. State its purpose in one sentence.63. List the data structures it reads and writes.74. Name the pattern (singleton, factory, state machine, observer...).85. Rewrite it as clean, idiomatic Swift (or the language the calling9 conventions imply), with doc comments.106. Flag any missing error handling, input validation or security check.1112Think it through at xhigh effort before answering: reason about what each13value is before you commit to names. Mark anything you are unsure of.1415[paste pseudocode]
Decompilation gives you what the code does. Opus 5.5 gives you why, and the names to rebuild it.
https://x.com/0x0SojalSec/status/2108389060192706674
https://x.com/0x0SojalSec/status/2108031166502896035
Not every target needs a disassembler. REA's Notion showcase finds the clipboard feature in the app's JavaScript, follows it through the Electron layers into the main process, and shows exactly how it builds the rich clipboard, a full trace with no assembly at all. See
07. Obfuscation - the Tigress benchmark
Some apps are built to resist exactly what you are doing. Their code is scrambled on purpose: the logic is shuffled, the text is encrypted, and fake branches are added to waste your time.
This is called obfuscation, and it is the one place even the best model struggles. Elastic Security Labs measured it, pointing Claude Opus at the Tigress scrambler across 20 tasks. Keep these numbers in mind.

Two practical lessons sit in those numbers.
- First, a failed attempt costs about twice a successful one, because the model keeps trying harder and harder before it gives up, so set a spending limit per function and stop early.
- Second, strip the junk out of the decompiled code before you send it (a free tool called Caveman removes about 75% of it) so the model spends its attention on the real logic, not the filler.
The five tricks you will actually meet, and what each looks like when you open the code:

1This function looks obfuscated. Work at max effort.231. Identify the techniques present (control-flow flattening, opaque predicates,4 dead code, string encryption, function splitting) and point to where each shows5 up in this specific code.62. Resolve them: remove dead branches, evaluate opaque predicates, unflatten the7 dispatch, decrypt inline strings if the key is recoverable.83. Show the clean function that remains.94. Rate your confidence 1-10. Below 6, tell me exactly which parts are uncertain10 and what neighboring context would resolve them. Do not guess silently.1112[paste obfuscated pseudocode]
08. The swarm - a controller running workers
A single chat cannot read 500 functions well. It forgets what it saw, calls the same thing by three different names, and starts contradicting itself.
The fix is a small team: one controller chat that hands out the work, and several worker chats that each take one function.
The controller holds the big picture and stitches the pieces back together.

You do not build anything special for this, the two prompts below are the whole setup.
1You are a reverse-engineering controller. The function map is in functions.json2(address, name, size, xref_count).341. Cluster functions by call-graph proximity; order clusters by xref count.52. Dispatch each cluster to a worker. Never analyze a function yourself.63. Inject already-resolved structs into each worker's brief so names stay consistent.74. When a worker returns confidence below 6, queue a second pass with context8 from its resolved neighbors.95. Track cumulative token spend and report it after each cluster.
1You are a worker. You get one decompiled function and the structs resolved so far.2Return exactly: address, purpose, confidence (1-10), structs_used, structs_new,3clean_source, flags. Reuse existing struct names; never invent a second name for4a struct the controller already gave you. One function only. Stop when done.
https://x.com/victor_explore/status/2109466356454510612
09. Clean room - four rules that keep it legal
A clean-room rebuild means you copy what the app does, never the code inside it. Get this right and what you ship is fully yours. Get it wrong and you are carrying someone else's copyright.

Four rules keep you on the safe side, and the WordCraft team checks all four automatically on every build.
- Observe, never copy. Run the target black-box, watch what it does, screenshot only its own window. Never read, disassemble or paste its code. Never copy wording beyond plain feature names.
- Specs, not sources. File formats come from public standards (OOXML is ECMA-376 / ISO 29500, plus the published RTF and ODF specs), never from reading a competitor's parser or any GPL/LGPL code.
- Original assets only. Every icon, font, template and sound is drawn in code, public-domain, or openly licensed, with a row in an attribution file. A CI check fails the build otherwise.
- Separate the two jobs. One agent recovers behavior and writes a spec. A different context implements from the spec alone, never looking at the original analysis. This separation is the clean-room boundary.
1From the completed analysis, write a clean-room specification for a reimplementation.23Describe BEHAVIOR only. Include: every public interface, the data model, each4user-visible feature as a testable requirement, the file formats read and written5(by observed behavior and public spec), and the error-handling behavior.67Do NOT include: addresses or offsets, variable names from the decompile, assembly,8or anything copied from the original. A developer who never saw the binary must be9able to implement a compatible version from this document alone.1011Output markdown with sections: Architecture, Data Model, Public API, File Formats,12Test Cases.
Working from a description is not just legal cover. It lets you make the right choices for your own language and needs, instead of inheriting decisions the original author made decades ago.

WordCraft is faster than Word in places precisely because it did not copy Word's insides.
10. Crafting Apps - twelve pro tools, one method
WordCraft is not a one-off. It is one app in a shelf of twelve from the ArtCraft team, each a clean-room rebuild of a tool you already pay for, all written from scratch in Rust and shipped free and open on GitHub.
Their own line is "Twelve apps. One craft", and the one craft is the method from step 9: watch the original, read the public specs, build a fresh version from behavior alone.

The payoff of that shared method is the same everywhere. No Electron: each app is native on macOS, Windows and Linux, and all but FilmCraft also run in a browser tab through WebAssembly.
And because every action inside them is a named command, all twelve are drivable by an AI agent straight away.
Every Craft app is built the same way, and the shape is worth copying. Each is stacked in layers, each layer using only the one beneath it, from basic measurements at the bottom to the on-screen window at the top.
Here are WordCraft's layers:

And every action is just a named command, so a person clicking, a keyboard shortcut, and an AI agent all trigger the exact same thing. That is what makes any of them drivable by an agent.
1drive WordCraft over MCP23# Headless document automation4claude mcp add wordcraft -- wordcraft-cli mcp56# Or drive the running desktop app7wordcraft --control 7981 &8claude mcp add wordcraft-app -- wordcraft-cli mcp --connect 127.0.0.1:7981910# Tools: list_commands, execute, batch, type_text, select_text,11# inspect_document, render_page, save_document (+ screenshot/click/key live)12> Open report.docx, make every heading 14pt bold, export to PDF13 ✓ select.all-headings -> 12 selected14 ✓ format.font-size 14 · format.bold15 ✓ export report.pdf (selectable text, bookmarks kept)
https://x.com/yuhasbeentaken/status/2109235513102057828
11. Verify and ship - prove parity, expose MCP
You never had the original's source code, so you cannot compare it line by line.
You compare behavior instead: give both the original and your rebuild the same inputs and check they produce the same output.
1Build a behavioral test harness comparing the original binary and my rebuild.23Generate 50 inputs: 30 normal, 10 edge (empty, max size, unicode, special chars),410 error (malformed, missing fields, corrupt). Run each through both. Compare output5byte-for-byte where possible, semantically otherwise. Report match rate, a divergence6list, and a severity for each (cosmetic / behavioral / critical). Save to report.md.
This is also the most convincing proof you can show anyone (the RE slot at the very top of the article).

Then release your rebuild the same way REA and WordCraft did: as an MCP server, so the next person's agent can drive it just like you drove REA.
Give each function a clear name and description, wrap it in a simple command-line tool, and make it install in one line.
https://x.com/0xMovez/status/2108884063515746410
And test as you go, not at the end, because a mistake found after you have built three layers on top of it is far more expensive to fix.
Six mistakes that waste a weekend
- Opening a disassembler on an Electron app.If the JavaScript is right there, route to analyze_javascript_application and skip the native path entirely.
- Dumping everything before reading anything.Ask REA for a summary first. Pulling the whole app at once buries the real logic in noise and runs up your bill.
- Reading functions in file order.Sort by cross-reference count. The 147-xref function is the architecture; the 2-xref helper can wait.
- Grinding stage-3 obfuscation.The benchmark solves 0% of multi-layer. Set a budget, bank the context from neighbors, come back later.
- Letting the model copy code into your rebuild.That breaks the clean room. Spec first in one context, implement from the spec in another.
- Shipping without a parity report."I think it matches" is not evidence. 50 behavioral tests and a match rate are.
Conclusion:
Install REA. Read the binary. Rebuild it as your own.
Route the target, map its surface, decompile the hot functions, let Opus 5.5 name everything, break the obfuscation worth breaking, scale it with a swarm, then spec it clean and ship the rebuild over MCP.
Eleven steps. One model. Zero copied code.





