Agent-assisted reverse engineering, verified byte for byte.
relumea puts an agent on a stripped executable. Read-only calls run at once; the 143 that write pause the run for you. Recovered C is recompiled with the original toolchain and diffed against your binary.
Agent run sample workspace
illustrative · not a customer binaryTriage updater_svc.exe. Name the persistence path and the C2 send. Prove the decoder.
one line from the analyst · 8 tool calls · the model never touches the binary itselfThe sample, one screen
412 functions in address order. Filled means the recovered C recompiled to the same bytes; empty means not attempted yet.
| .text | 0x00401000 | 98,304 | RX | 93.0% | code. Every function on this page. |
|---|---|---|---|---|---|
| .rdata | 0x00419000 | 32,768 | R | — | read-only data. Scanner output, digests, technique tables. |
| .data | 0x00421000 | 24,576 | RW | — | writable state. Names, types and signatures you decide. |
| .reloc | 0x00427000 | 8,192 | R | — | base relocations, resolved at link time. |
Identity
PE header updater_svc.exe
mingw-14.2.0-win32Capabilities, protocols, hardening
Import table and strings only. Every finding names the import or string that fired it.
Imports
106 entriesfingerprintpe-infofiletypecapabilitiesprotocolsbehaviorhardeningsecretssecurity-scanthreatremediationcrypto-scanstructsunstripmatchlineagerelatedcompositionbenchmarkFindings
import evidence: high · string only: medium| Scan | Finding | Evidence | Conf. |
|---|---|---|---|
| capabilities | networking | WinHttpSendRequest | high |
| capabilities | persistence | RegSetValueExA | high |
| capabilities | process-injection | CreateRemoteThread | high |
| hardening | anti-debug-api | IsDebuggerPresent | high |
| protocols | http | WinHttpOpen | high |
| threat | T1071 Application Layer Protocol | WinHttp* + WS2_32 | high |
| threat | T1547 Boot or Logon Autostart | RegSetValueExA on Run key path | medium |
| threat | T1055 Process Injection | CreateRemoteThread | high |
ATT&CK mapping
Matched against a curated technique table. Software type and threat score are computed from the stored scans.
Techniques
threat.classify_binaryDecompiled C
Decompiler output, stored before the agent reads it.
Recovered source cfg/decode.c
{ "function_id": 412 }unsigned int decode_config(unsigned char *buf, unsigned int len, unsigned int key)
{
unsigned int i, sum = 0;
for (i = 0; i < len; i++) {
buf[i] ^= (unsigned char)(key >> ((i & 3) * 8));
sum += buf[i];
}
return sum ^ 0x5A5A;
}The paused write
Renaming writes to the function table, so the run stops with the exact call it wants to make. Approve it and the rename lands, journaled, with the previous name recorded. Refuse it and the refusal goes back to the model as the tool result; the run continues. Nothing is written while it waits.
Run paused
destructiveHint · confirm_conversation_run{ "function_id": 412, "name": "decode_config", "source": "ai" } → rename_function- rename_function → awaiting_approval
- nothing is written until you answer
- a refusal is fed back to the model, not raised as an error
Corpus matches
Ranked against every binary already in the workspace. Stub rows stay visible.
Coverage rebrew status
last verify231/236mingw-14.2.0-win32Functions sample rows
illustrative| VA | Name | Size | Status | Source |
|---|---|---|---|---|
| 0x00401020 | svc_Main | 1842 | STUB | svc/main.c |
| 0x00401840 | cfg_LoadEncrypted | 412 | RELOC | cfg/load.c |
| 0x00401a20 | decode_config | 54 | EXACT | cfg/decode.c |
| 0x00401c80 | net_OpenSession | 288 | RELOC | net/session.c |
| 0x00402210 | http_SendBeacon | 640 | NEAR | net/beacon.c |
| 0x00402a90 | reg_PersistRunKey | 196 | EXACT | persist/runkey.c |
| 0x00403100 | inj_WriteRemote | 720 | PROVEN | inj/remote.c |
| 0x004038c0 | anti_IsDebugged | 48 | EXACT | anti/debug.c |
| 0x00403b40 | str_WideToUtf8 | 92 | EXACT | util/wide.c |
| 0x00404100 | buf_Grow | 128 | RELOC | util/buf.c |
| 0x00404880 | crc32_update | 176 | EXACT | util/crc32.c |
| 0x00405120 | svc_Install | 384 | RELOC | svc/install.c |
Byte comparison
The original toolchain recompiles the recovered C. Bytes are diffed instruction by instruction: EXACT, RELOC or PROVEN.
decode_config 0x00401a20
mingw-14.2.0-win32 ·0x00401a20unsigned int decode_config(unsigned char *buf, unsigned int len, unsigned int key)
{
unsigned int i, sum = 0;
for (i = 0; i < len; i++) {
buf[i] ^= (unsigned char)(key >> ((i & 3) * 8));
sum += buf[i];
}
return sum ^ 0x5A5A;
}Remediation artifacts
Artifacts
built from the stored scansWhy relumea
Legacy tools analyze one binary at a time and hand you a similarity score. relumea runs the analysis for you, stops when a write is involved, and proves the result against the compiler that produced the target.
No source. No symbols. No debug info.
A stripped PE is the normal input. Headers, imports and strings are the evidence, and the scans and the model work on the bytes as shipped.
The agent asks before it writes.
124 tools are read-only and run on request. The other 143 carry MCP's destructiveHint, so the run pauses on the call itself and waits for a person.
A match is decided by a compiler.
Recovered C goes back through the original toolchain and the bytes are compared. Similarity scores are a starting point; this is the verdict.
One workbench, four capabilities
From a single uploaded artifact to a signed-off rename. Each capability names the engine or tool call behind it.
Fits the toolchain you already run
Renames and signatures leave as runnable scripts for the disassembler you have open. Agents reach the same store over MCP; everything else over the REST API or the CLI.
Where it gets used
Malware triage
capabilities, ATT&CK mapping, threat score, family detection from your own reference samples
Vulnerability research
security findings ranked by reachability, attack surface mapped from stored scans
Third-party assurance
library identification and an SBOM for software you did not build
Supply chain
CycloneDX or SPDX per artifact, repeated across a fleet
Legacy modernisation
recompile an old binary and byte-match it to prove the source is the original
Firmware
carve and scan device firmware images
Questions
Is this just an LLM?
No. Capabilities, protocols, hardening, secrets, ATT&CK mapping, matching and the byte comparison are deterministic scans and a compiler. The model is optional and reads decompilation already stored.
Where do my binaries go?
Into your workspace, content-addressed and scoped to you. AI features are opt-in; the model sees stored artifacts, not the raw sample.
How do you handle packed malware?
Filetype detection names the packer from section names, entry-point bytes, constants and entropy, and reportal unpacks LZEXE and UPX itself. A packer that rewrites its own stub is reported as unidentified rather than guessed at.
Do you support firmware?
Yes. Firmware extraction and scanning is a separate path from PE analysis.
Can you match across architectures and file formats?
The platform and architecture scope is a coarse filter derived from the stored fingerprint, not a guarantee. Every payload says so.
What can I export?
YARA, Snort 2, STIX 2.1, an SBOM as CycloneDX, SPDX or CSV, a PDF report, C headers for recovered types and signatures, and rename scripts for Ghidra, IDA Pro and Binary Ninja.
Do you integrate with Ghidra, IDA and Binary Ninja?
As exports rather than plugins: renames and signatures leave as runnable scripts for those three tools. Agents reach the same store over MCP, and everything else over the REST API or the CLI.
Can I undo what the agent wrote?
Yes. Every mutating call returns a journal action, so revert_journal_entry undoes it later, from another process.
Verdicts
rebrew test writes the status. Neither an operator nor the model assigns it.
One registry, three surfaces
The same 267 tools back the web UI, the CLI and the MCP registry. An agent run calls the same handlers, under the same journal, with the same revert.
// it asked for these; reads ran at once
get_pe_info(binary_id=1)
get_imports(binary_id=1)
get_capabilities(binary_id=1)
get_decompilation(function_id=412)
// this one paused the run
rename_function(function_id=412)
// and the write came back revertible
journal_action: 31$ reportal add-binary updater_svc.exe
Registered 1 binary, queued scans
$ reportal conversation-run 4 "triage this"
paused: rename_function wants approval
$ reportal conversation-confirm 4
$ reportal match 1 --min-similarity 70
$ reportal journal revert 31- Conversations, with Approve call and Reject call on a paused run
- Binary details, hashes, sections, security mitigations
- Functions, matches, side-by-side diff
- Types, signatures, rename history
- Journal with per-row revert
Run control
Approval comes from the tool, not the prompt
Read-only tools run the moment the agent asks. The other 143 carry MCP's destructiveHint, so the pause happens on the call. A prompt cannot override the annotation.
A refused call returns as a tool result
A rejected call comes back to the model as the tool result. The run continues; the next call is usually read-only.
Bounded and cancellable
A run stops at agent.MAX_TOOL_CALLS and streams its state as server-sent events. cancel_conversation_run halts it at the next step boundary.
Every write is revertible
The rename at step 05 returns a journal_action. revert_journal_entry undoes it later, from another process; the descriptor is stored on disk.
272 compilers, containerized
MSVC 1.0 through 11, Borland, Watcom, Delphi, MinGW, GCC, Clang, IDO, PSY-Q, MWCC, ProDG and more. The original compiler decides a match.
Stripped binaries
Scans and model work on the bytes as shipped. A miss is reported as a miss.
Waitlist
hosted · no installStop scoring it. Start proving it.
One email when the hosted workspace opens. Bring a stripped binary and a corpus; the engine behind this page already runs.