[GH-ISSUE #1558] [Feature] Java Reverse Engineering #525

Open
opened 2026-10-15 18:25:50 +00:00 by bsakaguchi · 16 comments
Owner

Originally created by @HypergamyDenier on GitHub (Oct 10, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/1558

Originally assigned to: @N0zoM1z0 on GitHub.

Before submitting

  • I searched the open and closed issues and pull requests for a related proposal.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Native analysis or decompilation

Current limitation

REA does not currently have a Java RE domain. Users and agents working with compiled Java classes cannot ask REA for class/member identity, decompile .class to .java, search references, or apply deobfuscation/bytecode edits through normalized contracts. Native binary analysis does not understand JVM class identity or bytecode. Android/DEX work in https://github.com/morluto/rea/issues/717 is related, but it does not cover standalone .class/.java inspection. Today this requires manually running GUI tools or separate CLIs, which is not agent-friendly and lacks evidence, lifecycle, resource bounds, and catalog integration.

Use cases

  • Given a .class file or an archive of .class files (like a .jar file), inspect class name, methods, fields, annotations, constants, and bytecode.
  • Decompile a selected .class to .java, with bytecode fallback when decompilation fails or is incomplete.
  • Search for class/member references across a set of .class files.
  • Deobfuscate Java bytecode and compare original vs transformed .class/.java output.
  • Edit or patch Java bytecode into a new artifact without mutating the original.
  • Use alongside Android/DEX work in https://github.com/morluto/rea/issues/717 when obfuscated Java-like bytecode needs heavy lifting from Java RE tooling.

Current tools are insufficient because they are mostly GUI-first, CLI-first, or library-only; they are not normalized into REA evidence, provider/version/options, cancellation, and resource limits.

Desired outcome and success criteria

  • REA exposes a Java RE domain with named contracts for:
    • class identity: internal class name/descriptor, source file, major/minor version, access flags, annotations;
    • member identity: fields, methods, full parameter/return prototype, raw names and aliases;
    • decompilation: selected .class to .java, with provider/version/options, source locations, failures, and explicit unknowns;
    • xrefs/search: class/member lookup and static references where the provider supports it;
    • bytecode edit/deobfuscation: produce a new artifact, preserve original, record transformations and limitations.
  • Observable outputs include .class-derived evidence and .java decompiled output. Decompiled Java is derived analysis, not original source.
  • Failed or incomplete decompilation falls back to bytecode evidence or a precise limitation.
  • Tests use source-built fixtures for .class files, overloads, inner classes, obfuscated names, missing dependencies, malformed inputs, and decompiler failures.
  • Bring-your-own tools: no automatic JDK/SDK installation or host-default changes. (Although for Unix systems https://sdkman.io/ is great)
  • Consideration of EVERY tool in the references section of this issue! These tools ALL in some shape or form can be implemented in this project. Clone and analyze them one by one and either directly incorporate them or take every useful feature and port them to a master domain toolkit.

Authority boundaries and non-goals

  • Static analysis only by default. Do not execute untrusted Java bytecode as part of inspection unless risk is explained to the user and an agreement is made for a SANDBOXED execution of certain elements such as key derivation.
  • No target mutation. Edits/deobfuscation must write a new artifact and record provenance this is so as to preserve original jar in case of mistakes.
  • No automatic JDK, SDK, or provider installation without user agreement.
  • Provider caches/workspaces must be isolated and cleaned up, system resources should be used wisely.
  • Initial supported platform: host-side static analysis of .class/.java where the chosen provider runs; no guarantee of Windows/macOS/Linux parity until tested.
  • Out of scope: full Java build system integration, application server deployment analysis, arbitrary code execution, and treating decompiled .java as authoritative original source.
  • Licensing for each provider must be checked before copying or redistributing. Optional tools remain optional.

Alternatives considered

Alternatives considered

  • Existing REA native binary analysis: does not model JVM .class identity or .java decompilation.
  • Android/DEX work in https://github.com/morluto/rea/issues/717: relevant but scoped to Android/DEX semantics; this request is for Java .class/.java.
  • Manual use of Recaf, Trinity, JByteMod, CFR, Vineflower, Fernflower, Krakatau, Procyon, ASM, and deobfuscators: useful, but not integrated into REA contracts, evidence, lifecycle, or agent workflows.

Possible direction

  • Add a thin Java RE domain with provider adapters behind named contracts. Start with read-only .class inspection and .class-to-.java decompilation.
  • Candidate providers/references:
    • Recaf, RecafMCP, Recaf-Launcher for class inspection/editing and MCP prior art.
    • CFR, Vineflower, Fernflower, Krakatau, Procyon for decompilation.
    • java-deobfuscator, Threadtear, Diobf/Deobfuscator, ZKM-27-Full-Deobfuscator for deobfuscation follow-ups.
    • Trinity and JByteMod-Remastered as GUI/interface references or optional providers.
    • ASM OW2 for bytecode modification or Mokapot (https://github.com/henryhchchc/mokapot) which is rust based and has SSA intermediate representation via MokaIR (NOTE! Mokapot HAS NOT REACHED V1.0 YET! So consider ASM as well as other tools in references https://github.com/henryhchchc/mokapot/issues/29)
  • Reuse Android/DEX work from https://github.com/morluto/rea/issues/717 where it overlaps, but keep Java .class/.java contracts distinct from DEX member identity.
  • Maintainers need to decide before implementation:
    1. Is Java RE a new top-level domain or a provider set under an existing domain?
    2. Which contracts are stable enough for a first PR?
    3. Which providers are recommended vs optional, and how to handle their licenses?
    4. How to avoid duplicating https://github.com/morluto/rea/issues/717 and future DEX work?

References

NOTE: This section is treated as references AND useful tools (of which there are many) which this project could greatly benefit from!

(Slight relevance)

JVM Specifications (required for agents to know in order to actually modify the stack without verifier errors):
https://docs.oracle.com/javase/specs/
(Java VM) https://docs.oracle.com/javase/specs/jvms/se27/jvms27.pdf (More important and necessary)
(Java Language) https://docs.oracle.com/javase/specs/jls/se27/jls27.pdf

Originally created by @HypergamyDenier on GitHub (Oct 10, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/1558 Originally assigned to: @N0zoM1z0 on GitHub. ### Before submitting - [x] I searched the open and closed issues and pull requests for a related proposal. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Native analysis or decompilation ### Current limitation REA does not currently have a Java RE domain. Users and agents working with compiled Java classes cannot ask REA for class/member identity, decompile .class to .java, search references, or apply deobfuscation/bytecode edits through normalized contracts. Native binary analysis does not understand JVM class identity or bytecode. Android/DEX work in https://github.com/morluto/rea/issues/717 is related, but it does not cover standalone .class/.java inspection. Today this requires manually running GUI tools or separate CLIs, which is not agent-friendly and lacks evidence, lifecycle, resource bounds, and catalog integration. ### Use cases - Given a `.class` file or an archive of `.class` files (like a .jar file), inspect class name, methods, fields, annotations, constants, and bytecode. - Decompile a selected `.class` to `.java`, with bytecode fallback when decompilation fails or is incomplete. - Search for class/member references across a set of `.class` files. - Deobfuscate Java bytecode and compare original vs transformed `.class`/`.java` output. - Edit or patch Java bytecode into a new artifact without mutating the original. - Use alongside Android/DEX work in https://github.com/morluto/rea/issues/717 when obfuscated Java-like bytecode needs heavy lifting from Java RE tooling. Current tools are insufficient because they are mostly GUI-first, CLI-first, or library-only; they are not normalized into REA evidence, provider/version/options, cancellation, and resource limits. ### Desired outcome and success criteria - REA exposes a Java RE domain with named contracts for: - class identity: internal class name/descriptor, source file, major/minor version, access flags, annotations; - member identity: fields, methods, full parameter/return prototype, raw names and aliases; - decompilation: selected `.class` to `.java`, with provider/version/options, source locations, failures, and explicit unknowns; - xrefs/search: class/member lookup and static references where the provider supports it; - bytecode edit/deobfuscation: produce a new artifact, preserve original, record transformations and limitations. - Observable outputs include `.class`-derived evidence and `.java` decompiled output. Decompiled Java is derived analysis, not original source. - Failed or incomplete decompilation falls back to bytecode evidence or a precise limitation. - Tests use source-built fixtures for `.class` files, overloads, inner classes, obfuscated names, missing dependencies, malformed inputs, and decompiler failures. - Bring-your-own tools: no automatic JDK/SDK installation or host-default changes. (Although for Unix systems https://sdkman.io/ is great) - Consideration of EVERY tool in the references section of this issue! These tools ALL in some shape or form can be implemented in this project. Clone and analyze them one by one and either directly incorporate them or take every useful feature and port them to a master domain toolkit. ### Authority boundaries and non-goals - Static analysis only by default. Do not execute untrusted Java bytecode as part of inspection unless risk is explained to the user and an agreement is made for a SANDBOXED execution of certain elements such as key derivation. - No target mutation. Edits/deobfuscation must write a new artifact and record provenance this is so as to preserve original jar in case of mistakes. - No automatic JDK, SDK, or provider installation without user agreement. - Provider caches/workspaces must be isolated and cleaned up, system resources should be used wisely. - Initial supported platform: host-side static analysis of `.class`/`.java` where the chosen provider runs; no guarantee of Windows/macOS/Linux parity until tested. - Out of scope: full Java build system integration, application server deployment analysis, arbitrary code execution, and treating decompiled `.java` as authoritative original source. - Licensing for each provider must be checked before copying or redistributing. Optional tools remain optional. ### Alternatives considered **Alternatives considered** - Existing REA native binary analysis: does not model JVM `.class` identity or `.java` decompilation. - Android/DEX work in https://github.com/morluto/rea/issues/717: relevant but scoped to Android/DEX semantics; this request is for Java `.class`/`.java`. - Manual use of Recaf, Trinity, JByteMod, CFR, Vineflower, Fernflower, Krakatau, Procyon, ASM, and deobfuscators: useful, but not integrated into REA contracts, evidence, lifecycle, or agent workflows. ### Possible direction - Add a thin Java RE domain with provider adapters behind named contracts. Start with read-only `.class` inspection and `.class`-to-`.java` decompilation. - Candidate providers/references: - Recaf, RecafMCP, Recaf-Launcher for class inspection/editing and MCP prior art. - CFR, Vineflower, Fernflower, Krakatau, Procyon for decompilation. - java-deobfuscator, Threadtear, Diobf/Deobfuscator, ZKM-27-Full-Deobfuscator for deobfuscation follow-ups. - Trinity and JByteMod-Remastered as GUI/interface references or optional providers. - ASM OW2 for bytecode modification or **Mokapot (https://github.com/henryhchchc/mokapot) which is rust based and has SSA intermediate representation via MokaIR (NOTE! Mokapot HAS NOT REACHED V1.0 YET! So consider ASM as well as other tools in references** https://github.com/henryhchchc/mokapot/issues/29) - Reuse Android/DEX work from https://github.com/morluto/rea/issues/717 where it overlaps, but keep Java `.class`/`.java` contracts distinct from DEX member identity. - Maintainers need to decide before implementation: 1. Is Java RE a new top-level domain or a provider set under an existing domain? 2. Which contracts are stable enough for a first PR? 3. Which providers are recommended vs optional, and how to handle their licenses? 4. How to avoid duplicating https://github.com/morluto/rea/issues/717 and future DEX work? ### References **_NOTE: This section is treated as references AND useful tools (of which there are many) which this project could greatly benefit from!_** - Related Android/DEX proposal: https://github.com/morluto/rea/issues/717 - Recaf: https://github.com/Col-E/Recaf - RecafMCP: https://github.com/sniperrich/RecafMCP - Recaf-Launcher: https://github.com/Col-E/Recaf-Launcher - Java Deobfuscator: https://github.com/java-deobfuscator/deobfuscator - Threadtear: https://github.com/loerting/threadtear - Deobfuscator: https://github.com/Diobf/Deobfuscator - Deobfuscator v1: https://github.com/Diobf/Deobfuscator/tree/v1 - ZKM-27-Full-Deobfuscator: https://github.com/unleg1t/ZKM-27-Full-Deobfuscator - Trinity: https://github.com/firstfault/Trinity - **JByteMod-Remastered: https://github.com/jbytemod/JByteMod-Remastered** - **JByteMod-Remastered MCP: https://github.com/jbytemod/plugin-mcp** - Fernflower: https://github.com/jetBrains/fernflower - Vineflower: https://github.com/Vineflower/vineflower - CFR: https://github.com/leibnitz27/cfr - Krakatau: https://github.com/Storyyeller/Krakatau - Procyon: https://github.com/nbauma109/procyon - ASM OW2: https://asm.ow2.io/ - ASM Javadoc: https://asm.ow2.io/javadoc/index.html - ASM4 guide: https://asm.ow2.io/asm4-guide.pdf - CAFED00D: https://github.com/Col-E/CAFED00D (Obfuscation resilient Java class reader/writer) - **Mokapot: https://github.com/henryhchchc/mokapot (**MokaPot** is a Rust library for parsing, inspecting, and analyzing JVM bytecode. It provides a Java class-file model and **MokaIR**, an **SSA** intermediate representation for analyzing method behavior.) Not quite ready! https://github.com/henryhchchc/mokapot/issues/29** - Cafe Compare: https://github.com/loerting/cafecompare (Compare 2 java artifacts) - Java-Process-Inspector: https://github.com/0WhiteDev/Java-Process-Inspector (toolkit for inspecting, decompiling, analyzing, and modifying running JVM applications in real time) - JNI Detranspiler: https://github.com/0WhiteDev/Detranspiler (Recover Java source from JNI-native binaries) - JNIC Virtualization: https://github.com/YumeGod/JNIC-Virtualization (dump native library from JNIC obfuscated jars and add a compatible custom loader to it.) - JStudio: https://github.com/Tonic-Box/JStudio (A Java reverse engineering and static analysis IDE for analyzing, decompiling, and transforming Java bytecode.) - JDBG: https://github.com/roger1337/JDBG (Java Dynamic Reverse Engineering and Debugging Tool) - C2J Java JNI native deobfuscator: https://github.com/gaoyu06/c2j-native-deobfuscator (deobfuscates JNIC, j2cc, and radioegor146 native obfuscator) - Jattach: https://github.com/jattach/jattach (JVM Dynamic Attach utility. A utility to send commands to a JVM process via Dynamic Attach mechanism.) - Java mitmproxy: https://github.com/appium/mitmproxy-java (A bridge between Python's mitmproxy and Java programs. Built on top of mitmproxy-node) - Bindbg by Binclub/x4e (devs of Binscure): https://github.com/binclub/bindbg (Bringing Dynamic Analysis to Java) - Java Dumper by accessmodifier364: https://github.com/accessmodifier364/Dumper (Extract the classes dynamically loaded in Java applications.) - JnicX: https://github.com/Exeos/JnicX (Tool for extracting platform binaries from compressed jnic bin format) - Toolbox by JVMInspect: https://github.com/JVMInspect/toolbox (A collection of very **useful** tools for Java reverse engineering!) - SSVM: https://github.com/xxDark/SSVM (Java VM running on a JVM. Useful for sandboxing java code for reverse engineering) - Antares-Lite: https://github.com/SpartanB312/Antares-Lite (Agentic JVM JAR bytecode analysis) (Slight relevance) - https://github.com/stars/Col-E/lists/reverse-engineering-obf (Massive list of useful Java reverse engineering tools as well as that of some other languages. I recommend checking this out) - https://github.com/3000IQPlay/obfuscator-list (A list of java obfuscators and code hiding tools) - Useful notes on Java bytecode: https://github.com/Col-E/Useful-Things - Chinese java reverse engineering wiki: https://github.com/CakeSlayers/JavaReversingWiki - Dalvikus: https://github.com/loerting/dalvikus (Mainly for Android) (Additional MCPs for recaf; https://github.com/GzSakura1338/Recaf_MCP and https://github.com/Naptila/recaf-mcp) **JVM Specifications** (required for agents to know in order to actually modify the stack without verifier errors): https://docs.oracle.com/javase/specs/ **(Java VM)** https://docs.oracle.com/javase/specs/jvms/se27/jvms27.pdf (More **important** and necessary) (Java Language) https://docs.oracle.com/javase/specs/jls/se27/jls27.pdf
Author
Owner

@HypergamyDenier commented on GitHub (Oct 10, 2026):

Please do reply to this issue and suggest further tools for the java reverse engineering domain. I believe I have mentioned most of the well known tools as well as a few lesser known gems.

<!-- gh-comment-id:6101411758 --> @HypergamyDenier commented on GitHub (Oct 10, 2026): Please do reply to this issue and suggest further tools for the java reverse engineering domain. I believe I have mentioned most of the well known tools as well as a few lesser known gems.
Author
Owner

@morluto commented on GitHub (Oct 10, 2026):

@N0zoM1z0 @kaoru0822-kitauji plese take a look at this

<!-- gh-comment-id:6101875573 --> @morluto commented on GitHub (Oct 10, 2026): @N0zoM1z0 @kaoru0822-kitauji plese take a look at this
Author
Owner

@morluto commented on GitHub (Oct 11, 2026):

pinging again @N0zoM1z0 @kaoru0822-kitauji

<!-- gh-comment-id:6113175788 --> @morluto commented on GitHub (Oct 11, 2026): pinging again @N0zoM1z0 @kaoru0822-kitauji
Author
Owner

@SpartanB312 commented on GitHub (Oct 11, 2026):

Wow. I just published Antares-Lite for two days, and I saw the reference

<!-- gh-comment-id:6115326760 --> @SpartanB312 commented on GitHub (Oct 11, 2026): Wow. I just published Antares-Lite for two days, and I saw the reference
Author
Owner

@moeyinlo commented on GitHub (Oct 12, 2026):

should be more careful when it comes to cybersecurity. Some of the tools mentioned are not appropriate to be pushed to public

<!-- gh-comment-id:6116354377 --> @moeyinlo commented on GitHub (Oct 12, 2026): should be more careful when it comes to cybersecurity. Some of the tools mentioned are not appropriate to be pushed to public
Author
Owner

@zhangtbj commented on GitHub (Oct 12, 2026):

We are also waiting for this feautures :)

<!-- gh-comment-id:6117456843 --> @zhangtbj commented on GitHub (Oct 12, 2026): We are also waiting for this feautures :)
Author
Owner

@coygeek commented on GitHub (Oct 12, 2026):

Proposal for a first tracer-bullet slice, following this issue's "Start with read-only .class inspection and .class-to-.java decompilation", narrowed to the decompilation half. It comes from the decompiler survey in #2258 and the gap mapping in https://github.com/morluto/rea/issues/2258#issuecomment-6130226337 (gap 2).

Slice: one read-only CLI/MCP operation that takes a local .class or .jar, an optional class or package-prefix selector, and paging, and returns Java source per class from one bring-your-own engine.

  • Every source unit is labeled as inference, with engine name, version and options, input SHA-256, internal class name and class-file major/minor version in Evidence.
  • When a class or method fails, REA returns a failed or partial unit with the engine's reason plus bytecode evidence or a precise limitation. An engine's failure stub never counts as decompiled source.
  • Coverage counts requested, decompiled, partial, failed and skipped classes.
  • The engine runs as a supervised subprocess on a private copy with time, memory and output bounds, cancellation and cleanup. REA never loads target classes or installs an engine or JDK; doctor reports a missing engine or JDK.
  • Deferred to later slices: member/identity inspection, xrefs, deobfuscation, editing, a second engine, Kotlin output, WAR/EAR and nested JARs.

Two things on current main the slice has to handle:

  • classifyArtifactBytes (src/artifacts/inventory/ArtifactGraphConstruction.ts) and src/domain/binaryTarget.ts map the 0xCAFEBABE magic straight to mach-o-universal, so a JVM class file is classified as a universal Mach-O. Observed with rea-agents@6.4.0: rea inspect-artifact on a class-file header (magic CAFEBABE, major version 65) fails with target_unavailable, "truncated or invalid FAT architecture table". The slice needs byte-level disambiguation that keeps real fat Mach-O files working.
  • The JADX lane refuses anything that is not an APK (src/android/JadxProvider.ts), and #367's JVM scaffold was removed in c93422a89. No JVM path exists today.

Engine for the slice (checked 2026-10-12):

Vineflower CFR
License Apache-2.0 MIT
Latest release 1.12.0, 2026-04-29 0.152, 2021-12-11; master still active (2026-06)
Headless CLI java -jar vineflower.jar [args] <in> [<out>]; class, JAR, ZIP or folder; --only=<prefix>, --method-to-decompile java -jar cfr.jar <class/jar>; --outputdir, --jarfilter, --methodname
Class-file versions 1.12.0 tests include Java 25 fixtures 0.152 names versions up to Java 18; Java 25 switch patterns only on unreleased master (leibnitz27/cfr@0ebf01622)
Runtime Java 17+ for 1.11+ Very old JVMs (code targets Java 6)
Failure output --dump-bytecode-on-error (default on, usage) puts bytecode in the method body Comment plus a throw new IllegalStateException("Decompilation failed") stub, no bytecode

Vineflower looks like the better first engine. Its releases are current, it handles new class files, and bytecode-on-error output maps directly onto the fallback requirement. CFR would make a reasonable second engine for comparison. Widening the JADX lane is possible because JADX accepts .jar and .class, but REA's JADX lane is tied to APK admission and DEX-shaped contracts, and this issue asks to keep Java identity separate from DEX identity.

Maintainers: would you accept this slice, with Vineflower as the engine, as the scope for a first PR? CONTRIBUTING.md asks for that decision before a new provider is built.

<!-- gh-comment-id:6130457537 --> @coygeek commented on GitHub (Oct 12, 2026): Proposal for a first tracer-bullet slice, following this issue's "Start with read-only `.class` inspection and `.class`-to-`.java` decompilation", narrowed to the decompilation half. It comes from the decompiler survey in #2258 and the gap mapping in https://github.com/morluto/rea/issues/2258#issuecomment-6130226337 (gap 2). **Slice:** one read-only CLI/MCP operation that takes a local `.class` or `.jar`, an optional class or package-prefix selector, and paging, and returns Java source per class from one bring-your-own engine. - Every source unit is labeled as inference, with engine name, version and options, input SHA-256, internal class name and class-file major/minor version in Evidence. - When a class or method fails, REA returns a failed or partial unit with the engine's reason plus bytecode evidence or a precise limitation. An engine's failure stub never counts as decompiled source. - Coverage counts requested, decompiled, partial, failed and skipped classes. - The engine runs as a supervised subprocess on a private copy with time, memory and output bounds, cancellation and cleanup. REA never loads target classes or installs an engine or JDK; `doctor` reports a missing engine or JDK. - Deferred to later slices: member/identity inspection, xrefs, deobfuscation, editing, a second engine, Kotlin output, WAR/EAR and nested JARs. **Two things on current `main` the slice has to handle:** - `classifyArtifactBytes` (`src/artifacts/inventory/ArtifactGraphConstruction.ts`) and `src/domain/binaryTarget.ts` map the `0xCAFEBABE` magic straight to `mach-o-universal`, so a JVM class file is classified as a universal Mach-O. Observed with `rea-agents@6.4.0`: `rea inspect-artifact` on a class-file header (magic `CAFEBABE`, major version 65) fails with `target_unavailable`, "truncated or invalid FAT architecture table". The slice needs byte-level disambiguation that keeps real fat Mach-O files working. - The JADX lane refuses anything that is not an APK (`src/android/JadxProvider.ts`), and #367's JVM scaffold was removed in c93422a89. No JVM path exists today. **Engine for the slice (checked 2026-10-12):** | | [Vineflower](https://github.com/Vineflower/vineflower) | [CFR](https://github.com/leibnitz27/cfr) | |---|---|---| | License | Apache-2.0 | MIT | | Latest release | 1.12.0, 2026-04-29 | 0.152, 2021-12-11; master still active (2026-06) | | Headless CLI | `java -jar vineflower.jar [args] <in> [<out>]`; class, JAR, ZIP or folder; `--only=<prefix>`, `--method-to-decompile` | `java -jar cfr.jar <class/jar>`; `--outputdir`, `--jarfilter`, `--methodname` | | Class-file versions | 1.12.0 tests include Java 25 fixtures | 0.152 names versions up to Java 18; Java 25 switch patterns only on unreleased master (leibnitz27/cfr@0ebf01622) | | Runtime | Java 17+ for 1.11+ | Very old JVMs (code targets Java 6) | | Failure output | `--dump-bytecode-on-error` (default on, [usage](https://vineflower.org/usage/)) puts bytecode in the method body | Comment plus a `throw new IllegalStateException("Decompilation failed")` stub, no bytecode | Vineflower looks like the better first engine. Its releases are current, it handles new class files, and bytecode-on-error output maps directly onto the fallback requirement. CFR would make a reasonable second engine for comparison. Widening the JADX lane is possible because JADX accepts `.jar` and `.class`, but REA's JADX lane is tied to APK admission and DEX-shaped contracts, and this issue asks to keep Java identity separate from DEX identity. Maintainers: would you accept this slice, with Vineflower as the engine, as the scope for a first PR? CONTRIBUTING.md asks for that decision before a new provider is built.
Author
Owner

@HypergamyDenier commented on GitHub (Oct 12, 2026):

Hey @coygeek I personally believe this can definitely be better planned rather than having an LLM come up with the plan. This is genuinely something that requires human thought and understanding. Your plan is a little generic I must say.

<!-- gh-comment-id:6130525775 --> @HypergamyDenier commented on GitHub (Oct 12, 2026): Hey @coygeek I personally believe this can definitely be better planned rather than having an LLM come up with the plan. This is genuinely something that requires human thought and understanding. Your plan is a little generic I must say.
Author
Owner

@matbrgz commented on GitHub (Oct 12, 2026):

I opened focused companion proposals for the debugging side of this Java domain:

  • #2377 — offline inspection of compiler-emitted source-line/local-variable metadata in .class/JAR files. This gives bytecode offsets, local-slot scope ranges and explicit missing debug tables without treating decompiler line numbers as original source.
  • #2376 — a caller-selected JVM session through JDI/JDWP, with class-loader-qualified method identity, actual EventSet suspension policy, stop-scoped frame references and bounded value inspection.
  • #2378 — Android/ART attachment, adding explicit device, Android user and process-generation identity plus ownership of ADB forwarding resources.
  • #2379 — Java/JNI/native observation correlation, preserving independently verified module identities and distinguishing actual observed calls from static JNI bindings.

These can be specified and reviewed independently. #2377 is the static foundation; #2376 adds host-JVM runtime behavior; Android transport and JNI correlation need their own verification and scope decisions. The shared native debugger roadmap remains #1267.

For an initial JVM runtime lane, I propose attaching to one explicitly selected local endpoint where JDWP is already enabled, using a caller-installed JDK. Inspection would return raw fields and available locals without invoking toString/getters, evaluating arbitrary expressions, redefining classes or writing fields. Debugger attachment and suspension still have effects and must be declared. A socket endpoint or matching Java version does not prove that the running classes belong to a selected JAR.

The proposals include source-built fixture cases for overloads, duplicate class names in different class loaders, delayed class preparation, missing debug tables, exceptions, cancellation and disconnect. They are proposals, not claims of implemented provider support; substantial runtime-provider implementation for integration remains subject to the maintainer scope decision required by CONTRIBUTING.md.

Primary references: JVMS debug attributes, JDI EventSet, JDWP identity and frame lifetime, and Android debugger modes.

<!-- gh-comment-id:6132536919 --> @matbrgz commented on GitHub (Oct 12, 2026): I opened focused companion proposals for the debugging side of this Java domain: - #2377 — offline inspection of compiler-emitted source-line/local-variable metadata in .class/JAR files. This gives bytecode offsets, local-slot scope ranges and explicit missing debug tables without treating decompiler line numbers as original source. - #2376 — a caller-selected JVM session through JDI/JDWP, with class-loader-qualified method identity, actual EventSet suspension policy, stop-scoped frame references and bounded value inspection. - #2378 — Android/ART attachment, adding explicit device, Android user and process-generation identity plus ownership of ADB forwarding resources. - #2379 — Java/JNI/native observation correlation, preserving independently verified module identities and distinguishing actual observed calls from static JNI bindings. These can be specified and reviewed independently. #2377 is the static foundation; #2376 adds host-JVM runtime behavior; Android transport and JNI correlation need their own verification and scope decisions. The shared native debugger roadmap remains #1267. For an initial JVM runtime lane, I propose attaching to one explicitly selected local endpoint where JDWP is already enabled, using a caller-installed JDK. Inspection would return raw fields and available locals without invoking toString/getters, evaluating arbitrary expressions, redefining classes or writing fields. Debugger attachment and suspension still have effects and must be declared. A socket endpoint or matching Java version does not prove that the running classes belong to a selected JAR. The proposals include source-built fixture cases for overloads, duplicate class names in different class loaders, delayed class preparation, missing debug tables, exceptions, cancellation and disconnect. They are proposals, not claims of implemented provider support; substantial runtime-provider implementation for integration remains subject to the maintainer scope decision required by CONTRIBUTING.md. Primary references: [JVMS debug attributes](https://docs.oracle.com/javase/specs/jvms/se25/html/jvms-4.html), [JDI EventSet](https://docs.oracle.com/en/java/javase/26/docs/api/jdk.jdi/com/sun/jdi/event/EventSet.html), [JDWP identity and frame lifetime](https://docs.oracle.com/en/java/javase/25/docs/specs/jdwp/jdwp-spec.html), and [Android debugger modes](https://developer.android.com/studio/debug).
Author
Owner

@HypergamyDenier commented on GitHub (Oct 13, 2026):

I see that there are new companion issues which are intentionally narrow (obviously a good starting base for future work!), so I don’t think they each need to cover every referenced tool. But we have mentioned bytecode edit/deobfuscation in scope, and I don’t see a focused proposal for it yet. I think it would be worth opening one. ASM, CAFED00D/Recaf, Krakatau, JByteMod, and maybe Mokapot/MokaIR (FUTURE) all seem relevant. First implementation could be one provider, but the design should still map alternatives and limitations.

<!-- gh-comment-id:6144503896 --> @HypergamyDenier commented on GitHub (Oct 13, 2026): I see that there are new companion issues which are intentionally narrow (obviously a good starting base for future work!), so I don’t think they each need to cover every referenced tool. But we have mentioned bytecode edit/deobfuscation in scope, and I don’t see a focused proposal for it yet. I think it would be worth opening one. ASM, CAFED00D/Recaf, Krakatau, JByteMod, and maybe Mokapot/MokaIR (FUTURE) all seem relevant. First implementation could be one provider, but the design should still map alternatives and limitations.
Author
Owner

@moeyinlo commented on GitHub (Oct 14, 2026):

Recaf it self already manages an abstraction layer of class decompilers, and already has a human-readable assembly language for bytecode. Just manipulating bytecode just needs linking Recaf to LLMs, shouldn't be much work. It also provides several basic tools on searching reference or strings, which may be useful for analyzing obfuscated code

<!-- gh-comment-id:6160226340 --> @moeyinlo commented on GitHub (Oct 14, 2026): Recaf it self already manages an abstraction layer of class decompilers, and already has a human-readable assembly language for bytecode. Just manipulating bytecode just needs linking Recaf to LLMs, shouldn't be much work. It also provides several basic tools on searching reference or strings, which may be useful for analyzing obfuscated code
Author
Owner

@matbrgz commented on GitHub (Oct 14, 2026):

Adding an issue map and a concrete design for the bytecode transformation gap raised in this comment. The useful next step is to connect the tool list to stable analyst contracts, explicit provider boundaries and regression fixtures.

1. What the existing reports imply for the Java domain

Priority Concrete contract or behavior Existing issue evidence
Class identity before source reconstruction An exact archive occurrence, class digest, internal name, member name and JVM descriptor identify the input. Preserve case, duplicate entries and multi-release alternatives. A class-file parser and a decompiler must agree on that selected input. #2317, #3176, #1470, #1860, #1978, #2377
Truthful method coverage Distinguish Code present, native, abstract, transformed/inlined by the provider, failed decompilation, and an unsupported representation. A neighboring member's text or a failure stub must never count as the selected method's complete source. Preserve bytecode when source fails. #1846, #3443, #3488, #3489
Inventory without eager decompilation Read metadata once, index exact members, page selected results, and decompile only requested bodies. Cache against input digest, engine build/options, dependency profile and selected archive version. Report examined/returned/skipped/failed counts separately. #893, #901, #1850, #2852, #3134
Useful readiness and failure reasons Distinguish missing engine, incompatible JDK, bridge compilation failure, heap exhaustion, unsupported target and incomplete cleanup. Installation readiness cannot promise that a particular large input fits in memory. #1124, #1125, #2908, #2944, #3016, #3069, #3111, #3374, #3517
Runtime containers and resources JAR/WAR/EAR, nested archives, JMOD and JIMAGE need container identities and resource inventories independently of Java source reconstruction. Treat runtime/library classes separately from application-owned classes. #42, #367, #3571, #3490, #3459

These are proposed acceptance requirements. The issue index below records open/closed state; closure alone does not establish that a capability is shipped or still passes a real-provider regression. In particular, #367 is historical context, #2317 is a closed classification report, and #3176 reports another classification path. #2080 was closed as not planned and is not an approved implementation dependency.

2. A focused bytecode editing / general static deobfuscation design

I suggest a separately reviewable companion proposal with the following contract, rather than treating every upstream GUI or MCP command as part of REA's supported surface:

  1. Select and inspect: bind the operation to an immutable class/JAR digest, exact archive occurrence and method descriptor. Preserve the original bytes and raw names; display aliases do not change identity.
  2. Plan: return the requested edit or an allowlisted static transformation, the selected members, provider/version/options, required dependency classpath, and expected output. Applying an external rename map is a concrete possible first slice; explicitly account for unsupported reflection/resource-name references.
  3. Apply to a derived artifact: write a new output, never the original. Preserve a before/after ledger of entry digests, member identities, rename mappings, changed instructions and any removed or rewritten attributes. Keep input/output coverage and rejected transformations visible.
  4. Validate: parse the complete output and report structural/verifier checks supported by the chosen profile, unresolved dependencies, stack/frame failures, archive metadata and signature consequences. A valid output class does not prove behavioral equivalence, and regenerated source does not prove that no side effect moved. JVM execution-based verification would be a separate declared effect.
  5. Compare: show exact bytecode differences and optional reconstructed source side by side, with provider provenance. If evaluation of a decryptor or helper is required, return an execution requirement; do not silently run target code as a static transformation.

Source-built acceptance fixtures should include overloads, bridge/synthetic members, inner/nestmate classes, exception handlers, lambdas/bootstrap methods, missing dependencies, absent debug tables, invalid stack maps, duplicate and case-distinct ZIP entries, multi-release JARs and a signed JAR. Add a method with observable side effects to catch a reconstruction that looks plausible but changes their order. Record cancellation, output/heap limits and owned-workspace cleanup through both CLI and MCP.

The bytecode and verification model should follow the JVMS, with an explicit supported class-version profile. Multi-release selection and archive/signature handling should follow the JAR specification. Preserve unknown attributes as opaque evidence where supported; do not silently discard them or claim verifier support for an untested version.

3. Evaluate the tools by responsibility

The references in this issue cover several different jobs. A provider comparison should record the exact revision, callable headless interface, class-version support, dependencies, license, default rewrites, target execution/network effects, resource controls, failure output and verified fixtures for every candidate, including candidates ultimately rejected.

Responsibility Candidates already referenced here Evaluation needed
Workspace, inspection, assembly and editing Recaf and its MCP/launcher variants; JByteMod-Remastered/plugin-mcp; Trinity; JStudio; Antares-Lite Expose selected operations through REA contracts. Check import-time repair/normalization and script/plugin execution instead of assuming that opening a workspace preserves bytes.
Source reconstruction Vineflower, Fernflower, CFR, Procyon, Krakatau Start with one selected engine; add a second for disagreements. Compare failures and method attribution against bytecode, not source aesthetics. Kotlin/Scala/Groovy compiler output remains JVM bytecode and does not automatically become recovered original-language source.
Bytecode parsing, transformation and analysis ASM, CAFED00D, Recaf/assembler, Krakatau; Mokapot/MokaIR Preserve source spans and attributes, define verifier/dependency limits and distinguish a resilient parser's repairs from original input. MokaIR is an analysis candidate, not a substitute for proven class-file round trips.
General static transformation and comparison Java Deobfuscator, Threadtear, Diobf (including v1), Cafe Compare Evaluate individual transformations, their applicability and execution behavior; preserve mapping and change provenance. Obfuscator-specific references such as ZKM-27 need the same scope review, not automatic integration.
JVM observation and debugging Java-Process-Inspector, JDBG, Jattach, Bindbg, Dumper, JVMInspect/toolbox Coordinate with #2376. Process/class-loader identity, class-byte association, attach effects, frame lifetime and cleanup are separate from offline inspection.
JNI/native boundaries JNI Detranspiler, C2J, JnicX, JNIC-Virtualization Evaluate static inspection/extraction separately from execution or dedicated protection recovery. Reuse native providers for admitted native artifacts and #2379 for runtime correlation. Do not present native-to-Java reconstruction as original source.
Execution or protocol experiments SSVM, mitmproxy-java Running code in an interpreter remains execution; protocol interception remains a separate effect. Neither is a containment guarantee or a prerequisite for the initial static lane.
Android and reference collections Dalvikus, Android tools in #717, the JavaReversingWiki/Useful-Things/obfuscator-list/starred collections Useful research inputs and fixture ideas; record supported JVM versus DEX semantics independently. Lists are not provider support claims.

Recaf's documentation specifically describes multiple decompilers, assembly, automation, and automatic repairs during import. That makes original-versus-working-copy evidence a practical adapter requirement. Mokapot's documentation describes a class-file model and SSA analysis; its compatibility and stability need a pinned evaluation rather than a general maturity assumption.

Additional candidates worth adding to the inventory:

  • The JDK's Class-File API for parsing/generation/transformation and an independent comparison with ASM. Its models are lazy, so successful initial parsing is not proof that every attribute/body was examined; transformation options and class-hierarchy resolution also need explicit profiles.
  • javap as a caller-installed disassembly/debug-metadata baseline for source-built regression fixtures. Bind it to the exact member bytes rather than silently choosing a classpath alternative.
  • SootUp and WALA for a separately evaluated control/data-flow and call-graph lane. Specify the analysis algorithm, entry points, dependency universe and unresolved calls; a static graph is not a record of execution.

The integration decision should follow CONTRIBUTING.md. General static analysis/transformation, managed debugging, and specialized protection recovery must be assessed independently. A large toolkit list is not authorization to bundle every upstream behavior. This contribution proposes a roadmap and contracts; it does not claim that these providers have been integrated or tested together.

4. Incremental delivery and useful coverage measures

  1. Read-only class/member/bytecode identity and debug metadata (#2377), plus correct admission and raw fallback.
  2. Selected decompilation with one bring-your-own engine, bounded failure handling and method-level provenance; compare a second engine after that contract is stable.
  3. Static references and selected archive/runtime-container coverage (#3571). Preserve unresolved reflection, bootstrap targets and dependency resolution instead of inventing a complete call graph.
  4. The separate derived-artifact edit/transformation contract above, after its provider and scope decision.
  5. JVM observation (#2376), Android transport (#2378) and JNI correlation (#2379), with independently verified process/module identities and declared effects.

Measure archive occurrences accounted for, classes structurally examined, methods with exact instruction evidence, selected bodies successfully reconstructed, unresolved references and transformations independently validated. Keep denominators and exclusions explicit. Artifact capture, source reconstruction, runtime observation and behavioral recovery are different coverage measures; none implies “100% reverse engineered.”

5. Open and closed issue index

Snapshot: 2026-10-14. I paginated all 1,325 issue bodies, excluding pull requests, and supplemented that with 17 title/body/comment searches for Java, JVM, JDK, JAR, JIMAGE, JNI, DEX, JADX, Android, Apktool, Kotlin, bytecode, Recaf, CFR, Vineflower and deobfuscation/deobfuscator. The searches returned complete result sets without the 1,000-result cutoff. This is a relevance-reviewed map of 123 issues, including explicitly labeled adjacent dependencies; it excludes incidental JDK mentions in unrelated native-target examples and JavaScript-only issues. GitHub search indexing and issues created or changed after the snapshot remain limitations.

JVM class files, containers and Java-domain proposals — 8 issues
Issue Snapshot state Topic
#42 closed Add managed-runtime, bytecode, and package ecosystem providers
#367 closed Add JVM and Python bytecode providers
#1558 open [Feature] Java Reverse Engineering
#2258 open A recommended list of open-source decompilers
#2317 closed [Bug] Artifact inventory labels JVM class files as universal Mach-O executables
#2377 open [Feature] Inspect JVM source-line and local-variable metadata for debugging readiness
#3176 open [Bug] Bundle dylib tracing reports a valid JVM class resource as malformed Mach-O
#3571 open [Feature] Inventory JIMAGE runtime containers without loading target classes
Android/DEX analysis, resources and provider contracts — 40 issues
Issue Snapshot state Topic
#41 closed Add mobile application investigation providers and workflows
#366 closed Add Android APK/AAB/DEX and iOS IPA static investigation providers
#717 open [Feature] Integrate APK analysis tools into REA: research and roadmap
#893 closed JADX provider OOMs on real-world multidex APK (11 dex, 133MB)
#901 closed fix(android): avoid eager JADX code generation and retain owned APK sessions
#1124 closed fix(android): binary_session advertises tools without the required engine
#1125 closed fix(android): failures recommend doctor without relevant diagnostics
#1262 closed [Feature] codex 提示 REA 的 Android/JADX 流程在当前 Windows 宿主上不可用,需要受支持的 Linux/macOS 环境。
#1441 closed [Bug] JADX cleanup-failure fixture loses the reason for incomplete teardown
#1451 open [Feature] support droidasc for REA Android reverse feature
#1470 closed [Bug] inspect-artifact rejects a valid APK whose entries differ only in case
#1489 closed fix(mobile): bound bridge and runtime-family conventions to path segments
#1774 closed [Bug] Windows: apktool launcher probe fails with spawn EINVAL when REA_APKTOOL_COMMAND points to a .cmd/.bat wrapper
#1813 open [Design] Android split APK sets: set identity and relationship evidence before a bundletool lane
#1846 closed [Bug] Android method inspection loses executable static initializer evidence
#1850 closed [Bug] Focused Android class searches embed the complete provider inventory
#1860 closed [Bug] Android engine admission rejects duplicate ZIP resource names in the audited JAR
#1945 closed apktool refusals show generic target advice, and a relative REA_APKTOOL_COMMAND escapes as UNKNOWN
#1978 closed [Bug] search_android_classes fails on APKs where JADX lists okio.SegmentedByteString twice
#2563 closed fix(apktool): exclude configuration qualifiers from discovered locales
#2603 closed fix(android): disclose unread components omitted from application projection
#2672 closed fix(cli): documented string omission flag stops Android resource decoding
#2852 open Main compile: optional Jadx schema output is incompatible with JsonValue
#2909 closed fix(android): make advertised DEX descriptor patterns portable to JavaScript v mode
#2944 closed [Bug] Setup does not carry REA_JADX_MCP_JAR into agent registrations
#3068 closed [Bug] binary_session reports configured Apktool tools as provider_missing
#3069 open [Bug] binary_session reports JEB tools provider_missing without checking the JEB endpoint
#3111 open [Windows] Native controls self-check blocks static Android APK analysis on Win11 build 26300 (rea-agents 6.4.0)
#3337 open [Bug] Apktool shell launchers survive output overflow and cancellation
#3340 open [Bug] Apktool decode refusals report the launcher path instead of the selected APK
#3342 open [Bug] Apktool version probe stays pending after timeout or cancellation
#3347 open [Bug] Apktool version-probe deadlines return a nonretryable capability error
#3349 open [Bug] Mobile application graphs classify known directories as bytecode and native libraries
#3368 open [Bug] Package inspection rounds distinct Android version codes to the same value
#3374 open [Feature] rea doctor readiness check for the JADX (Android) provider
#3438 open apktool: no warning when the launcher is vulnerable to CVE-2024-21633
#3443 open [Bug] inspect_android_method reports an inlined Java method as "native/abstract" with no body
#3488 open [Bug] inspect_android_method returns neighbouring members as the "complete" body of a native method
#3489 open [Feature] inspect_android_class: report method access flags (native, abstract, static, synthetic, bridge)
#3517 open [Bug] JADX "Java heap space" load failure points to rea doctor, which reports healthy
Managed runtime, JNI and native-debugger coordination — 7 issues
Issue Snapshot state Topic
#968 open [Feature] Modular native runtime instrumentation through a Frida adapter
#1267 open [Feature] Live native debugging through x64dbg, GDB and LLDB adapters
#2080 closed / not planned [Feature] Android APK unpacking support for Ijiami (爱加密) packer
#2376 open [Design] Observe caller-selected JVM debugger sessions through JDI/JDWP
#2378 open [Design] Attach to a selected debuggable Android app with device and ART process identity
#2379 open [Design] Correlate Android Java/JNI and native debugger observations with verified module identities
#3518 open [Feature] Model the Cordova/Capacitor WebView bridge in JavaScript and Android analysis
Android device/transport dependencies (adjacent to Java, not JVM bytecode features) — 10 issues
Issue Snapshot state Topic
#1952 closed ADB refusals show generic target advice, and a relative REA_ADB_PATH escapes as UNKNOWN
#2175 closed fix(adb): logcat reports character units in total_bytes
#2220 closed [Bug] collect_adb_bugreport can overwrite an existing archive
#2225 closed [Bug] ADB activity startup treats Status: timeout as a successful launch
#2996 closed [Bug] inspect_adb_window reports no focus on Android 16 because focus lines moved out of dumpsys window windows
#3051 closed [Bug] list_adb_devices reports may_have_started_adb_server false after adb starts its server
#3067 closed [Bug] binary_session reports configured ADB tools as provider_missing
#3166 closed [Bug] Fresh ADB installs with --replace are reported as observed replacements
#3210 open [Bug] Malformed start-adb-activity extras omit required error classification and recovery fields
#3369 open [Bug] ADB push reports checksum capture overflow as device unavailability
JDK and Java bridge infrastructure (Ghidra analyzes native code here) — 35 issues
Issue Snapshot state Topic
#288 open Own Windows Ghidra process trees with kill-on-close semantics
#481 closed [Feature] Add a read-only Ghidra provider for macOS
#790 closed [Bug] Ghidra bridge discovery collides with a same-named working-directory entry
#821 closed [Bug] Ghidra provider pins Java to exactly major 21 and the Ghidra version to the exact string "12.1.4", blocking working installs
#832 closed [Bug] Linux: Ghidra provider unusable — GHIDRA_INSTALL_DIR not detected and Arch-family host flagged unsupported
#1026 closed [Bug] Windows Ghidra snapshot lease blocks Java readers
#1131 closed Ghidra provider rejects linux/arm64 hosts (hard-coded x64 allowlist) — one-line fix proven working
#1183 closed [Bug] Doctor and setup accept a relative GHIDRA_INSTALL_DIR that the registered MCP server rejects at startup
#1184 closed [Bug] Configuration errors omit the rejected Ghidra setting and its absolute-path constraint
#1190 closed [Bug] Failed Ghidra runtime cleanup omits the leftover path, and a later close reports success while it remains
#1191 closed [Bug] One terminal SIGINT through npx orphans the Ghidra JVM and its runtime directories
#1192 closed [Feature] Diagnose a Ghidra native decompiler built for the wrong platform or architecture
#1219 closed [Bug] Ghidra provider aborts on every operation when the runtime root path contains a dot-prefixed element
#1255 closed docs(ghidra): clarify supported heap and CPU controls
#1339 closed / not planned [Bug] A dot in the TMPDIR path makes Ghidra abort, reported as a generic "retry once" failure
#1518 closed [Bug] Ghidra boundary verifier fails on duplicate output schema ids since #1433
#1690 closed [Bug] Windows private runtime doubles the separator for a drive-root parent and rejects every later snapshot
#1701 open [Bug] Windows native authority self-test fails on real Windows: "Delete owned object by handle failed" (Win32 5), and leaves probe directories behind
#1720 open [Bug] query tool calls die at a flat ~60s timeout, shorter than configured Ghidra startup timeout
#1859 closed [Bug] Windows real-Ghidra verifiers fail on every host after #1635, #1419 and #1667
#1992 closed Ghidra launch failures surface no actionable diagnostics (macOS)
#2196 closed [Windows x64] Every provider-backed operation fails with "Delete owned object by handle failed (Win32 5)"
#2204 closed [Bug] Ghidra provider stays unavailable when JAVA_HOME contains non-ASCII characters on Windows
#2519 closed fix(verify-ghidra-dos): reports complete cleanup with unavailable process lineage
#2532 closed fix(ghidra): missing Java bitness is reported as a 0-bit runtime
#2629 closed test(ghidra): update positive integration hosts for declared Java admission
#2785 closed [Bug] Ghidra doctor passes but analysis fails when the JDK runs as x86_64 under Rosetta on Apple silicon
#2908 open [Feature] Compile packaged bridge Java sources as a CI preflight
#3016 open Persist provider settings (GHIDRA_INSTALL_DIR, HOPPER_LAUNCHER_PATH, REA_JADX_MCP_JAR) in a REA config so the value survives client restarts
#3032 open [Bug] macOS: closing a large Ghidra session reports cleanup_incomplete (sysctl_errno_22) while the JVM is mid-exit
#3179 open [Bug] Ghidra doctor passes version validation for malformed continued properties beginning with comment markers
#3372 open [Feature] Documented Docker image for running REA's MCP server and CLI on Linux
#3435 closed ghidra: Windows loopback bridge ends the session on the first unauthenticated connection
#3501 open [Bug] Installing from source omits the Windows native artifact, so every provider is rejected as unsupported_host
#3509 open [Bug] Open target lost after MCP transport failure; Ghidra analyses longer than the client's idle timeout can never complete (stdio)
Shared evidence, archive, paging and readiness dependencies — 23 issues
Issue Snapshot state Topic
#35 closed Model applications as artifact graphs and add safe decomposition
#740 open [Design] Roadmap: clarify investigation ownership and modularize REA capability integration
#778 open [Docs] Track reproducible demos across REA reverse-engineering domains
#1065 open [Feature] Roadmap: improve MCP usability and performance under bounded resources
#1248 closed feat(snapshot): report Evidence and workflow counts in save receipts
#1249 closed perf(snapshot): reduce eager materialization of large retained investigations
#1250 closed feat(process): report capture truncation separately for each evidence dimension
#1251 closed feat(process): explain omitted file digests and separate hashing from retained output
#1252 closed feat(process): expose bounded live capture progress through CLI and MCP
#1253 closed feat(process): support a bounded child finalization interval on capture timeout
#1485 closed fix(artifacts): keep ZIP-tail bytes out of unchanged and complete claims
#1491 closed fix(artifacts): classify container family from bytes before the filename suffix
#1680 closed feat(evidence): reduce heap expansion when importing complete large snapshots
#2016 closed feat: compatibility-first analysis efficiency and domain-module pilot
#2330 closed fix(artifacts): correct ZIP non-entry coverage description
#2383 open [Tracker] Audit analysis and debugging coverage for the TIOBE top 100 languages (October 2026)
#3008 open 170 MCP tools advertised across 15 surfaces, but doctor inspects only 2 providers
#3134 open test(perf): verify efficient paging of large retained investigations
#3136 open research(perf): establish whether Ghidra database reuse adds value beyond snapshots
#3459 open inspect_artifact inventory evidence reads only the first substep
#3490 open [Feature] extract_artifact: choose the destination and extract a subset of entries
#3537 open [Tracker] Audit and subsystem index of active bug reports (October 2026)
#3570 open [Feature] Preserve static file identity when inspect-artifact declines a format
<!-- gh-comment-id:6173879928 --> @matbrgz commented on GitHub (Oct 14, 2026): Adding an issue map and a concrete design for the bytecode transformation gap raised in [this comment](https://github.com/morluto/rea/issues/1558#issuecomment-6144503896). The useful next step is to connect the tool list to stable analyst contracts, explicit provider boundaries and regression fixtures. ## 1. What the existing reports imply for the Java domain | Priority | Concrete contract or behavior | Existing issue evidence | |---|---|---| | Class identity before source reconstruction | An exact archive occurrence, class digest, internal name, member name **and JVM descriptor** identify the input. Preserve case, duplicate entries and multi-release alternatives. A class-file parser and a decompiler must agree on that selected input. | #2317, #3176, #1470, #1860, #1978, #2377 | | Truthful method coverage | Distinguish `Code` present, native, abstract, transformed/inlined by the provider, failed decompilation, and an unsupported representation. A neighboring member's text or a failure stub must never count as the selected method's complete source. Preserve bytecode when source fails. | #1846, #3443, #3488, #3489 | | Inventory without eager decompilation | Read metadata once, index exact members, page selected results, and decompile only requested bodies. Cache against input digest, engine build/options, dependency profile and selected archive version. Report examined/returned/skipped/failed counts separately. | #893, #901, #1850, #2852, #3134 | | Useful readiness and failure reasons | Distinguish missing engine, incompatible JDK, bridge compilation failure, heap exhaustion, unsupported target and incomplete cleanup. Installation readiness cannot promise that a particular large input fits in memory. | #1124, #1125, #2908, #2944, #3016, #3069, #3111, #3374, #3517 | | Runtime containers and resources | JAR/WAR/EAR, nested archives, JMOD and JIMAGE need container identities and resource inventories independently of Java source reconstruction. Treat runtime/library classes separately from application-owned classes. | #42, #367, #3571, #3490, #3459 | These are proposed acceptance requirements. The issue index below records open/closed state; closure alone does not establish that a capability is shipped or still passes a real-provider regression. In particular, #367 is historical context, #2317 is a closed classification report, and #3176 reports another classification path. #2080 was closed as **not planned** and is not an approved implementation dependency. ## 2. A focused bytecode editing / general static deobfuscation design I suggest a separately reviewable companion proposal with the following contract, rather than treating every upstream GUI or MCP command as part of REA's supported surface: 1. **Select and inspect:** bind the operation to an immutable class/JAR digest, exact archive occurrence and method descriptor. Preserve the original bytes and raw names; display aliases do not change identity. 2. **Plan:** return the requested edit or an allowlisted static transformation, the selected members, provider/version/options, required dependency classpath, and expected output. Applying an external rename map is a concrete possible first slice; explicitly account for unsupported reflection/resource-name references. 3. **Apply to a derived artifact:** write a new output, never the original. Preserve a before/after ledger of entry digests, member identities, rename mappings, changed instructions and any removed or rewritten attributes. Keep input/output coverage and rejected transformations visible. 4. **Validate:** parse the complete output and report structural/verifier checks supported by the chosen profile, unresolved dependencies, stack/frame failures, archive metadata and signature consequences. A valid output class does not prove behavioral equivalence, and regenerated source does not prove that no side effect moved. JVM execution-based verification would be a separate declared effect. 5. **Compare:** show exact bytecode differences and optional reconstructed source side by side, with provider provenance. If evaluation of a decryptor or helper is required, return an execution requirement; do not silently run target code as a static transformation. Source-built acceptance fixtures should include overloads, bridge/synthetic members, inner/nestmate classes, exception handlers, lambdas/bootstrap methods, missing dependencies, absent debug tables, invalid stack maps, duplicate and case-distinct ZIP entries, multi-release JARs and a signed JAR. Add a method with observable side effects to catch a reconstruction that looks plausible but changes their order. Record cancellation, output/heap limits and owned-workspace cleanup through both CLI and MCP. The bytecode and verification model should follow the [JVMS](https://docs.oracle.com/javase/specs/jvms/se25/html/jvms-4.html), with an explicit supported class-version profile. Multi-release selection and archive/signature handling should follow the [JAR specification](https://docs.oracle.com/en/java/javase/25/docs/specs/jar/jar.html). Preserve unknown attributes as opaque evidence where supported; do not silently discard them or claim verifier support for an untested version. ## 3. Evaluate the tools by responsibility The references in this issue cover several different jobs. A provider comparison should record the exact revision, callable headless interface, class-version support, dependencies, license, default rewrites, target execution/network effects, resource controls, failure output and verified fixtures for **every candidate**, including candidates ultimately rejected. | Responsibility | Candidates already referenced here | Evaluation needed | |---|---|---| | Workspace, inspection, assembly and editing | Recaf and its MCP/launcher variants; JByteMod-Remastered/plugin-mcp; Trinity; JStudio; Antares-Lite | Expose selected operations through REA contracts. Check import-time repair/normalization and script/plugin execution instead of assuming that opening a workspace preserves bytes. | | Source reconstruction | Vineflower, Fernflower, CFR, Procyon, Krakatau | Start with one selected engine; add a second for disagreements. Compare failures and method attribution against bytecode, not source aesthetics. Kotlin/Scala/Groovy compiler output remains JVM bytecode and does not automatically become recovered original-language source. | | Bytecode parsing, transformation and analysis | ASM, CAFED00D, Recaf/assembler, Krakatau; Mokapot/MokaIR | Preserve source spans and attributes, define verifier/dependency limits and distinguish a resilient parser's repairs from original input. MokaIR is an analysis candidate, not a substitute for proven class-file round trips. | | General static transformation and comparison | Java Deobfuscator, Threadtear, Diobf (including v1), Cafe Compare | Evaluate individual transformations, their applicability and execution behavior; preserve mapping and change provenance. Obfuscator-specific references such as ZKM-27 need the same scope review, not automatic integration. | | JVM observation and debugging | Java-Process-Inspector, JDBG, Jattach, Bindbg, Dumper, JVMInspect/toolbox | Coordinate with #2376. Process/class-loader identity, class-byte association, attach effects, frame lifetime and cleanup are separate from offline inspection. | | JNI/native boundaries | JNI Detranspiler, C2J, JnicX, JNIC-Virtualization | Evaluate static inspection/extraction separately from execution or dedicated protection recovery. Reuse native providers for admitted native artifacts and #2379 for runtime correlation. Do not present native-to-Java reconstruction as original source. | | Execution or protocol experiments | SSVM, mitmproxy-java | Running code in an interpreter remains execution; protocol interception remains a separate effect. Neither is a containment guarantee or a prerequisite for the initial static lane. | | Android and reference collections | Dalvikus, Android tools in #717, the JavaReversingWiki/Useful-Things/obfuscator-list/starred collections | Useful research inputs and fixture ideas; record supported JVM versus DEX semantics independently. Lists are not provider support claims. | [Recaf's documentation](https://github.com/Col-E/Recaf#features) specifically describes multiple decompilers, assembly, automation, and automatic repairs during import. That makes original-versus-working-copy evidence a practical adapter requirement. [Mokapot's documentation](https://github.com/henryhchchc/mokapot) describes a class-file model and SSA analysis; its compatibility and stability need a pinned evaluation rather than a general maturity assumption. Additional candidates worth adding to the inventory: - The JDK's [Class-File API](https://docs.oracle.com/en/java/javase/25/docs/api/java.base/java/lang/classfile/package-summary.html) for parsing/generation/transformation and an independent comparison with ASM. Its models are lazy, so successful initial parsing is not proof that every attribute/body was examined; transformation options and class-hierarchy resolution also need explicit profiles. - [`javap`](https://docs.oracle.com/en/java/javase/25/docs/specs/man/javap.html) as a caller-installed disassembly/debug-metadata baseline for source-built regression fixtures. Bind it to the exact member bytes rather than silently choosing a classpath alternative. - [SootUp](https://github.com/soot-oss/SootUp) and [WALA](https://github.com/wala/WALA) for a separately evaluated control/data-flow and call-graph lane. Specify the analysis algorithm, entry points, dependency universe and unresolved calls; a static graph is not a record of execution. The integration decision should follow [CONTRIBUTING.md](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). General static analysis/transformation, managed debugging, and specialized protection recovery must be assessed independently. A large toolkit list is not authorization to bundle every upstream behavior. This contribution proposes a roadmap and contracts; it does not claim that these providers have been integrated or tested together. ## 4. Incremental delivery and useful coverage measures 1. Read-only class/member/bytecode identity and debug metadata (#2377), plus correct admission and raw fallback. 2. Selected decompilation with one bring-your-own engine, bounded failure handling and method-level provenance; compare a second engine after that contract is stable. 3. Static references and selected archive/runtime-container coverage (#3571). Preserve unresolved reflection, bootstrap targets and dependency resolution instead of inventing a complete call graph. 4. The separate derived-artifact edit/transformation contract above, after its provider and scope decision. 5. JVM observation (#2376), Android transport (#2378) and JNI correlation (#2379), with independently verified process/module identities and declared effects. Measure archive occurrences accounted for, classes structurally examined, methods with exact instruction evidence, selected bodies successfully reconstructed, unresolved references and transformations independently validated. Keep denominators and exclusions explicit. **Artifact capture, source reconstruction, runtime observation and behavioral recovery are different coverage measures; none implies “100% reverse engineered.”** ## 5. Open and closed issue index Snapshot: **2026-10-14**. I paginated all **1,325 issue bodies**, excluding pull requests, and supplemented that with 17 title/body/comment searches for Java, JVM, JDK, JAR, JIMAGE, JNI, DEX, JADX, Android, Apktool, Kotlin, bytecode, Recaf, CFR, Vineflower and deobfuscation/deobfuscator. The searches returned complete result sets without the 1,000-result cutoff. This is a relevance-reviewed map of **123 issues**, including explicitly labeled adjacent dependencies; it excludes incidental JDK mentions in unrelated native-target examples and JavaScript-only issues. GitHub search indexing and issues created or changed after the snapshot remain limitations. <details> <summary>JVM class files, containers and Java-domain proposals — 8 issues</summary> | Issue | Snapshot state | Topic | |---|---|---| | [#42](https://github.com/morluto/rea/issues/42) | closed | Add managed-runtime, bytecode, and package ecosystem providers | | [#367](https://github.com/morluto/rea/issues/367) | closed | Add JVM and Python bytecode providers | | [#1558](https://github.com/morluto/rea/issues/1558) | open | [Feature] Java Reverse Engineering | | [#2258](https://github.com/morluto/rea/issues/2258) | open | A recommended list of open-source decompilers | | [#2317](https://github.com/morluto/rea/issues/2317) | closed | [Bug] Artifact inventory labels JVM class files as universal Mach-O executables | | [#2377](https://github.com/morluto/rea/issues/2377) | open | [Feature] Inspect JVM source-line and local-variable metadata for debugging readiness | | [#3176](https://github.com/morluto/rea/issues/3176) | open | [Bug] Bundle dylib tracing reports a valid JVM class resource as malformed Mach-O | | [#3571](https://github.com/morluto/rea/issues/3571) | open | [Feature] Inventory JIMAGE runtime containers without loading target classes | </details> <details> <summary>Android/DEX analysis, resources and provider contracts — 40 issues</summary> | Issue | Snapshot state | Topic | |---|---|---| | [#41](https://github.com/morluto/rea/issues/41) | closed | Add mobile application investigation providers and workflows | | [#366](https://github.com/morluto/rea/issues/366) | closed | Add Android APK/AAB/DEX and iOS IPA static investigation providers | | [#717](https://github.com/morluto/rea/issues/717) | open | [Feature] Integrate APK analysis tools into REA: research and roadmap | | [#893](https://github.com/morluto/rea/issues/893) | closed | JADX provider OOMs on real-world multidex APK (11 dex, 133MB) | | [#901](https://github.com/morluto/rea/issues/901) | closed | fix(android): avoid eager JADX code generation and retain owned APK sessions | | [#1124](https://github.com/morluto/rea/issues/1124) | closed | fix(android): binary_session advertises tools without the required engine | | [#1125](https://github.com/morluto/rea/issues/1125) | closed | fix(android): failures recommend doctor without relevant diagnostics | | [#1262](https://github.com/morluto/rea/issues/1262) | closed | [Feature] codex 提示 REA 的 Android/JADX 流程在当前 Windows 宿主上不可用,需要受支持的 Linux/macOS 环境。 | | [#1441](https://github.com/morluto/rea/issues/1441) | closed | [Bug] JADX cleanup-failure fixture loses the reason for incomplete teardown | | [#1451](https://github.com/morluto/rea/issues/1451) | open | [Feature] support droidasc for REA Android reverse feature | | [#1470](https://github.com/morluto/rea/issues/1470) | closed | [Bug] inspect-artifact rejects a valid APK whose entries differ only in case | | [#1489](https://github.com/morluto/rea/issues/1489) | closed | fix(mobile): bound bridge and runtime-family conventions to path segments | | [#1774](https://github.com/morluto/rea/issues/1774) | closed | [Bug] Windows: apktool launcher probe fails with spawn EINVAL when REA_APKTOOL_COMMAND points to a .cmd/.bat wrapper | | [#1813](https://github.com/morluto/rea/issues/1813) | open | [Design] Android split APK sets: set identity and relationship evidence before a bundletool lane | | [#1846](https://github.com/morluto/rea/issues/1846) | closed | [Bug] Android method inspection loses executable static initializer evidence | | [#1850](https://github.com/morluto/rea/issues/1850) | closed | [Bug] Focused Android class searches embed the complete provider inventory | | [#1860](https://github.com/morluto/rea/issues/1860) | closed | [Bug] Android engine admission rejects duplicate ZIP resource names in the audited JAR | | [#1945](https://github.com/morluto/rea/issues/1945) | closed | apktool refusals show generic target advice, and a relative REA_APKTOOL_COMMAND escapes as UNKNOWN | | [#1978](https://github.com/morluto/rea/issues/1978) | closed | [Bug] search_android_classes fails on APKs where JADX lists okio.SegmentedByteString twice | | [#2563](https://github.com/morluto/rea/issues/2563) | closed | fix(apktool): exclude configuration qualifiers from discovered locales | | [#2603](https://github.com/morluto/rea/issues/2603) | closed | fix(android): disclose unread components omitted from application projection | | [#2672](https://github.com/morluto/rea/issues/2672) | closed | fix(cli): documented string omission flag stops Android resource decoding | | [#2852](https://github.com/morluto/rea/issues/2852) | open | Main compile: optional Jadx schema output is incompatible with JsonValue | | [#2909](https://github.com/morluto/rea/issues/2909) | closed | fix(android): make advertised DEX descriptor patterns portable to JavaScript v mode | | [#2944](https://github.com/morluto/rea/issues/2944) | closed | [Bug] Setup does not carry REA_JADX_MCP_JAR into agent registrations | | [#3068](https://github.com/morluto/rea/issues/3068) | closed | [Bug] binary_session reports configured Apktool tools as provider_missing | | [#3069](https://github.com/morluto/rea/issues/3069) | open | [Bug] binary_session reports JEB tools provider_missing without checking the JEB endpoint | | [#3111](https://github.com/morluto/rea/issues/3111) | open | [Windows] Native controls self-check blocks static Android APK analysis on Win11 build 26300 (rea-agents 6.4.0) | | [#3337](https://github.com/morluto/rea/issues/3337) | open | [Bug] Apktool shell launchers survive output overflow and cancellation | | [#3340](https://github.com/morluto/rea/issues/3340) | open | [Bug] Apktool decode refusals report the launcher path instead of the selected APK | | [#3342](https://github.com/morluto/rea/issues/3342) | open | [Bug] Apktool version probe stays pending after timeout or cancellation | | [#3347](https://github.com/morluto/rea/issues/3347) | open | [Bug] Apktool version-probe deadlines return a nonretryable capability error | | [#3349](https://github.com/morluto/rea/issues/3349) | open | [Bug] Mobile application graphs classify known directories as bytecode and native libraries | | [#3368](https://github.com/morluto/rea/issues/3368) | open | [Bug] Package inspection rounds distinct Android version codes to the same value | | [#3374](https://github.com/morluto/rea/issues/3374) | open | [Feature] `rea doctor` readiness check for the JADX (Android) provider | | [#3438](https://github.com/morluto/rea/issues/3438) | open | apktool: no warning when the launcher is vulnerable to CVE-2024-21633 | | [#3443](https://github.com/morluto/rea/issues/3443) | open | [Bug] inspect_android_method reports an inlined Java method as "native/abstract" with no body | | [#3488](https://github.com/morluto/rea/issues/3488) | open | [Bug] inspect_android_method returns neighbouring members as the "complete" body of a native method | | [#3489](https://github.com/morluto/rea/issues/3489) | open | [Feature] inspect_android_class: report method access flags (native, abstract, static, synthetic, bridge) | | [#3517](https://github.com/morluto/rea/issues/3517) | open | [Bug] JADX "Java heap space" load failure points to rea doctor, which reports healthy | </details> <details> <summary>Managed runtime, JNI and native-debugger coordination — 7 issues</summary> | Issue | Snapshot state | Topic | |---|---|---| | [#968](https://github.com/morluto/rea/issues/968) | open | [Feature] Modular native runtime instrumentation through a Frida adapter | | [#1267](https://github.com/morluto/rea/issues/1267) | open | [Feature] Live native debugging through x64dbg, GDB and LLDB adapters | | [#2080](https://github.com/morluto/rea/issues/2080) | closed / not planned | [Feature] Android APK unpacking support for Ijiami (爱加密) packer | | [#2376](https://github.com/morluto/rea/issues/2376) | open | [Design] Observe caller-selected JVM debugger sessions through JDI/JDWP | | [#2378](https://github.com/morluto/rea/issues/2378) | open | [Design] Attach to a selected debuggable Android app with device and ART process identity | | [#2379](https://github.com/morluto/rea/issues/2379) | open | [Design] Correlate Android Java/JNI and native debugger observations with verified module identities | | [#3518](https://github.com/morluto/rea/issues/3518) | open | [Feature] Model the Cordova/Capacitor WebView bridge in JavaScript and Android analysis | </details> <details> <summary>Android device/transport dependencies (adjacent to Java, not JVM bytecode features) — 10 issues</summary> | Issue | Snapshot state | Topic | |---|---|---| | [#1952](https://github.com/morluto/rea/issues/1952) | closed | ADB refusals show generic target advice, and a relative REA_ADB_PATH escapes as UNKNOWN | | [#2175](https://github.com/morluto/rea/issues/2175) | closed | fix(adb): logcat reports character units in total_bytes | | [#2220](https://github.com/morluto/rea/issues/2220) | closed | [Bug] collect_adb_bugreport can overwrite an existing archive | | [#2225](https://github.com/morluto/rea/issues/2225) | closed | [Bug] ADB activity startup treats Status: timeout as a successful launch | | [#2996](https://github.com/morluto/rea/issues/2996) | closed | [Bug] inspect_adb_window reports no focus on Android 16 because focus lines moved out of dumpsys window windows | | [#3051](https://github.com/morluto/rea/issues/3051) | closed | [Bug] list_adb_devices reports may_have_started_adb_server false after adb starts its server | | [#3067](https://github.com/morluto/rea/issues/3067) | closed | [Bug] binary_session reports configured ADB tools as provider_missing | | [#3166](https://github.com/morluto/rea/issues/3166) | closed | [Bug] Fresh ADB installs with --replace are reported as observed replacements | | [#3210](https://github.com/morluto/rea/issues/3210) | open | [Bug] Malformed start-adb-activity extras omit required error classification and recovery fields | | [#3369](https://github.com/morluto/rea/issues/3369) | open | [Bug] ADB push reports checksum capture overflow as device unavailability | </details> <details> <summary>JDK and Java bridge infrastructure (Ghidra analyzes native code here) — 35 issues</summary> | Issue | Snapshot state | Topic | |---|---|---| | [#288](https://github.com/morluto/rea/issues/288) | open | Own Windows Ghidra process trees with kill-on-close semantics | | [#481](https://github.com/morluto/rea/issues/481) | closed | [Feature] Add a read-only Ghidra provider for macOS | | [#790](https://github.com/morluto/rea/issues/790) | closed | [Bug] Ghidra bridge discovery collides with a same-named working-directory entry | | [#821](https://github.com/morluto/rea/issues/821) | closed | [Bug] Ghidra provider pins Java to exactly major 21 and the Ghidra version to the exact string "12.1.4", blocking working installs | | [#832](https://github.com/morluto/rea/issues/832) | closed | [Bug] Linux: Ghidra provider unusable — GHIDRA_INSTALL_DIR not detected and Arch-family host flagged unsupported | | [#1026](https://github.com/morluto/rea/issues/1026) | closed | [Bug] Windows Ghidra snapshot lease blocks Java readers | | [#1131](https://github.com/morluto/rea/issues/1131) | closed | Ghidra provider rejects linux/arm64 hosts (hard-coded x64 allowlist) — one-line fix proven working | | [#1183](https://github.com/morluto/rea/issues/1183) | closed | [Bug] Doctor and setup accept a relative `GHIDRA_INSTALL_DIR` that the registered MCP server rejects at startup | | [#1184](https://github.com/morluto/rea/issues/1184) | closed | [Bug] Configuration errors omit the rejected Ghidra setting and its absolute-path constraint | | [#1190](https://github.com/morluto/rea/issues/1190) | closed | [Bug] Failed Ghidra runtime cleanup omits the leftover path, and a later close reports success while it remains | | [#1191](https://github.com/morluto/rea/issues/1191) | closed | [Bug] One terminal SIGINT through `npx` orphans the Ghidra JVM and its runtime directories | | [#1192](https://github.com/morluto/rea/issues/1192) | closed | [Feature] Diagnose a Ghidra native decompiler built for the wrong platform or architecture | | [#1219](https://github.com/morluto/rea/issues/1219) | closed | [Bug] Ghidra provider aborts on every operation when the runtime root path contains a dot-prefixed element | | [#1255](https://github.com/morluto/rea/issues/1255) | closed | docs(ghidra): clarify supported heap and CPU controls | | [#1339](https://github.com/morluto/rea/issues/1339) | closed / not planned | [Bug] A dot in the TMPDIR path makes Ghidra abort, reported as a generic "retry once" failure | | [#1518](https://github.com/morluto/rea/issues/1518) | closed | [Bug] Ghidra boundary verifier fails on duplicate output schema ids since #1433 | | [#1690](https://github.com/morluto/rea/issues/1690) | closed | [Bug] Windows private runtime doubles the separator for a drive-root parent and rejects every later snapshot | | [#1701](https://github.com/morluto/rea/issues/1701) | open | [Bug] Windows native authority self-test fails on real Windows: "Delete owned object by handle failed" (Win32 5), and leaves probe directories behind | | [#1720](https://github.com/morluto/rea/issues/1720) | open | [Bug] query tool calls die at a flat ~60s timeout, shorter than configured Ghidra startup timeout | | [#1859](https://github.com/morluto/rea/issues/1859) | closed | [Bug] Windows real-Ghidra verifiers fail on every host after #1635, #1419 and #1667 | | [#1992](https://github.com/morluto/rea/issues/1992) | closed | Ghidra launch failures surface no actionable diagnostics (macOS) | | [#2196](https://github.com/morluto/rea/issues/2196) | closed | [Windows x64] Every provider-backed operation fails with "Delete owned object by handle failed (Win32 5)" | | [#2204](https://github.com/morluto/rea/issues/2204) | closed | [Bug] Ghidra provider stays unavailable when JAVA_HOME contains non-ASCII characters on Windows | | [#2519](https://github.com/morluto/rea/issues/2519) | closed | fix(verify-ghidra-dos): reports complete cleanup with unavailable process lineage | | [#2532](https://github.com/morluto/rea/issues/2532) | closed | fix(ghidra): missing Java bitness is reported as a 0-bit runtime | | [#2629](https://github.com/morluto/rea/issues/2629) | closed | test(ghidra): update positive integration hosts for declared Java admission | | [#2785](https://github.com/morluto/rea/issues/2785) | closed | [Bug] Ghidra doctor passes but analysis fails when the JDK runs as x86_64 under Rosetta on Apple silicon | | [#2908](https://github.com/morluto/rea/issues/2908) | open | [Feature] Compile packaged bridge Java sources as a CI preflight | | [#3016](https://github.com/morluto/rea/issues/3016) | open | Persist provider settings (GHIDRA_INSTALL_DIR, HOPPER_LAUNCHER_PATH, REA_JADX_MCP_JAR) in a REA config so the value survives client restarts | | [#3032](https://github.com/morluto/rea/issues/3032) | open | [Bug] macOS: closing a large Ghidra session reports cleanup_incomplete (sysctl_errno_22) while the JVM is mid-exit | | [#3179](https://github.com/morluto/rea/issues/3179) | open | [Bug] Ghidra doctor passes version validation for malformed continued properties beginning with comment markers | | [#3372](https://github.com/morluto/rea/issues/3372) | open | [Feature] Documented Docker image for running REA's MCP server and CLI on Linux | | [#3435](https://github.com/morluto/rea/issues/3435) | closed | ghidra: Windows loopback bridge ends the session on the first unauthenticated connection | | [#3501](https://github.com/morluto/rea/issues/3501) | open | [Bug] Installing from source omits the Windows native artifact, so every provider is rejected as unsupported_host | | [#3509](https://github.com/morluto/rea/issues/3509) | open | [Bug] Open target lost after MCP transport failure; Ghidra analyses longer than the client's idle timeout can never complete (stdio) | </details> <details> <summary>Shared evidence, archive, paging and readiness dependencies — 23 issues</summary> | Issue | Snapshot state | Topic | |---|---|---| | [#35](https://github.com/morluto/rea/issues/35) | closed | Model applications as artifact graphs and add safe decomposition | | [#740](https://github.com/morluto/rea/issues/740) | open | [Design] Roadmap: clarify investigation ownership and modularize REA capability integration | | [#778](https://github.com/morluto/rea/issues/778) | open | [Docs] Track reproducible demos across REA reverse-engineering domains | | [#1065](https://github.com/morluto/rea/issues/1065) | open | [Feature] Roadmap: improve MCP usability and performance under bounded resources | | [#1248](https://github.com/morluto/rea/issues/1248) | closed | feat(snapshot): report Evidence and workflow counts in save receipts | | [#1249](https://github.com/morluto/rea/issues/1249) | closed | perf(snapshot): reduce eager materialization of large retained investigations | | [#1250](https://github.com/morluto/rea/issues/1250) | closed | feat(process): report capture truncation separately for each evidence dimension | | [#1251](https://github.com/morluto/rea/issues/1251) | closed | feat(process): explain omitted file digests and separate hashing from retained output | | [#1252](https://github.com/morluto/rea/issues/1252) | closed | feat(process): expose bounded live capture progress through CLI and MCP | | [#1253](https://github.com/morluto/rea/issues/1253) | closed | feat(process): support a bounded child finalization interval on capture timeout | | [#1485](https://github.com/morluto/rea/issues/1485) | closed | fix(artifacts): keep ZIP-tail bytes out of unchanged and complete claims | | [#1491](https://github.com/morluto/rea/issues/1491) | closed | fix(artifacts): classify container family from bytes before the filename suffix | | [#1680](https://github.com/morluto/rea/issues/1680) | closed | feat(evidence): reduce heap expansion when importing complete large snapshots | | [#2016](https://github.com/morluto/rea/issues/2016) | closed | feat: compatibility-first analysis efficiency and domain-module pilot | | [#2330](https://github.com/morluto/rea/issues/2330) | closed | fix(artifacts): correct ZIP non-entry coverage description | | [#2383](https://github.com/morluto/rea/issues/2383) | open | [Tracker] Audit analysis and debugging coverage for the TIOBE top 100 languages (October 2026) | | [#3008](https://github.com/morluto/rea/issues/3008) | open | 170 MCP tools advertised across 15 surfaces, but doctor inspects only 2 providers | | [#3134](https://github.com/morluto/rea/issues/3134) | open | test(perf): verify efficient paging of large retained investigations | | [#3136](https://github.com/morluto/rea/issues/3136) | open | research(perf): establish whether Ghidra database reuse adds value beyond snapshots | | [#3459](https://github.com/morluto/rea/issues/3459) | open | inspect_artifact inventory evidence reads only the first substep | | [#3490](https://github.com/morluto/rea/issues/3490) | open | [Feature] extract_artifact: choose the destination and extract a subset of entries | | [#3537](https://github.com/morluto/rea/issues/3537) | open | [Tracker] Audit and subsystem index of active bug reports (October 2026) | | [#3570](https://github.com/morluto/rea/issues/3570) | open | [Feature] Preserve static file identity when inspect-artifact declines a format | </details>
Author
Owner

@anyanyna commented on GitHub (Oct 16, 2026):

I'd like to propose one addition to the decompilation slice, and get a scope decision before
writing anything.

The gap: @matbrgz's comment states it directly - "a valid output class does not prove
behavioral equivalence, and regenerated source does not prove that no side effect moved."
The coverage measures discussed so far count reconstructed bodies and methods with exact
instruction evidence, but nothing counts reconstructions checked against the input bytes.
Recovered source is inference plus a plausibility check, and a class that compiles cleanly
can still change overload binding, exception suppression or the order of side effects.

Proposal: make one part of that claim mechanical. Recompile the recovered source with a
pinned compiler in an owned workspace, compare the rebuilt class bytes against the original,
and report a per-class verdict next to the coverage number:

  • equivalent: the rebuilt class matches;
  • benign: differences explained by enumerated compiler behaviors, each tolerance carrying
    the measurement it came from;
  • suspect / damaged: unexplained differences, or a reconstruction that does not rebuild;
  • harness error: the check itself could not run, reported as unknown rather than safe.

Coverage and verdicts are printed together, so what was not verified is as visible as what
was, and a reconstruction that does not pass is never handed over as recovered source.

Deliberate non-goals for a first slice: the gate reads class bytes only - nothing loads or
runs the target classes; obfuscated or packed input is reported as a limitation, not
defeated; the original artifact is never modified; recovered names and comments are never
claimed as original. A behavioral differential mode that executes both versions is a
separate declared effect and I am not proposing it here.

Questions for a maintainer decision:

  1. Is a mechanical equivalence claim in scope, and where does it belong - a field on the
    decompilation result, a separate compare operation, or a caller-gated optional step?
  2. Effect boundary: a javac build over recovered source is not target execution, but it
    does compile source derived from the target. Given "REA never loads target classes",
    does that belong in the same operation as decompilation, or as its own declared step?
  3. Distribution: caller-supplied CLI, or a pinned vendored release with an audited release
    identity? If the latter, what release identity, license and notice material would REA
    expect?
  4. The step needs bounded workspace, heap and output, with typed capacity failures instead
    of partial results. Should that be specified in the contract before any implementation?

If this is in scope, I can implement the first slice - read-only class and member identity,
one bring-your-own decompile engine, and this gate - and open a draft PR that is not
requesting merge. I have not implemented any of it yet and have not run it against a REA
adapter.

<!-- gh-comment-id:6206726429 --> @anyanyna commented on GitHub (Oct 16, 2026): I'd like to propose one addition to the decompilation slice, and get a scope decision before writing anything. The gap: @matbrgz's comment states it directly - "a valid output class does not prove behavioral equivalence, and regenerated source does not prove that no side effect moved." The coverage measures discussed so far count reconstructed bodies and methods with exact instruction evidence, but nothing counts reconstructions checked against the input bytes. Recovered source is inference plus a plausibility check, and a class that compiles cleanly can still change overload binding, exception suppression or the order of side effects. Proposal: make one part of that claim mechanical. Recompile the recovered source with a pinned compiler in an owned workspace, compare the rebuilt class bytes against the original, and report a per-class verdict next to the coverage number: - equivalent: the rebuilt class matches; - benign: differences explained by enumerated compiler behaviors, each tolerance carrying the measurement it came from; - suspect / damaged: unexplained differences, or a reconstruction that does not rebuild; - harness error: the check itself could not run, reported as unknown rather than safe. Coverage and verdicts are printed together, so what was not verified is as visible as what was, and a reconstruction that does not pass is never handed over as recovered source. Deliberate non-goals for a first slice: the gate reads class bytes only - nothing loads or runs the target classes; obfuscated or packed input is reported as a limitation, not defeated; the original artifact is never modified; recovered names and comments are never claimed as original. A behavioral differential mode that executes both versions is a separate declared effect and I am not proposing it here. Questions for a maintainer decision: 1. Is a mechanical equivalence claim in scope, and where does it belong - a field on the decompilation result, a separate compare operation, or a caller-gated optional step? 2. Effect boundary: a javac build over recovered source is not target execution, but it does compile source derived from the target. Given "REA never loads target classes", does that belong in the same operation as decompilation, or as its own declared step? 3. Distribution: caller-supplied CLI, or a pinned vendored release with an audited release identity? If the latter, what release identity, license and notice material would REA expect? 4. The step needs bounded workspace, heap and output, with typed capacity failures instead of partial results. Should that be specified in the contract before any implementation? If this is in scope, I can implement the first slice - read-only class and member identity, one bring-your-own decompile engine, and this gate - and open a draft PR that is not requesting merge. I have not implemented any of it yet and have not run it against a REA adapter.
Author
Owner

@CarbonEdge commented on GitHub (Oct 16, 2026):

Vineflower would probably help here, it also decompiles older java

<!-- gh-comment-id:6224375040 --> @CarbonEdge commented on GitHub (Oct 16, 2026): Vineflower would probably help here, it also decompiles older java
Author
Owner

@unclamped commented on GitHub (Oct 19, 2026):

+1 on this, java decomp tools are all scattered through GitHub. it would be nice for this project to support it.

<!-- gh-comment-id:6278343521 --> @unclamped commented on GitHub (Oct 19, 2026): +1 on this, java decomp tools are all scattered through GitHub. it would be nice for this project to support it.
Author
Owner

@master7720 commented on GitHub (Oct 30, 2026):

lmk when this is impl 🙏

<!-- gh-comment-id:6528242961 --> @master7720 commented on GitHub (Oct 30, 2026): lmk when this is impl 🙏
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#525
No description provided.