

React Native is everywhere. Instagram, Discord, Shopify, Walmart, thousands of enterprise apps. They all ship the same thing: a compiled Hermes bytecode bundle sitting in the APK's assets/ folder. If you've ever tried to reverse one of these, you know the pain.
You open the APK in JADX. You see a ReactActivity. You find index.android.bundle in the assets. You open it in a hex editor and see c6 1f bc 1e at offset 0. Congratulations, it's Hermes bytecode. Now what?
Hermes is Meta's JavaScript engine for React Native. Instead of shipping JS source code that gets parsed at runtime (like V8 or JavaScriptCore), Hermes precompiles everything into bytecode during the build. The result is a .hbc file with a custom binary format: function tables, string tables, register-based opcodes, environment chains for closures. None of the original source code survives.
There was no public tool to properly decompile this. You had hbctool which could disassemble individual opcodes, but reading raw register-based assembly for thousands of functions is not realistic. JEB added some Hermes support, but it's expensive and closed-source. For most people, reversing a React Native app meant staring at bytecode mnemonics and reconstructing the logic in your head.
That's a problem when you're doing a security audit on a React Native app and the entire business logic lives in that bytecode bundle.
Anthony Bondu, security researcher at Symbiotic Security, built hermes-decomp. It's a Rust-based decompiler that turns Hermes bytecode back into readable JavaScript. It's open-source. It's fast. It supports every Hermes bytecode version from 40 to 99.
https://github.com/SymbioticSec/hermes-decomp/
Here's what it does: you point it at an index.android.bundle (or any .hbc file), and it gives you back JavaScript. Not perfect source code, but readable, structured code with control flow recovery, constant propagation, closure resolution, and pattern detection for generators, async functions, and classes.
The decompilation pipeline has five stages:
r0, r1, ...).0x3b 0x00 0x01 becomes Mov r0, r1. String references are resolved so you see LoadConstString r3, "REVEAL FLAG" instead of raw string IDs.if/else, while, for, try/catch). There's also pattern matching to detect generator state machines, async/await patterns, and class constructors.Beyond decompile, the tool ships with: info (file metadata), disasm (raw bytecode), xref (cross-references to strings or functions), extract (split Metro modules into separate files), dump (export string/function tables), tui (interactive terminal browser with bin-diff split view), bin-diff (compare two HBC files), graphviz (control flow graph), modules/deps (Metro module registry and dependency tree), and closures (resolve what each closure_X maps to).
We needed real-world test cases. Insomnihack 2026 gave us exactly that.
Orange Cyberdefense Switzerland published two mobile reverse engineering challenges: so-AIRMES and !so-AIRMES. Both were React Native APKs shipping Hermes bytecode version 96. The first one had the crypto logic in a native C++ library. The second one had everything in JavaScript, with heavy obfuscation and custom crypto routines.
These were perfect test cases: real challenges, realistic app structure (10,000+ functions bundled with React Native framework code), and crypto logic that required actually understanding the decompiled output, not just pattern matching.
hermes-decomp is not perfect. Some things to know:
Generator functions (async/await compiled to state machines) produce partial decompilation in some cases. The tool handles many generator patterns, but complex state machines sometimes need the disassembly view to fill in gaps.
Variable names are gone. Hermes strips all variable names in release builds. You get closure_0, tmp3, r10020 instead of setStatus, result, apiKey. The tool uses heuristics to name some things (like detecting React hooks), but it's fundamentally working with register numbers.
Not all Hermes opcodes are documented by Meta. The tool supports versions 40 through 99, but some exotic instructions in newer versions might not decompile cleanly.
If you've ever opened a React Native APK and hit a wall at index.android.bundle, this tool gets you past it.
1. GitHub: https://github.com/SymbioticSec/hermes-decomp
git clone <https://github.com/SymbioticSec/hermes-decomp.git>
cd hermes-decomp
cargo build --release2. The tool also ships as an MCP server, so you can plug it directly into AI assistants (Claude, Cursor, etc.) for AI-assisted reverse engineering.
If you find something interesting with it, we'd love to hear about it. If you want to contribute rules, PRs are open.
