
Un obfuscateur JavaScript basé sur des techniques d’obfuscation cryptographique par indistinguabilité.
Ce projet n'atteint pas l'obfuscation d'indistinguabilité. Vous ne devriez pas utiliser ce produit pour protéger des secrets. Il existe pour dissuader la rétro-ingénierie, pas pour l'empêcher

Un obfuscateur JavaScript conçu pour rendre le code extrêmement difficile à lire et à analyser, aussi bien pour les humains que pour les LLM. Écrit en TypeScript. Il implémente des techniques issues de la recherche en obfuscation cryptographique évaluée par les pairs.
npm install
npm run build
# Basic usage
node dist/index.js input.js > output.js
# With target token budget (default: 2,000,000)
node dist/index.js --target-tokens 500000 input.js > output.js
# Minimal obfuscation (small output)
node dist/index.js --target-tokens 10000 input.js > output.js
# Maximum bloat (10M tokens)
node dist/index.js --target-tokens 10000000 input.js > output.js
# Using environment variable
INPUT_FILE=input.js node dist/index.js > output.js
# Help
node dist/index.js --help
| Option | Défaut | Description |
|---|---|---|
--target-tokens <n> | 2000000 | Taille de sortie cible en tokens. Les petites entrées sont gonflées jusqu'à cette limite. Les grandes entrées produisent moins de gonflement pour rester dans le budget. |
--help, -h | Affiche le message d'aide. |
npm run build # Compile TypeScript to dist/
npm run start # Run the obfuscator (reads input.js)
npm run test # Run the test suite
npm run obfuscate-package # Run compatibility tests against npm packages
const { obfuscate } = require('./dist/obfuscator');
const code = 'function add(a, b) { return a + b; }';
const obfuscated = obfuscate(code);
// With options
const obfuscated = obfuscate(code, { targetTokens: 500000 });
L'obfuscateur applique 20 transformations réparties en 4 phases. Chaque étape s'appuie sur la précédente.
| Ordre | Transformation | Fichier | Description |
|---|---|---|---|
| 1 | Pièges anti-débogage | transforms/antiDebug.ts | Injecte des instructions eval("debugger") et 10 à 20 boucles setInterval avec des intervalles de nombres premiers (5 s à 600 s) qui déclenchent à plusieurs reprises des points d'arrêt du débogueur. Chaque instance utilise des chaînes encodées uniques. |
| 2 | Déclencheurs de programme perforé | transforms/tripwires.ts | Intègre des vérifications cachées comparant des hachages de paramètres à des valeurs secrètes. 5 modèles de hachage (empreinte binaire, arithmétique modulaire, charCodeAt, hachage numérique, typeof+length). Déclenche une corruption silencieuse de l'état, des boucles actives ou des exceptions sur les entrées secrètes. [Paper 4] |
| 3 | Injection de bruit LPN | transforms/noiseInjection.ts | Ajoute et annule un bruit aléatoire via des chemins divisés dans les calculs arithmétiques. 6 modèles : add/sub, XOR, mul/div, double variable divisée, chaîne de hachage calculée, rotation de bits. Les valeurs intermédiaires sont dénuées de sens sans tracer l'annulation complète. [Paper 7] |
| Ordre | Transformation | Fichier | Description |
|---|---|---|---|
| 4 | Aplatissement du flux de contrôle | transforms/controlFlowFlattening.ts | Convertit les corps de fonction en machines à états while(true) { switch((_s * P) % M) { ... } } avec répartition par arithmétique modulaire — les valeurs de cas sont encodées via (stateId * multiplier) % modulus en utilisant des paramètres premiers aléatoires. [Paper 3] |
| 5 | Prédicats opaques | transforms/opaquePredicates.ts | Injecte des conditions if qui s'évaluent toujours à vrai ou à faux mais qui sont mathématiquement difficiles à prouver (par exemple, (x*x+x)%2===0). 15 formules de prédicats réparties dans les catégories arithmétique modulaire, opérations binaires et vérification de types. |
| 6 | Fonctions proxy | transforms/proxyFunctions.ts | Route tous les appels de fonction via deux répartiteurs : _fc(fn, ...args) pour les appels simples, _mc(obj, prop, ...args) pour les appels de méthode. Utilise Function.prototype.apply capturé dans une variable locale pour la résilience. |
| 7 | Épuisement de la fenêtre de contexte | transforms/contextExhaustion.ts | Enveloppe les expressions dans des ternaires profondément imbriqués avec des conditions opaques, des chaînes d'expressions void et du remplissage void conditionnel. Force les LLM à gaspiller les tokens de la fenêtre de contexte dans du bruit. |
| 8 | Fusion d'expressions à virgule | transforms/commaExpressions.ts | Réduit les instructions d'expression consécutives en une seule expression à virgule : a(); b(); return c() devient return a(), b(), c(). |
| Ordre | Passe | Fichier | Description |
|---|---|---|---|
| 9 | Passe 1 : Catalogue | passes/firstPass.ts | Parcourt l'AST et catalogue chaque identifiant, construisant une carte des globaux qui attribue à chacun un nom Unicode aléatoire de 6 à 16 caractères issu de 16 plages d'écritures (CJK, Hangul, grec, cyrillique, devanagari, thaï, arabe, katakana, etc.). |
| 10 | Passe 2 : Substitution | passes/secondPass.ts | Remplace tous les noms d'identifiants par leurs équivalents Unicode obfusqués. Encode les arguments de require() avec String.fromCharCode(...). Encode les sources d'import/export statiques comme des littéraux de chaîne échappés en Unicode. Substitue les références superClass de classes, les expressions de gabarits, les motifs de déstructuration. |
| 11 | Passe 3 : Paramètres factices | passes/thirdPass.ts | Injecte de 0 à 15 paramètres inutilisés aléatoires dans chaque déclaration et expression de fonction. Ignore les fonctions avec des paramètres de reste. Supprime tous les commentaires. |