Home
/
Blog
/

Releasing hermes-dec, an open-source disassembler and decompiler for the React Native Hermes bytecode

P1 Security releases Hermes-Dec, an open-source React Native Hermes bytecode disassembler and decompiler.

Service annoucement
Jan 9, 2023
Releasing hermes-dec, an open-source disassembler and decompiler for the React Native Hermes bytecode

Mobile operators are distributing more and more Android and iOS applications in order to interface with their APIs and provide enhanced services to their subscribers. The need for P1 Security to reverse engineer mobile platform-targeted applications in the context of black-box security audits, as well as the global lack of effective tools regarding reverse engineering React Native-based applications, led us to develop hermes-dec.

P1 Security is publishing the initial release of hermes-dec, a new tool for reverse engineering React Native mobile applications for Android and iOS embedding a JS bundle compiled within the bytecode language of the Hermes virtual machine.

Hermes Bytecode

The Hermes bytecode is a binary-form, intermediary representation of Javascript which is used as a mean of optimizing the execution speed of React Native mobile applications. Announced by Facebook on July 2019, and ultimately used by default in new React Native projects since September 2022, we have seen the Hermes bytecode format used in many popular React Native applications, whilst React Native itself is an increasingly popular mobile software development platform, and a major cross-platform mobile development framework.

When enabled, the Hermes bytecode compiler is used to produce a binary-form output into the “assets/index.android.bundle” file present in the file tree of the Android .APK file (which is a renamed and signed .ZIP file). When Hermes is not enabled, the “assets/index.android.bundle” will contain a plain, classical minified JavaScript bundle.

Hermes bytecode files can be recognized by the libmagic library on Linux, which means that the type of the corresponding files can be identified using the “file” command-line utility:

$ file assets/index.android.bundle
assets/index.android.bundle: Hermes JavaScript bytecode, version 84

Relevant tools

The hermes-dec tool released by P1 Security allows to disassemble the Hermes bytecode, with the intent to be compatible will all public version of the Hermes virtual machines (from 0.1.0 to the current 0.12.0, or bytecode version 89, at the time of writing, end of 2022). Other tools such as the hbctool utility support a more restricted set of versions of the Hermes bytecode, and the hbcdump tool present in the Hermes source tree supports the exact version of the Hermes virtual machine it was built for.

In addition, it allows to decompile the associated code into JavaScript-like pseudo-code. Please keep in mind that this is the equivalent of beautifying a minified React Native bundle, hence nor the naming of the variables, nor the original control flow, neither the structure of functions will be reconstructed as an outcome of the decompilation process.

It was developed considering the need for P1 Security to often reverse engineer mobile platform-targeted applications in the context of black-box security audits, as well as the global lack of effective tools regarding reverse engineering React Native-based applications.

Currently, hermes-dec should be able to decode the whole Hermes VM instruction set and to produce a single decompiled bundle file with nested closures (as the pre-binary compilation code step is).

The pseudo-code decompiler currently has the following limitations in regard to valid Javascript:

  • It outputs jump instructions and labels instead of structured conditions and loops (we hope to reconstruct conditions and loops in the future, but this will require some graph-based processing of the basic blocks present within the decompiled code in order to undo certain LLVM optimization, as the Hermes VM compiler relies on LLVM)
  • It uses registers rather than local variables.
  • Generally, it doesn’t merge yet many instruction-unit statements into single statements (such an optimization/variable renaming phase should be added when conditional and loop structures will be reconstructed, we may then use an external JavaScript reprocessing tool for this purpose).

Here is a sample of what the pseudo-code produced by the decompiler (using the "hbc-decompiler"command) currently looks like:

        r6 = 'recordInteraction';
        r4['key'] = r6;
        r6 = function() { // Original name: recordInteraction, environment: r5
            r0 = this;
            r1 = r0._listRef;
            JumpNotCondition(target_address=27)r1;
            r1 = r0._listRef;
            r0 = r1.recordInteraction;
            r0 = r0.bind(r1)();
label_27:
            r0 = undefined;

Here is a sample of what the disassembled code (produced by the "hbc-disassembler" script) looks like:

=> [Function #1930 "emitEvent" of 65 bytes]: 2 params, frame size=12, env size=1, read index sz=3, write index sz=0, strict=0, exc handler=0, debug info=0  @ offset 0x00158e2b

Bytecode listing:

==> 00000000: <CreateEnvironment>: <Reg8: 1>
==> 00000002: <LoadThisNS>: <Reg8: 2>
==> 00000004: <GetById>: <Reg8: 0, Reg8: 2, UInt8: 1, string_id: 18692>  # String: '_listeners' (Identifier)
==> 0000000a: <GetByIdShort>: <Reg8: 3, Reg8: 0, UInt8: 2, string_id: 169>  # String: 'length' (Identifier)
==> 0000000f: <LoadConstZero>: <Reg8: 0>
==> 00000011: <JStrictEqual>: <Addr8: 44, Reg8: 3, Reg8: 0>  # Address: 0000003d
==> 00000015: <LoadConstUndefined>: <Reg8: 0>
==> 00000017: <StoreNPToEnvironment>: <Reg8: 1, UInt8: 0, Reg8: 0>
==> 0000001b: <LoadParam>: <Reg8: 3, UInt8: 1>
==> 0000001e: <Call1>: <Reg8: 3, Reg8: 3, Reg8: 0>

This is open-source software, feel free to give it a try and provide any feedback and contribution. Please also note that this tool was initially made by P1 Security for its internal use and that its stability for other uses is not guaranteed.

-> Check code and usage instructions on Github<-

Summary
Download our whitepaper

LTE Pwnage: Hacking HLR/HSS and MME Core Network Elements

By clicking download you confirm that you accept our terms and conditions.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Be informed

SS7 Attacker Heaven turns into Riot: How to make Nation-State and Intelligence Attackers’ lives much harder on mobile networks

By clicking download you confirm that you accept our terms and conditions.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Towards Harmonization: Mapping EU Telecom Security Regulations and their evolution

By clicking download you confirm that you accept our terms and conditions.
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.