Skip to content
The hosted workspace is open by invitation.

AI reverse engineering with byte-identical verification

relumea analyzes stripped binaries with an AI agent, then recompiles each recovered function with the original toolchain and compares it with the binary, so you know which results are exact.

call 07 of 09rename_functiongated

The agent called a tool that changes data, so the run is paused until you decide.

{ "function_id": 3, "name": "decode_config", "actor": "agent" }
→ rename_function
Nothing is written while it waits.
Illustrative. The run is a sample, not a capture.

284 tools in the registry. 134 are read-only and run as soon as the agent calls them. The other 150 change data, so the run pauses until you approve the call.

272compiler toolchains7,546tests44example targets

read-only 134gated 150

Triage, matching, decompilation and remediation in one workspace

For stripped binaries with no source or symbols, from first triage to detection rules.

Agentic malware analysis
Identity, imports, capabilities, protocols and ATT&CK mapping in one run, with a threat score, family detection against your own reference samples and a written summary.
run_conversation_agent
Function matching
Match functions against your own corpus, compare candidates side by side and carry names across to the binary you are working on.
resembl · get_matches
AI decompilation
Decompiler output with model-proposed names, comments and types, each journaled and revertible.
rebrew decompile · get_decompilation
Automated remediation
A YARA rule, Snort 2 rules per network indicator, a STIX 2.1 bundle, an SBOM and a PDF report, generated from the same scans.
remediation · export_sbom · report-pdf

What relumea adds

Works with your tools

Ghidra
renames as a runnable Python script
IDA Pro
renames as an IDA Python script
Binary Ninja
renames as a JSON document
MCP
every registry tool, for agent clients
REST API
the API the web workspace uses
CLI
reportal, from a terminal
SBOM
CycloneDX, SPDX or CSV per artifact
Detection
YARA, Snort 2 and STIX 2.1

One triage run, call by call

The agent runs triage tools in order and cites the evidence for each finding. In this run 8 read-only calls ran without asking; the rename waited for an analyst's approval.

Illustrative sample · updater_svc.exe

Task
Triage updater_svc.exe: find the persistence mechanism and the C2 send routine.
Target
PE · x86_32 · mingw-14.2.0-win32 · 412 functions · sha256 a7ed6974787de73373b3ca48d32faaf6611b6745ed362e85599282d68c1489d4
  1. 01get_pe_inforead-only
    { "binary_id": 1 }
    PE · x86_32 · 4 sections · 196,608 bytes
  2. 02get_importsread-only
    { "binary_id": 1 }
    106 imports from 5 libraries
  3. 03get_capabilitiesread-only
    { "binary_id": 1 }
    networking · persistence · process-injection
  4. 04get_protocols_scanread-only
    { "binary_id": 1 }
    http
  5. 05get_threat_reportread-only
    { "binary_id": 1 }
    3 ATT&CK techniques · software type · threat score
  6. 06get_decompilationread-only
    { "function_id": 3 }
    fcn.00401a20 · 10 lines of C
  7. 07rename_functiongated
    { "function_id": 3, "name": "decode_config", "actor": "agent" }
    journal_action 31 · name_history row written

    The run paused here until an analyst approved the rename.

  8. 08get_matchesread-only
    { "function_id": 3 }
    8 candidates from your corpus
  9. 09get_remediationread-only
    { "binary_id": 1 }
    YARA rule

Findings

From the import table and strings. Each finding lists the import that triggered it.

  • networkinghigh
    capabilities · WinHttpSendRequest
  • persistencehigh
    capabilities · RegSetValueExA
  • process-injectionhigh
    capabilities · CreateRemoteThread
  • anti-debug-apihigh
    hardening · IsDebuggerPresent
  • httphigh
    protocols · WinHttpOpen
  • T1071 Application Layer Protocolhigh
    threat · WinHttp* + WS2_32
  • T1547 Boot or Logon Autostartmedium
    threat · RegSetValueExA on a Run key
  • T1055 Process Injectionhigh
    threat · CreateRemoteThread

Byte-identical verification

Function matching and AI decompilation give you a likely answer. relumea checks it: the recovered C is compiled with the same compiler and flags as the target, and the output is compared with the original bytes. Point at a line on either side to see how source and instructions correspond.

Illustrative sample · updater_svc.exe

Recovered source

cfg/decode.c

Line 6 → 8 instructions, 22 bytes

89 d1 8b 74 24 14 83 e1 03 c1 e1 03 d3 ee 89 f1 32 0c 13 88 0c 13

Original bytes

mingw-14.2.0-win32
54 / 54 bytes identical · EXACTdecode_config · 0x00401a20

From stripped binary to verified source

One function from a stripped PE, run through real tools. The decompiler output is correct but hard to read. The corrected C adds names, types and the original loop structure, and compiles to the same 60 bytes.

Sample function · real compiler and decompiler output

1

Original assembly

0x00401000 · 60 bytes · no symbols
  1. 0040100055push ebp
  2. 0040100189e5mov ebp, esp
  3. 0040100356push esi
  4. 004010048b550cmov edx, dword [ebp + 0xc]
  5. 004010078b4508mov eax, dword [ebp + 8]
  6. 0040100a53push ebx
  7. 0040100b8b5d10mov ebx, dword [ebp + 0x10]
  8. 0040100ef7d0not eax
  9. 0040101001d3add ebx, edx
  10. 0040101239dacmp edx, ebx
  11. 004010147420je 0x401036
  12. 004010160fb60amovzx ecx, byte [edx]
  13. 0040101942inc edx
  14. 0040101a31c8xor eax, ecx
  15. 0040101cb908000000mov ecx, 8
  16. 0040102189c6mov esi, eax
  17. 0040102383e001and eax, 1
  18. 00401026f7d8neg eax
  19. 00401028d1eeshr esi, 1
  20. 0040102a252083b8edand eax, 0xedb88320
  21. 0040102f31f0xor eax, esi
  22. 0040103149dec ecx
  23. 0040103275edjne 0x401021
  24. 00401034ebdcjmp 0x401012
  25. 004010365bpop ebx
  26. 00401037f7d0not eax
  27. 004010395epop esi
  28. 0040103a5dpop ebp
  29. 0040103bc3ret
2

Decompiler output

Ghidra (rz-ghidra)
  1. uint32_t __cdecl fcn.00401000(int32_t arg_4h, char *arg_8h, int32_t arg_ch)
  2. {
  3. uint8_t uVar1;
  4. uint32_t uVar2;
  5. int32_t iVar3;
  6. uint8_t *puVar4;
  7. // [00] -r-x section size 4096 named .text
  8. uVar2 = ~arg_4h;
  9. puVar4 = (uint8_t *)(arg_8h + arg_ch);
  10. while ((uint8_t *)arg_8h != puVar4) {
  11. uVar1 = *arg_8h;
  12. arg_8h = (char *)((uint8_t *)arg_8h + 1);
  13. uVar2 = uVar2 ^ uVar1;
  14. iVar3 = 8;
  15. do {
  16. uVar2 = -(uVar2 & 1) & 0xedb88320 ^ uVar2 >> 1;
  17. iVar3 = iVar3 + -1;
  18. } while (iVar3 != 0);
  19. }
  20. return ~uVar2;
  21. }
3

Corrected C

names, types and structure
  1. uint32_t crc32_update(uint32_t crc, const uint8_t *buf, size_t len)
  2. {
  3. crc = ~crc;
  4. while (len--) {
  5. crc ^= *buf++;
  6. for (int bit = 0; bit < 8; bit++)
  7. crc = (crc >> 1) ^ (0xEDB88320u & -(crc & 1));
  8. }
  9. return ~crc;
  10. }
Names
fcn.00401000 → crc32_update, arg_4h and uVar2 → crc, arg_8h → buf, arg_ch → len, iVar3 → bit
Types
int32_t → uint32_t, char * → const uint8_t *, int32_t → size_t
Structure
end-pointer loop → while (len--), countdown do/while → for over 8 bits, uVar1 and puVar4 dropped
4

Recompiled assembly

mingw-w64 gcc 16.2.0 -Os
  1. 0040100055push ebp
  2. 0040100189e5mov ebp, esp
  3. 0040100356push esi
  4. 004010048b550cmov edx, dword [ebp + 0xc]
  5. 004010078b4508mov eax, dword [ebp + 8]
  6. 0040100a53push ebx
  7. 0040100b8b5d10mov ebx, dword [ebp + 0x10]
  8. 0040100ef7d0not eax
  9. 0040101001d3add ebx, edx
  10. 0040101239dacmp edx, ebx
  11. 004010147420je 0x401036
  12. 004010160fb60amovzx ecx, byte [edx]
  13. 0040101942inc edx
  14. 0040101a31c8xor eax, ecx
  15. 0040101cb908000000mov ecx, 8
  16. 0040102189c6mov esi, eax
  17. 0040102383e001and eax, 1
  18. 00401026f7d8neg eax
  19. 00401028d1eeshr esi, 1
  20. 0040102a252083b8edand eax, 0xedb88320
  21. 0040102f31f0xor eax, esi
  22. 0040103149dec ecx
  23. 0040103275edjne 0x401021
  24. 00401034ebdcjmp 0x401012
  25. 004010365bpop ebx
  26. 00401037f7d0not eax
  27. 004010395epop esi
  28. 0040103a5dpop ebp
  29. 0040103bc3ret
60 / 60 bytes identical · EXACTcrc32_update · 0x00401000

Decompilation projects

Each binary becomes a project: a tree of recovered C files that builds with the original toolchain, and a verdict for every function. When a function is close, relumea searches compiler flags and source variants for an exact match, and uses angr and Z3 to prove equivalence where the bytes still differ. This project covers all 412 functions, including the ones that do not match yet.

Illustrative sample · updater_svc.exe

85.2%
matched or proven · 351 of 412 functions
EXACT198
Recompiled bytes identical to the original.
RELOC141
Identical except for addresses the linker fills in.
PROVEN12
Bytes differ; equivalence proven with angr and Z3.
NEAR2
At least 60% of bytes match; the rest is usually register allocation, instruction order or a compiler flag.
STUB3
Under 60% of bytes match: not implemented yet, or control flow differs.
unattempted56
Not attempted yet. Counted in the total.
Function ledger
NameSizeVerdict
svc_Main1,842STUB
cfg_LoadEncrypted412RELOC
decode_config54EXACT
net_OpenSession288RELOC
http_SendBeacon640NEAR
reg_PersistRunKey196EXACT
inj_WriteRemote720PROVEN
anti_IsDebugged48EXACT

Data handling and control

What the workspace does with your binaries, and what the agent is allowed to change.

Stored by content hash
Each binary is kept under its sha256 in your workspace.
Model features are opt-in
AI routes stay off until the workspace configures a model.
Writes wait for approval
The 150 tools that change data pause the run until a person approves the call.
Every write is journaled
Approved changes record the value they replaced, and revert_journal_entry undoes them.

Frequently asked questions

Matching, the model, packers and the tools you already use.

How is this different from similarity-based function matching?

Similarity matching suggests what a function probably is. relumea uses it as a starting point, then recompiles the recovered C and compares it with the original, so each function ends with a verdict instead of a score.

Does relumea depend on an LLM?

The capability, protocol, hardening and secrets scans, the ATT&CK mapping, the matching and the byte comparison run without a model. The model is opt-in: it drives the agent and proposes names, comments and types for stored decompilation.

What happens when a function does not match?

Its verdict records how close it got (NEAR or STUB), and it stays in the project and in the coverage figure.

How do you handle packed malware?

Filetype detection names the packer from section names, entry-point bytes, constants and entropy. LZEXE and UPX can be unpacked on request; a packer that rewrites its own stub is not identified.

Does it work with Ghidra, IDA Pro and Binary Ninja?

Yes. Renames export as a Python script for Ghidra or IDA and as a JSON document for Binary Ninja.

Can it match across architectures and file formats?

Only coarsely. Platform and architecture scope is inferred from the stored fingerprint, and results say it is inferred.

Do you support firmware?

Yes. Firmware has its own extraction and scanning pipeline, separate from PE analysis.

Join the waitlist

The hosted workspace is open by invitation. We’ll email you one.

We store your email address and the date you joined, and use them only to send you an invitation.