Understanding Hermes Bytecode Versions
Hermes bytecode files embed a version number in the header that determines the instruction set used to encode JavaScript. Each Hermes engine release may:- Introduce new opcodes (e.g., new array operations)
- Remove deprecated opcodes
- Reorder the opcode table
- Change operand types or sizes
When to Regenerate Opcodes
Scenario 1: Analyzing a Newer App
You try to analyze an.hbc file but get an error:
Scenario 2: New Hermes Release
Facebook ships a new Hermes version with bytecode changes. Check the Hermes releases page for new tags.Opcode Generation Workflow
Download Hermes definitions
Run the download script to fetch C++ instruction definitions from the Hermes repository:What it does (from
pkg/utils/download_all.sh):- Fetches
BytecodeList.def(instruction definitions) - Fetches
BytecodeVersion.h(version constants) - Fetches
Builtins.def(builtin function names) - Stores files in
pkg/utils/defversions/
Generate Go opcode packages
Run the opcode generator to parse What it does (from
.def files and produce Go code:pkg/cmd/genopcodes.go:16):- Parses each
BytecodeList.deffor instruction names, opcodes, and operands - Generates
pkg/hbc/types/opcodes/bcvXX/hbcXX.gofor each version - Creates instruction lookup tables and builtin name lists
pkg/hbc/types/opcodes/bcv96/hbc96.go):Register the new version
Generated packages are not automatically used. You must register them in the parser.Edit
pkg/hbc/bytecode_parser.go and add the new version to parserModuleTable:Download Scripts Deep Dive
Thedownload_all.sh script runs three specialized downloaders:
Bytecode Definitions
Function Builtins
Regex Bytecode
Parser Version Fallback
Not every bytecode version requires its own parser entry. The parser uses a fallback strategy:- File has bytecode version 93
- Registered versions: 90, 92, 94, 96
- Parser uses version 92 (highest ≤ 93)
- If the new version introduces incompatible instruction changes
- If operand types change (e.g., Reg8 → Reg16)
- If the opcode table is reordered
- If only builtin names changed (use previous version)
- If changes are to unused instructions
Troubleshooting
download_all.sh fails to fetch files
download_all.sh fails to fetch files
Cause: Network issue or Hermes repository structure changed.Solution:
- Check your internet connection
- Verify the Hermes tag exists: https://github.com/facebook/hermes/tags
- Manually download missing files:
- Check script URLs in
pkg/utils/defversions/*/get_source.sh
genopcodes produces invalid Go code
genopcodes produces invalid Go code
Cause:
.def file format changed in newer Hermes versions.Solution:- Check the generated file:
pkg/hbc/types/opcodes/bcvXX/hbcXX.go - Compare with a working version (e.g.,
bcv96/hbc96.go) - Update the parser in
pkg/utils/(generator implementation) - File an issue on the Hedis repository with the
.deffile contents
Parser still can't read the bytecode version
Parser still can't read the bytecode version
Cause: Forgot to register the version in
parserModuleTable.Solution:- Check
pkg/hbc/bytecode_parser.goimports - Verify the version number in
parserModuleTable - Rebuild:
go build -o hermes-decompiler .
Disassembly output looks wrong
Disassembly output looks wrong
Cause: Opcode table mismatch or operand size errors.Solution:
- Compare disassembly with official Hermes disassembler:
- Check if operand sizes match (Reg8 vs Reg16 vs Reg32)
- Verify instruction order matches Hermes source
- Test with a simple known bundle (e.g.,
console.log('test'))
Supporting Custom Hermes Forks
If you’re using a custom Hermes fork with modified opcodes:Modify the download script
Edit
pkg/utils/defversions/hermes_bytecode_src/get_source.sh to use your custom files instead of downloading from GitHub.Version Mapping Reference
| Hermes Version | Bytecode Version | React Native Version |
|---|---|---|
| v0.5.0 | v74 | 0.64 |
| v0.7.0 | v76 | 0.66 |
| v0.9.0 | v84 | 0.68 |
| v0.11.0 | v90 | 0.70 |
| v0.12.0 | v93 | 0.72 |
| v0.13.0 | v95 | 0.74 |
| v0.14.0 | v96 | 0.76 |
Next Steps
- Analyze apps with the new parser
- Configure environment for your setup
- Build the database with packages using the new version