
Inspecte, décompile et applique des correctifs structurels au bytecode Hermes (HBC) des applications React Native, avec un REPL de style GDB, un CFG, un décompilateur et un patcheur de re-sérialisation.
Hermes Reverse Engineering & Manipulation Interactive Toolkit.
hermit inspecte, décompile et patche structurellement le bytecode Hermes (HBC), le
format dans lequel les applications React Native livrent leur JavaScript. Ouvrez un fichier .hbc, parcourez
ses fonctions, lisez le JavaScript décompilé, modifiez les instructions, les chaînes et les
littéraux dans un éditeur interactif, et réécrivez un fichier que la VM Hermes
charge et exécute encore.
Contrairement aux outils qui ne font qu'analyser le bytecode, ou qui le patchent sur place sans changer les tailles, hermit re-sérialise le fichier entier. Il peut insérer et supprimer des instructions, relocaliser les sauts et les gestionnaires d'exceptions, reconstruire les tables de chaînes et de littéraux, ajouter de nouvelles fonctions et recalculer le pied de page SHA-1. Un fichier non modifié effectue un aller-retour octet pour octet.
.hbc| Version | Rôle |
|---|---|
| 96 | Cible principale. Ce qu'utilisent les applications React Native livrées : RN 0.73 à 0.83, et RN 0.84+ avec Hermes V1 désactivé. |
| 94, 95 | Validées. Le format est identique à la 96, seules les tables d'opcodes diffèrent. |
Les applications compilées avec Hermes V1 (par défaut à partir de RN 0.84) émettent du HBC 98, qui n'est pas
encore pris en charge. Les notes de format sont dans doc/hbc-format/.
Chaque release contient des archives pour macOS et Linux, sur arm64 et x86_64. Aucun Python ni compilateur n'est nécessaire :
| Archive | Contenu |
|---|---|
hermit-<version>-<platform>.tar.gz | Le REPL interactif : ./hermit file.hbc. |
hermit-tools-<version>-<platform>.tar.gz | Les outils en ligne de commande hbc_* autonomes. |
SHA256SUMS | Sommes de contrôle : shasum -a 256 -c SHA256SUMS. |
tar -xzf hermit-0.1.0-macos-arm64.tar.gz
./hermit-0.1.0-macos-arm64/hermit --version
Les binaires macOS ne sont pas signés. Après le téléchargement, effacez le drapeau de quarantaine
une fois : xattr -dr com.apple.quarantine hermit-0.1.0-macos-arm64. Les builds Linux
nécessitent glibc 2.35 ou plus récent. La commande cfg nécessite toujours graph-easy installé.
Les releases sont produites par .github/workflows/release.yml lorsqu'un tag v* est
poussé, en utilisant packaging/build-release.sh, que vous pouvez aussi exécuter localement.
FetchContent sauf s'ils sont déjà installés.graph-easy pour la commande cfg
(cpanm Graph::Easy), less comme paginateur.Exécutez tout depuis ce répertoire (celui contenant CMakeLists.txt) :
cmake -B build
cmake --build build -j
Cela compile la bibliothèque statique libhbc, le module Python _libhbc (dans
build/bindings/), les outils en ligne de commande (dans build/tools/) et les tests
unitaires. Le REPL n'a besoin que du module Python :
cmake --build build --target _libhbc
Les outils et les tests peuvent être exclus d'un build, par exemple pour une release :
cmake -B build -DCMAKE_BUILD_TYPE=Release -DHERMIT_BUILD_TOOLS=OFF -DHERMIT_BUILD_TESTS=OFF
Recompilez avec la même commande après chaque modification de core/ ou bindings/.
macOS : si l'édition de liens échoue avec une erreur concernant un SDK malformé, pointez le build vers un SDK complet, par exemple
SDKROOT=/Library/Developer/CommandLineTools/SDKs/MacOSX26.5.sdk cmake --build build.
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
Le module _libhbc n'est pas installé dans le virtualenv. Ajoutez son répertoire de build
à PYTHONPATH chaque fois que vous exécutez hermit :
export PYTHONPATH=$PWD/build/bindings:$PYTHONPATH
.hbcUne application React Native livre son bundle sous forme de fichier simple :
| Plateforme | Emplacement dans le paquet |
|---|---|
Android (.apk, un zip) | assets/index.android.bundle |
iOS (.ipa, un zip) | Payload/<App>.app/main.jsbundle |
Si le fichier commence par les octets C6 1F BC 03 C1 03 19 1F, c'est du bytecode Hermes.
Le REPL n'ouvre que les fichiers avec l'extension .hbc, donc renommez-le :
unzip -p app.apk assets/index.android.bundle > app.hbc
xxd app.hbc | head -1 # c61f bc03 c103 191f ...
N'analysez que les applications que vous êtes autorisé à étudier, par exemple les vôtres, ou des applications open-source pour la recherche.
Pour obtenir des entrées petites et contrôlées, compilez du JavaScript ou du TypeScript avec un compilateur Hermes
qui émet du HBC 96 (par exemple hermesc de react-native 0.73 à
0.83, sous node_modules/react-native/sdks/hermesc/) :
hermes -emit-binary -g0 -out hello.hbc hello.js # -g0: no debug info
Le paquet seeder/ automatise cela pour les programmes d'exemple dans
seeder/samples/ et écrit les résultats dans seeder/corpus/ :
.venv/bin/python -m seeder.compile # all samples
.venv/bin/python -m seeder.compile --g0 seeder/samples/loop_sum.js
.venv/bin/python -m seeder.compile --debug seeder/samples/greeting.js
--g0 écrit <name>_g0.hbc sans informations de débogage, --debug écrit
<name>_g.hbc avec les informations de débogage complètes. Les exemples .ts nécessitent tsc dans votre PATH ;
le compilateur est pris depuis --hermes (par défaut hermes). seeder/build-real-bundle.sh
compile une vraie application React Native open-source en un .hbc.
export PYTHONPATH=$PWD/build/bindings:$PYTHONPATH
.venv/bin/python -m cli.main app.hbc
Sans argument de fichier, le REPL démarre vide ; utilisez open <file.hbc>. L'invite
affiche la version HBC et le nom du fichier, avec un + lorsqu'il y a des
modifications non enregistrées : [hbc v96 | app+] >. L'historique est conservé dans ~/.hermit_history
et les commandes sont complétées par tabulation.