Skip to main content

hermes-dec-bytecode-reverse-engineering

Disassemble and decompile React Native Hermes bytecode (HBC) files for reverse engineering

الانتقال إلى التثبيت

معلومات المصدر

المستودع
reason-machines/hermes-skills
آخر نشاط في المصدر
٦ يونيو ٢٠٢٦ في ٠٣:٠٦
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٥
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
hermes-dec-bytecode-reverse-engineering
description
Disassemble and decompile React Native Hermes bytecode (HBC) files for reverse engineering
triggers
["decompile hermes bytecode","disassemble react native hbc file","reverse engineer hermes bundle","parse hermes bytecode headers","extract javascript from android apk","analyze hermes vm bytecode","convert hbc to javascript","decode react native bundle"]
# Hermes-Dec Bytecode Reverse Engineering > Skill by [ara.so](https://ara.so) — Hermes Skills collection. ## Overview `hermes-dec` is a reverse-engineering tool for disassembling and decompiling React Native applications compiled to Hermes VM bytecode (HBC) format. It provides three main utilities: - **hbc-file-parser**: Parse and display HBC file headers and metadata - **hbc-disassembler**: Convert bytecode to assembly-like representation (.hasm) - **hbc-decompiler**: Decompile bytecode to pseudo-JavaScript code Hermes is the default JavaScript engine for React Native on Android (since RN 0.70) and is commonly found in mobile apps at `assets/index.android.bundle`. ## Installation ```bash # Using pipx (recommended for CLI tools) pipx install hermes-dec # Using uv uv tool install hermes-dec # Using pip pip install hermes-dec # From source git clone https://github.com/P1sec/hermes-dec.git cd hermes-dec pip install -e . ``` ### System-specific installations ```bash # Ubuntu (Snap) sudo snap install hermes-dec # Commands become: hermes-dec.hbc-disassembler, hermes-dec.hbc-file-parser, hermes-dec.hbc-decompiler # Arch Linux (AUR) yay -S hermes-dec ``` ## Extracting Hermes Bytecode from APK React Native Android apps package Hermes bytecode in APK files. Extract it first: ```bash # APK files are ZIP archives unzip my_application.apk -d my_application/ cd my_application/ # Verify it's Hermes bytecode file assets/index.android.bundle # Output: assets/index.android.bundle: Hermes JavaScript bytecode, version 84 # Or use 7z 7z x my_application.apk ``` Common locations in APK: - `assets/index.android.bundle` (main bundle) - `assets/*.hbc` (additional bundles) - `assets/index.android.bundle.hbc` ## Core Commands ### 1. Parse File Headers Inspect HBC file structure, bytecode version, and metadata: ```bash # Display file information to stdout hbc-file-parser assets/index.android.bundle # Save output to file hbc-file-parser assets/index.android.bundle > analysis.txt ``` **Example output:** ``` Hermes Bytecode File v84 File size: 2,453,678 bytes SHA1 hash: a1b2c3d4... Number of functions: 1,234 String table size: 45,678 entries Debug info: present ``` ### 2. Disassemble to Assembly Convert bytecode to human-readable assembly (.hasm format): ```bash # Output to stdout hbc-disassembler assets/index.android.bundle # Save to file hbc-disassembler assets/index.android.bundle output.hasm # Typical workflow hbc-disassembler index.android.bundle disassembled.hasm ``` **Example .hasm output:** ```assembly Function<loginUser>(3 params, 15 registers): Offset in debug table: source 0x0000 LoadParam r2, 1 LoadParam r3, 2 LoadConstString r1, "username" GetByVal r0, r2, r1 LoadConstString r1, "password" GetByVal r4, r2, r1 Call2 r0, r3, r0, r4 Ret r0 ``` ### 3. Decompile to Pseudo-JavaScript Generate pseudo-JavaScript code (not yet valid JS, missing control flow): ```bash # Output to stdout hbc-decompiler assets/index.android.bundle # Save to file hbc-decompiler assets/index.android.bundle decompiled.js # Typical workflow hbc-decompiler index.android.bundle output.js ``` **Example decompiled output:** ```javascript function loginUser(param0, param1, param2) { var r0, r1, r2, r3, r4; r2 = param1; r3 = param2; r1 = "username"; r0 = r2[r1]; r1 = "password"; r4 = r2[r1]; r0 = r3(r0, r4); return r0; } ``` ## Practical Workflows ### Full Analysis Pipeline ```bash #!/bin/bash # analyze_hbc.sh - Complete Hermes bytecode analysis APK_FILE="$1" OUTPUT_DIR="analysis_$(date +%Y%m%d_%H%M%S)" mkdir -p "$OUTPUT_DIR" # Extract APK echo "[+] Extracting APK..." unzip -q "$APK_FILE" -d "$OUTPUT_DIR/extracted" # Find HBC files echo "[+] Locating HBC files..." find "$OUTPUT_DIR/extracted" -name "*.bundle" -o -name "*.hbc" > "$OUTPUT_DIR/hbc_files.txt" # Process each HBC file while IFS= read -r hbc_file; do basename=$(basename "$hbc_file") echo "[+] Processing $basename..." # Parse headers hbc-file-parser "$hbc_file" > "$OUTPUT_DIR/${basename}.info.txt" # Disassemble hbc-disassembler "$hbc_file" "$OUTPUT_DIR/${basename}.hasm" # Decompile hbc-decompiler "$hbc_file" "$OUTPUT_DIR/${basename}.js" done < "$OUTPUT_DIR/hbc_files.txt" echo "[+] Analysis complete in $OUTPUT_DIR" ``` ### Searching for Specific Functions ```bash # Disassemble and search for API endpoints hbc-disassembler index.android.bundle output.hasm grep -i "https://" output.hasm # Find authentication-related code grep -i -E "(token|auth|password|login)" output.hasm # Decompile and search for specific strings hbc-decompiler index.android.bundle output.js grep -i "api_key" output.js ``` ### Comparing Versions ```bash # Compare two versions of the same app hbc-disassembler old_version/index.android.bundle old.hasm hbc-disassembler new_version/index.android.bundle new.hasm # Diff the assembly diff -u old.hasm new.hasm > changes.diff # Or use a better diff tool code --diff old.hasm new.hasm ``` ## Python API Usage While hermes-dec is primarily a CLI tool, you can import its modules in Python: ```python #!/usr/bin/env python3 """ Example: Programmatic access to hermes-dec functionality """ import sys from pathlib import Path # Import hermes-dec modules (structure may vary by version) # Note: Internal API may change; CLI is the stable interface def analyze_hbc_file(hbc_path: Path): """ Analyze an HBC file programmatically """ if not hbc_path.exists(): print(f"Error: {hbc_path} not found") return # Read file header with open(hbc_path, 'rb') as f: magic = f.read(8) if magic[:4] != b'\xC6\x1F\xBC\x03': print("Not a valid Hermes bytecode file") return # Version is at offset 4 version = int.from_bytes(magic[4:8], 'little') print(f"Hermes bytecode version: {version}") # For detailed parsing, use the CLI tools import subprocess # Get file info result = subprocess.run( ['hbc-file-parser', str(hbc_path)], capture_output=True, text=True ) if result.returncode == 0: print("\n=== File Info ===") print(result.stdout) if __name__ == "__main__": if len(sys.argv) < 2: print("Usage: python analyze.py <hbc_file>") sys.exit(1) analyze_hbc_file(Path(sys.argv[1])) ``` ### Batch Processing Script ```python #!/usr/bin/env python3 """ Batch process multiple APK files for Hermes bytecode analysis """ import subprocess import zipfile from pathlib import Path from typing import List def extract_hbc_from_apk(apk_path: Path, output_dir: Path) -> List[Path]: """ Extract HBC files from an APK Returns list of extracted HBC file paths """ hbc_files = [] output_dir.mkdir(parents=True, exist_ok=True) with zipfile.ZipFile(apk_path, 'r') as apk: for name in apk.namelist(): if name.endswith('.bundle') or name.endswith('.hbc'): # Extract file target = output_dir / Path(name).name with apk.open(name) as source, open(target, 'wb') as dest: dest.write(source.read()) # Verify it's HBC if is_hermes_bytecode(target): hbc_files.append(target) print(f"[+] Extracted {name} -> {target}") return hbc_files def is_hermes_bytecode(file_path: Path) -> bool: """Check if file is Hermes bytecode""" try: with open(file_path, 'rb') as f: magic = f.read(4) return magic == b'\xC6\x1F\xBC\x03' except: return False def decompile_hbc(hbc_path: Path, output_path: Path): """Decompile HBC file to pseudo-JavaScript""" subprocess.run( ['hbc-decompiler', str(hbc_path), str(output_path)], check=True ) print(f"[+] Decompiled {hbc_path.name} -> {output_path}") def main(): apk_dir = Path("apks") output_base = Path("decompiled") for apk in apk_dir.glob("*.apk"): print(f"\n[*] Processing {apk.name}") # Create output directory for this APK apk_output = output_base / apk.stem apk_output.mkdir(parents=True, exist_ok=True) # Extract HBC files hbc_files = extract_hbc_from_apk(apk, apk_output / "extracted") # Decompile each for hbc in hbc_files: js_output = apk_output / f"{hbc.stem}.js" try: decompile_hbc(hbc, js_output) except subprocess.CalledProcessError as e: print(f"[!] Failed to decompile {hbc.name}: {e}") if __name__ == "__main__": main() ``` ## Understanding Output Formats ### Assembly (.hasm) Format The disassembler outputs Hermes VM assembly instructions: ```assembly Function<ComponentName>(params, registers): # Instruction Dest Source1 Source2 LoadParam r0, 1 # Load first parameter LoadConstString r1, "key" # Load string constant GetByVal r2, r0, r1 # Property access: r0[r1] Call r3, r2 # Function call Ret r3 # Return value ``` Common opcodes: - `LoadParam`: Load function parameter - `LoadConst*`: Load constants (string, number, undefined, etc.) - `GetByVal`/`PutByVal`: Property access - `Call*`: Function calls - `NewObject`/`NewArray`: Object/array creation - `Ret`: Return from function - `Jmp*`: Jump instructions (control flow) ### Pseudo-JavaScript Format The decompiler outputs register-based pseudo-code: ```javascript // Not yet valid JavaScript - shows data flow function example(param0, param1) { var r0, r1, r2, r3; // Registers r0 = param0; // Parameter assignment r1 = "property"; // String constant r2 = r0[r1]; // Property access r3 = someFunc(r2); // Function call return r3; } ``` **Limitations:** - No control flow reconstruction (loops, conditionals appear linear) - Register-based (not variable-based) - May have dead code - Requires manual cleanup for valid JS ## Troubleshooting ### Not a Hermes Bytecode File ```bash $ file index.android.bundle index.android.bundle: ASCII text, with very long lines ``` **Solution**: This is minified JavaScript, not Hermes bytecode. The app doesn't use Hermes engine or you have the wrong file. ### Unsupported Bytecode Version ``` Error: Unsupported bytecode version 96 ``` **Solution**: Update hermes-dec to the latest version: ```bash pipx upgrade hermes-dec # or pip install --upgrade hermes-dec ``` If still unsupported, check the [GitHub issues](https://github.com/P1sec/hermes-dec/issues) or open a new one. ### Incomplete Decompilation The decompiler output is incomplete or has missing functions. **Solution**: Try disassembly first to understand structure: ```bash # Disassemble to see raw instructions hbc-disassembler file.bundle output.hasm # Then manually interpret critical sections # The decompiler is best-effort; some complex patterns may not decompile ``` ### Empty Output Files ```bash $ hbc-decompiler index.android.bundle output.js $ wc -l output.js 0 output.js ``` **Solution**: Check file format and permissions: ```bash # Verify it's HBC file index.android.bundle hexdump -C index.android.bundle | head # Check permissions ls -la index.android.bundle # Try with stdout first hbc-decompiler index.android.bundle ``` ### APK Extraction Issues ```bash $ unzip app.apk error: cannot find or open app.apk ``` **Solution**: Ensure APK is not corrupted: ```bash # Verify ZIP structure 7z t app.apk # Try alternative extraction jar xf app.apk # or python -m zipfile -e app.apk output_dir/ ``` ## Advanced Techniques ### Finding Obfuscated Strings ```bash # Decompile and search for base64 hbc-decompiler index.android.bundle output.js grep -E '[A-Za-z0-9+/]{20,}={0,2}' output.js # Look for hex patterns grep -E '0x[0-9a-fA-F]{4,}' output.js ```
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub