Référence des options
Sommaire
compact
config
controlFlowFlattening
controlFlowFlatteningThreshold
deadCodeInjection
deadCodeInjectionThreshold
debugProtection
debugProtectionInterval
disableConsoleOutput
domainLock
Domaines et sous-domaines multiples
domainLockRedirectUrl
exclude
forceTransformStrings
identifierNamesCache
API Node.js
CLI
identifierNamesGenerator
identifiersDictionary
identifiersPrefix
randomIdentifiersPrefix
ignoreImports
inputFileName
log
numbersToExpressions
optionsPreset
parseHtml
renameGlobals
renameProperties
renamePropertiesMode
reservedNames
reservedStrings
seed
selfDefending
simplify
sourceMap
sourceMapBaseUrl
sourceMapFileName
sourceMapMode
sourceMapSourcesMode
splitStrings
splitStringsChunkLength
stringArray
stringArrayCallsTransform
stringArrayCallsTransformThreshold
stringArrayEncoding
stringArrayIndexesType
stringArrayIndexShift
stringArrayRotate
stringArrayShuffle
stringArrayWrappersCount
stringArrayWrappersChainedCalls
stringArrayWrappersParametersMaxCount
stringArrayWrappersType
stringArrayThreshold
strictMode
target
transformObjectKeys
warnings
vmObfuscation
vmTargetFunctions
vmExcludeFunctions
vmTargetFunctionsMode
vmForceCompileDynamicCode
vmWrapTopLevelInitializers
vmDynamicOpcodes
vmBytecodeEncoding
vmBytecodeArrayEncoding
vmBytecodeArrayEncodingKey
vmBytecodeArrayEncodingKeyGetter
vmAsyncExecutor
vmJumpsEncoding
vmMacroOps
vmDebugProtection
vmSelfDefending
vmDefenseHook
vmDefenseReaction
vmStatefulOpcodes
vmCallContextOpcodes
vmStackEncoding
vmCompactDispatcher
vmStringArrayBytecodeOnly
vmDomainLock
Domaines et sous-domaines multiples
vmDomainLockRedirectUrl
Options de préréglage
Obfuscation élevée, performances faibles
Obfuscation moyenne, performances optimales
Obfuscation faible, performances élevées
Préréglage par défaut, performances élevées
Obfuscation VM Ultra High (sécurité maximale)
VM Anti-LLM (protection contre les agents IA)
Obfuscation VM High (sécurité la plus élevée)
Obfuscation VM Medium (sécurité équilibrée)
Obfuscation VM Low (sécurité de base, meilleures performances)
VM Default (VM + protection du tableau de chaînes)
compact
Type: boolean Default: true
Sortie de code compacte sur une seule ligne.
config
Type: string Default: ``
Nom du fichier de configuration JS/JSON contenant les options de l'obfuscateur. Ces options seront remplacées par celles passées directement en ligne de commande (CLI).
controlFlowFlattening
Type: boolean Default: false
⚠️ Cette option affecte fortement les performances, jusqu'à une exécution 1,5x plus lente. Utilisez controlFlowFlatteningThreshold pour définir le pourcentage de nœuds concernés par l'aplatissement du flux de contrôle.
Active l'aplatissement du flux de contrôle du code. L'aplatissement du flux de contrôle est une transformation de la structure du code source qui en complique la compréhension.
Exemple :
// input
(function(){
function foo () {
return function () {
var sum = 1 + 2;
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
console.log(6);
}
}
foo()();
})();
// output
(function () {
function _0x3bfc5c() {
return function () {
var _0x3260a5 = {
'WtABe': '4|0|6|5|3|2|1',
'GokKo': function _0xf87260(_0x427a8e, _0x43354c) {
return _0x427a8e + _0x43354c;
}
};
var _0x1ad4d6 = _0x3260a5['WtABe']['split']('|'), _0x1a7b12 = 0x0;
while (!![]) {
switch (_0x1ad4d6[_0x1a7b12++]) {
case '0':
console['log'](0x1);
continue;
case '1':
console['log'](0x6);
continue;
case '2':
console['log'](0x5);
continue;
case '3':
console['log'](0x4);
continue;
case '4':
var _0x1f2f2f = _0x3260a5['GokKo'](0x1, 0x2);
continue;
case '5':
console['log'](0x3);
continue;
case '6':
console['log'](0x2);
continue;
}
break;
}
};
}
_0x3bfc5c()();
}());
controlFlowFlatteningThreshold
Type: number Default: 0.75 Min: 0 Max: 1
Probabilité que la transformation controlFlowFlattening soit appliquée à un nœud donné.
Ce paramètre est particulièrement utile pour les codes volumineux, car un grand nombre de transformations du flux de contrôle peut ralentir votre code et en augmenter la taille.
controlFlowFlatteningThreshold: 0 équivaut à controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Augmente considérablement la taille du code obfusqué (jusqu'à 200 %) ; à n'utiliser que si la taille du code obfusqué n'a pas d'importance. Utilisez deadCodeInjectionThreshold pour définir le pourcentage de nœuds concernés par l'injection de code mort.
⚠️ Cette option active de force l'option stringArray.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé.
Avec cette option, des blocs aléatoires de code mort sont ajoutés au code obfusqué.
Exemple :
// input
(function(){
if (true) {
var foo = function () {
console.log('abc');
};
var bar = function () {
console.log('def');
};
var baz = function () {
console.log('ghi');
};
var bark = function () {
console.log('jkl');
};
var hawk = function () {
console.log('mno');
};
foo();
bar();
baz();
bark();
hawk();
}
})();
// output
var _0x37b8 = [
'YBCtz',
'GlrkA',
'urPbb',
'abc',
'NMIhC',
'yZgAj',
'zrAId',
'EtyJA',
'log',
'mno',
'jkl',
'def',
'Quzya',
'IWbBa',
'ghi'
];
function _0x43a7(_0x12cf56, _0x587376) {
_0x43a7 = function (_0x2f87a8, _0x47eac2) {
_0x2f87a8 = _0x2f87a8 - (0x16a7 * 0x1 + 0x5 * 0x151 + -0x1c92);
var _0x341e03 = _0x37b8[_0x2f87a8];
return _0x341e03;
};
return _0x43a7(_0x12cf56, _0x587376);
}
(function () {
if (!![]) {
var _0xbbe28f = function () {
var _0x2fc85f = _0x43a7;
if (_0x2fc85f(0xaf) === _0x2fc85f(0xae)) {
_0x1dd94f[_0x2fc85f(0xb2)](_0x2fc85f(0xb5));
} else {
console[_0x2fc85f(0xb2)](_0x2fc85f(0xad));
}
};
var _0x5e46bc = function () {
var _0x15b472 = _0x43a7;
if (_0x15b472(0xb6) !== _0x15b472(0xaa)) {
console[_0x15b472(0xb2)](_0x15b472(0xb5));
} else {
_0x47eac2[_0x15b472(0xb2)](_0x15b472(0xad));
}
};
var _0x3669e8 = function () {
var _0x47a442 = _0x43a7;
if (_0x47a442(0xb7) !== _0x47a442(0xb0)) {
console[_0x47a442(0xb2)](_0x47a442(0xb8));
} else {
_0x24e0bf[_0x47a442(0xb2)](_0x47a442(0xb3));
}
};
var _0x28b05a = function () {
var _0x497902 = _0x43a7;
if (_0x497902(0xb1) === _0x497902(0xb1)) {
console[_0x497902(0xb2)](_0x497902(0xb4));
} else {
_0x59c9c6[_0x497902(0xb2)](_0x497902(0xb4));
}
};
var _0x402a54 = function () {
var _0x1906b7 = _0x43a7;
if (_0x1906b7(0xab) === _0x1906b7(0xac)) {
_0xb89cd0[_0x1906b7(0xb2)](_0x1906b7(0xb8));
} else {
console[_0x1906b7(0xb2)](_0x1906b7(0xb3));
}
};
_0xbbe28f();
_0x5e46bc();
_0x3669e8();
_0x28b05a();
_0x402a54();
}
}());
deadCodeInjectionThreshold
Type: number Default: 0.4 Min: 0 Max: 1
Permet de définir le pourcentage de nœuds concernés par deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Peut figer votre navigateur si vous ouvrez les outils de développement.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmDebugProtection.
Cette option rend presque impossible l'utilisation de la fonction debugger des outils de développement (aussi bien sur les navigateurs basés sur WebKit que sur Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Peut figer votre navigateur ! À utiliser à vos risques et périls.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmDebugProtection.
Si cette option est définie, un intervalle en millisecondes est utilisé pour forcer le mode débogage sur l'onglet Console, rendant plus difficile l'utilisation des autres fonctionnalités des outils de développement. Fonctionne si debugProtection est activé. La valeur recommandée est comprise entre 2000 et 4000 millisecondes.
disableConsoleOutput
Type: boolean Default: false
⚠️ Cette option désactive les appels à console de façon globale pour tous les scripts
Désactive l'utilisation de console.log, console.info, console.error, console.warn, console.debug, console.exception et console.trace en les remplaçant par des fonctions vides. Cela rend l'utilisation du débogueur plus difficile.
domainLock
Type: string[] Default: []
⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'
Permet d'exécuter le code source obfusqué uniquement sur des domaines et/ou sous-domaines précis. Cela rend très difficile le simple copier-coller de votre code source pour l'exécuter ailleurs.
Si le code source n'est pas exécuté sur les domaines spécifiés par cette option, le navigateur est redirigé vers l'URL passée à l'option domainLockRedirectUrl.
Domaines et sous-domaines multiples
Il est possible de verrouiller votre code sur plusieurs domaines ou sous-domaines. Par exemple, pour le verrouiller de sorte qu'il ne s'exécute que sur www.example.com, ajoutez www.example.com. Pour qu'il fonctionne sur le domaine racine ainsi que sur tous ses sous-domaines (example.com, sub.example.com), utilisez .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'
Permet de rediriger le navigateur vers une URL fournie si le code source n'est pas exécuté sur les domaines spécifiés par domainLock
exclude
Type: string[] Default: []
Noms de fichiers ou motifs glob indiquant les fichiers à exclure de l'obfuscation.
forceTransformStrings
Type: string[] Default: []
Force la transformation des littéraux de chaîne correspondant aux motifs RegExp fournis.
⚠️ Cette option n'affecte que les chaînes qui ne devraient pas être transformées par stringArrayThreshold (ou d'éventuels autres seuils à l'avenir)
Cette option a priorité sur l'option reservedStrings, mais pas sur les conditional comments.
Exemple :
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
L'objectif principal de cette option est de pouvoir réutiliser les mêmes noms d'identifiants lors de l'obfuscation de plusieurs sources/fichiers.
Actuellement, deux types d'identifiants sont pris en charge :
- Identifiants globaux :
- Tous les identifiants globaux sont écrits dans le cache ;
- Tous les identifiants globaux non déclarés correspondants sont remplacés par les valeurs du cache.
- Identifiants de propriété, uniquement lorsque l'option
renamePropertiesest activée :- Tous les identifiants de propriété sont écrits dans le cache ;
- Tous les identifiants de propriété correspondants sont remplacés par les valeurs du cache.
API Node.js
Si la valeur null est passée, le cache est entièrement désactivé.
Si un objet vide ({}) est passé, l'écriture des noms d'identifiants dans l'objet-cache (type TIdentifierNamesCache) est activée. Cet objet-cache est accessible via l'appel de la méthode getIdentifierNamesCache de l'objet ObfuscationResult.
L'objet-cache obtenu peut ensuite être utilisé comme valeur de l'option identifierNamesGenerator afin de réutiliser ces noms lors de l'obfuscation de tous les identifiants correspondants des sources suivantes.
Exemple :
const source1ObfuscationResult = JavaScriptObfuscator.obfuscate(
`
function foo(arg) {
console.log(arg)
}
function bar() {
var bark = 2;
}
`,
{
compact: false,
identifierNamesCache: {},
renameGlobals: true
}
)
console.log(source1ObfuscationResult.getIdentifierNamesCache());
/*
{
globalIdentifiers: {
foo: '_0x5de86d',
bar: '_0x2a943b'
}
}
*/
const source2ObfuscationResult = JavaScriptObfuscator.obfuscate(
`
// Expecting that these global functions are defined in another obfuscated file
foo(1);
bar();
// Expecting that this global function is defined in third-party package
baz();
`,
{
compact: false,
identifierNamesCache: source1ObfuscationResult.getIdentifierNamesCache(),
renameGlobals: true
}
)
console.log(source2ObfuscationResult.getObfuscatedCode());
/*
_0x5de86d(0x1);
_0x2a943b();
baz();
*/
CLI
La CLI dispose d'une option différente, --identifier-names-cache-path, qui permet de définir le chemin d'un fichier .json existant servant à lire et écrire le cache des noms d'identifiants.
Si le chemin d'un fichier vide est passé, le cache des noms d'identifiants y sera écrit.
Ce fichier contenant un cache existant peut être réutilisé comme valeur de l'option --identifier-names-cache-path afin de réutiliser ces noms lors de l'obfuscation de tous les identifiants correspondants des fichiers suivants.
identifierNamesGenerator
Type: string Default: hexadecimal
Définit le générateur de noms d'identifiants.
Valeurs disponibles :
dictionary: noms d'identifiants issus de la listeidentifiersDictionaryhexadecimal: noms d'identifiants du type_0xabc123mangled: noms d'identifiants courts commea,b,cmangled-shuffled: identique àmangled, mais avec un alphabet mélangé
identifiersDictionary
Type: string[] Default: []
Définit le dictionnaire d'identifiants pour l'option identifierNamesGenerator : dictionary. Chaque identifiant du dictionnaire sera utilisé en plusieurs variantes, avec une casse différente pour chaque caractère. Le nombre d'identifiants du dictionnaire doit donc dépendre du nombre d'identifiants présents dans le code source d'origine.
identifiersPrefix
Type: string Default: ''
Définit un préfixe pour tous les identifiants globaux.
Utilisez cette option lorsque vous obfusquez plusieurs fichiers. Elle permet d'éviter les conflits entre les identifiants globaux de ces fichiers. Le préfixe doit être différent pour chaque fichier.
randomIdentifiersPrefix
Type: boolean Default: false
Ajoute un préfixe aléatoire dérivé de la graine (6 caractères alphanumériques) à tous les identifiants globaux. Utilisez cette option pour éviter les collisions entre des bundles obfusqués séparément et chargés dans la même portée globale — elle évite d'avoir à choisir manuellement un identifiersPrefix unique pour chaque bundle.
- La valeur aléatoire est dérivée de l'option
seedet du hash du code source ; des builds reproductibles avec la même graine produisent donc le même préfixe. - Combinée à
identifiersPrefix, les caractères aléatoires sont ajoutés à la suite du préfixe fourni par l'utilisateur (par exemplemyApp+aBc123aléatoire →myAppaBc123). - Combinée à
vmObfuscation, la valeur aléatoire remplace le préfixevmpar défaut — le caractère aléatoire garantit déjà l'unicité.
ignoreImports
Type: boolean Default: false
Empêche l'obfuscation des imports require. Peut être utile dans certains cas où, pour une raison ou une autre, l'environnement d'exécution exige que ces imports utilisent uniquement des chaînes statiques.
inputFileName
Type: string Default: ''
Permet de définir le nom du fichier d'entrée contenant le code source. Ce nom est utilisé en interne pour la génération de la source map.
Requis lors de l'utilisation de l'API NodeJS lorsque l'option sourceMapSourcesMode a la valeur sources.
log
Type: boolean Default: false
Active la journalisation des informations dans la console.
numbersToExpressions
Type: boolean Default: false
Active la conversion des nombres en expressions.
Exemple :
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Permet de définir un préréglage d'options.
Valeurs disponibles :
vm-default;vm-low-obfuscation;vm-medium-obfuscation;vm-high-obfuscation;vm-ultra-high-obfuscation;vm-anti-llm;default;low-obfuscation;medium-obfuscation;high-obfuscation.
Toutes les options supplémentaires seront fusionnées avec le préréglage d'options sélectionné.
parseHtml
Type: boolean Default: false
Active l'obfuscation du JavaScript contenu dans les balises HTML <script>.
Lorsqu'elle est activée, l'obfuscateur :
- Détecte automatiquement si l'entrée est du HTML (en recherchant les balises
<!DOCTYPE,<html>,<head>,<body>ou<script>) - Extrait le JavaScript des balises
<script>marquées par l'attributdata-javascript-obfuscator - Obfusque chaque script marqué individuellement tout en préservant la structure HTML
- Réinjecte le code obfusqué à ses positions d'origine
Important : seuls les scripts portant l'attribut data-javascript-obfuscator sont obfusqués. Chaque script marqué est obfusqué de façon individuelle et indépendante. Cela signifie que :
- Le code contenu dans les balises de script marquées doit être isolé : il ne doit PAS référencer de variables, fonctions ou classes définies dans d'autres balises de script marquées
- Les scripts non marqués peuvent tout de même accéder aux globales définies par les scripts marqués (via des déclarations
varou des affectations explicites àglobalThis) - Cela vous donne un contrôle explicite sur les scripts à protéger
Obfusqués (doivent porter l'attribut data-javascript-obfuscator) :
<script data-javascript-obfuscator>- scripts ordinaires<script type="text/javascript" data-javascript-obfuscator>- scripts au type explicite- Scripts comportant des attributs supplémentaires (
id,class, autresdata-*, etc.)
Ignorés (laissés inchangés) :
- Scripts sans l'attribut
data-javascript-obfuscator <script type="module">- modules ES (même avec l'attribut)<script src="...">- scripts externes (même avec l'attribut)- Balises de script vides
Remarque : aucune source map n'est générée lorsque parseHtml est activé, car elle ne correspondrait pas correctement à la sortie HTML.
Exemple :
// input
const html = `<!DOCTYPE html>
<html>
<body>
<!-- This script will NOT be obfuscated -->
<script>
var helper = 'utility';
</script>
<!-- This script WILL be obfuscated -->
<script data-javascript-obfuscator>
var greeting = 'Hello World';
console.log(greeting);
</script>
</body>
</html>`;
JavaScriptObfuscator.obfuscate(html, {
parseHtml: true,
stringArray: true
});
// output: HTML with only the marked script obfuscated
renameGlobals
Type: boolean Default: false
⚠️ cette option peut casser votre code. Ne l'activez que si vous savez ce qu'elle fait !
Active l'obfuscation des noms de variables et de fonctions globales avec déclaration.
Lorsque cette option est désactivée et que le code d'entrée déclare des fonctions ou des classes dans la portée globale (c'est-à-dire que le code n'est pas encapsulé dans une IIFE), leurs noms sont conservés tels quels dans la sortie obfusquée — d'autres scripts peuvent y faire référence par leur nom. Sous vmObfuscation, un avertissement VMGlobalFunctionNamesNotRenamed listant ces noms est signalé, car le corps de la fonction est masqué sous forme de bytecode tandis que le nom lisible de premier niveau révèle toujours ce que fait le code (par exemple à un LLM). Pour éviter cette exposition, encapsulez le code dans une IIFE ou activez cette option.
renameProperties
Type: boolean Default: false
⚠️ cette option PEUT casser votre code. Ne l'activez que si vous savez ce qu'elle fait !
Active le renommage des noms de propriétés. Toutes les propriétés DOM intégrées ainsi que les propriétés des classes JavaScript de base sont ignorées.
Pour basculer entre les modes safe et unsafe de cette option, utilisez l'option renamePropertiesMode.
Pour définir le format des noms de propriétés renommés, utilisez l'option identifierNamesGenerator.
Pour contrôler quelles propriétés seront renommées, utilisez l'option reservedNames.
Exemple :
// input
(function () {
const foo = {
prop1: 1,
prop2: 2,
calc: function () {
return this.prop1 + this.prop2;
}
};
console.log(foo.calc());
})();
// output
(function () {
const _0x46529b = {
'_0x10cec7': 0x1,
'_0xc1c0ca': 0x2,
'_0x4b961d': function () {
return this['_0x10cec7'] + this['_0xc1c0ca'];
}
};
console['log'](_0x46529b['_0x4b961d']());
}());
renamePropertiesMode
Type: string Default: safe
⚠️ Même en mode safe, l'option renameProperties PEUT casser votre code.
Spécifie le mode de l'option renameProperties :
safe- comportement par défaut depuis la version2.11.0. Tente de renommer les propriétés de façon plus sûre afin d'éviter les erreurs d'exécution. Dans ce mode, certaines propriétés sont exclues du renommage.unsafe- comportement par défaut avant la version2.11.0. Renomme les propriétés de façon non sécurisée, sans aucune restriction.
Si un fichier utilise des propriétés d'un autre fichier, utilisez l'option identifierNamesCache pour conserver les mêmes noms de propriétés entre ces fichiers.
reservedNames
Type: string[] Default: []
Désactive l'obfuscation et la génération des identifiants correspondant aux motifs RegExp fournis.
Exemple :
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Désactive la transformation des littéraux de chaîne correspondant aux motifs RegExp fournis. Les chaînes correspondantes resteront visibles dans la sortie obfusquée.
Avec l'obfuscation VM, les chaînes réservées sont stockées dans un tableau distinct non chiffré afin de rester visibles. C'est utile pour les chaînes qui doivent rester lisibles, comme les points de terminaison d'API pour la supervision ou les identifiants de bibliothèques.
Exemple :
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Cette option définit la graine du générateur aléatoire. C'est utile pour obtenir des résultats reproductibles.
Si la graine vaut 0, le générateur aléatoire fonctionne sans graine.
selfDefending
Type: boolean Default: false
⚠️ Ne modifiez d'aucune façon le code obfusqué après l'obfuscation avec cette option, car toute modification comme une minification du code peut déclencher l'auto-défense et le code cessera de fonctionner !
⚠️ Cette option force la valeur compact à true
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmSelfDefending.
Cette option rend le code de sortie résistant à la mise en forme et au renommage des variables. Si l'on tente d'utiliser un embellisseur JavaScript sur le code obfusqué, celui-ci cessera de fonctionner, ce qui le rend plus difficile à comprendre et à modifier.
simplify
Type: boolean Default: true
Active une obfuscation supplémentaire du code par simplification.
⚠️ dans les prochaines versions, l'obfuscation des littéraux boolean (true => !![]) sera déplacée sous cette option.
Exemple :
// input
if (condition1) {
const foo = 1;
const bar = 2;
console.log(foo);
return bar;
} else if (condition2) {
console.log(1);
console.log(2);
console.log(3);
return 4;
} else {
return 5;
}
// output
if (condition1) {
const foo = 0x1, bar = 0x2;
return console['log'](foo), bar;
} else
return condition2 ? (console['log'](0x1), console['log'](0x2), console['log'](0x3), 0x4) : 0x5;
sourceMap
Type: boolean Default: false
Active la génération d'une source map pour le code obfusqué.
Les source maps peuvent vous aider à déboguer votre code source JavaScript obfusqué. Si vous souhaitez ou devez déboguer en production, vous pouvez téléverser le fichier de source map distinct vers un emplacement secret, puis y diriger votre navigateur.
sourceMapBaseUrl
Type: string Default: ``
Définit l'URL de base de l'URL d'import de la source map lorsque sourceMapMode: 'separate'.
Exemple en CLI :
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Résultat :
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Définit le nom du fichier de sortie de la source map lorsque sourceMapMode: 'separate'.
Exemple en CLI :
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Résultat :
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Spécifie le mode de génération de la source map :
inline- ajoute la source map à la fin de chaque fichier .js ;separate- génère un fichier '.map' correspondant contenant la source map. Si vous exécutez l'obfuscateur via la CLI, un lien vers le fichier de source map est ajouté à la fin du fichier de code obfusqué ://# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Permet de contrôler les champs sources et sourcesContent de la source map :
sources-content- ajoute un champsourcesfactice et un champsourcesContentcontenant le code source d'origine ;sources- ajoute un champsourcesavec une description de source valide, sans ajouter de champsourcesContent. Avec l'API NodeJS, il est nécessaire de définir l'optioninputFileName, qui sera utilisée comme valeur du champsources.
splitStrings
Type: boolean Default: false
Découpe les chaînes littérales en morceaux dont la longueur correspond à la valeur de l'option splitStringsChunkLength.
Exemple :
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Définit la longueur des morceaux de l'option splitStrings.
stringArray
Type: boolean Default: true
Retire les littéraux de chaîne et les place dans un tableau spécial. Par exemple, la chaîne "Hello World" dans var m = "Hello World"; sera remplacée par quelque chose comme var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ l'option stringArray doit être activée
Active la transformation des appels au stringArray. Tous les arguments de ces appels peuvent être extraits vers un autre objet selon la valeur de stringArrayCallsTransformThreshold.
Cela rend encore plus difficile la détection automatique des appels au tableau de chaînes.
Exemple :
function foo() {
var k = {
c: 0x2f2,
d: '0x396',
e: '0x397',
f: '0x39a',
g: '0x39d',
h: 0x398,
l: 0x394,
m: '0x39b',
n: '0x39f',
o: 0x395,
p: 0x395,
q: 0x399,
r: '0x399'
};
var c = i(k.d, k.e);
var d = i(k.f, k.g);
var e = i(k.h, k.l);
var f = i(k.m, k.n);
function i(c, d) {
return b(c - k.c, d);
}
var g = i(k.o, k.p);
var h = i(k.q, k.r);
}
function j(c, d) {
var l = { c: 0x14b };
return b(c - -l.c, d);
}
console[j(-'0xa6', -'0xa6')](foo());
function b(c, d) {
var e = a();
b = function (f, g) {
f = f - 0xa3;
var h = e[f];
return h;
};
return b(c, d);
}
function a() {
var m = [
'string5',
'string1',
'log',
'string3',
'string6',
'string2',
'string4'
];
a = function () {
return m;
};
return a();
}
stringArrayCallsTransformThreshold
Type: number Default: 0.5
⚠️ les options stringArray et stringArrayCallsTransformThreshold doivent être activées
Ce paramètre permet d'ajuster la probabilité (de 0 à 1) que les appels au tableau de chaînes soient transformés.
stringArrayEncoding
Type: string[] Default: []
⚠️ l'option stringArray doit être activée
Cette option peut ralentir votre script.
Encode tous les littéraux de chaîne du stringArray à l'aide de base64 ou rc4 et insère un code spécial servant à les décoder à l'exécution.
Chaque valeur du stringArray sera encodée selon un encodage choisi aléatoirement dans la liste fournie. Cela permet d'utiliser plusieurs encodages.
Valeurs disponibles :
'none'(boolean) : n'encode pas la valeur dustringArray'base64'(string) : encode la valeur dustringArrayavecbase64'rc4'(string) : encode la valeur dustringArrayavecrc4. Environ 30 à 50 % plus lent quebase64, mais rend plus difficile la récupération des valeurs initiales.
Par exemple, avec les valeurs d'option suivantes, certaines valeurs du stringArray ne seront pas encodées, et d'autres seront encodées avec base64 et rc4 :
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ l'option stringArray doit être activée
Permet de contrôler le type des index d'appel au tableau de chaînes.
Chaque index d'appel au stringArray sera transformé selon un type choisi aléatoirement dans la liste fournie. Cela permet d'utiliser plusieurs types.
Valeurs disponibles :
'hexadecimal-number'(default) : transforme les index d'appel au tableau de chaînes en nombres hexadécimaux'hexadecimal-numeric-string': transforme les index d'appel au tableau de chaînes en chaînes numériques hexadécimales
Avant la version 2.9.0, javascript-obfuscator transformait tous les index d'appel au tableau de chaînes avec le type hexadecimal-numeric-string. Cela rend la déobfuscation manuelle légèrement plus difficile, mais permet une détection facile de ces appels par les déobfuscateurs automatiques.
Le nouveau type hexadecimal-number vise à rendre plus difficile la détection automatique des motifs d'appel au tableau de chaînes dans le code.
D'autres types seront ajoutés à l'avenir.
stringArrayIndexShift
Type: boolean Default: true
⚠️ l'option stringArray doit être activée
Active un décalage d'index supplémentaire pour tous les appels au tableau de chaînes
stringArrayRotate
Type: boolean Default: true
⚠️ stringArray doit être activé
Décale le tableau stringArray d'un nombre de positions fixe et aléatoire (généré lors de l'obfuscation du code). Cela rend plus difficile la mise en correspondance de l'ordre des chaînes retirées avec leur emplacement d'origine.
stringArrayShuffle
Type: boolean Default: true
⚠️ stringArray doit être activé
Mélange aléatoirement les éléments du tableau stringArray.
stringArrayWrappersCount
Type: number Default: 1
⚠️ l'option stringArray doit être activée
Définit le nombre de wrappers du string array dans chaque portée racine ou de fonction.
Le nombre réel de wrappers dans chaque portée est limité par le nombre de nœuds literal présents dans cette portée.
Exemple :
// Input
const foo = 'foo';
const bar = 'bar';
function test () {
const baz = 'baz';
const bark = 'bark';
const hawk = 'hawk';
}
const eagle = 'eagle';
// Output, stringArrayWrappersCount: 5
const _0x3f6c = [
'bark',
'bar',
'foo',
'eagle',
'hawk',
'baz'
];
const _0x48f96e = _0x2e13;
const _0x4dfed8 = _0x2e13;
const _0x55e970 = _0x2e13;
function _0x2e13(_0x33c4f5, _0x3f6c62) {
_0x2e13 = function (_0x2e1388, _0x60b1e) {
_0x2e1388 = _0x2e1388 - 0xe2;
let _0x53d475 = _0x3f6c[_0x2e1388];
return _0x53d475;
};
return _0x2e13(_0x33c4f5, _0x3f6c62);
}
const foo = _0x48f96e(0xe4);
const bar = _0x4dfed8(0xe3);
function test() {
const _0x1c262f = _0x2e13;
const _0x54d7a4 = _0x2e13;
const _0x5142fe = _0x2e13;
const _0x1392b0 = _0x1c262f(0xe7);
const _0x201a58 = _0x1c262f(0xe2);
const _0xd3a7fb = _0x1c262f(0xe6);
}
const eagle = _0x48f96e(0xe5);
stringArrayWrappersChainedCalls
Type: boolean Default: true
⚠️ les options stringArray et stringArrayWrappersCount doivent être activées
Active les appels chaînés entre les wrappers du string array.
Exemple :
// Input
const foo = 'foo';
const bar = 'bar';
function test () {
const baz = 'baz';
const bark = 'bark';
function test1() {
const hawk = 'hawk';
const eagle = 'eagle';
}
}
// Output, stringArrayWrappersCount: 5, stringArrayWrappersChainedCalls: true
const _0x40c2 = [
'bar',
'bark',
'hawk',
'eagle',
'foo',
'baz'
];
const _0x31c087 = _0x3280;
const _0x31759a = _0x3280;
function _0x3280(_0x1f52ee, _0x40c2a2) {
_0x3280 = function (_0x3280a4, _0xf07b02) {
_0x3280a4 = _0x3280a4 - 0x1c4;
let _0x57a182 = _0x40c2[_0x3280a4];
return _0x57a182;
};
return _0x3280(_0x1f52ee, _0x40c2a2);
}
const foo = _0x31c087(0x1c8);
const bar = _0x31c087(0x1c4);
function test() {
const _0x848719 = _0x31759a;
const _0x2693bf = _0x31c087;
const _0x2c08e8 = _0x848719(0x1c9);
const _0x359365 = _0x2693bf(0x1c5);
function _0x175e90() {
const _0x310023 = _0x848719;
const _0x2302ef = _0x2693bf;
const _0x237437 = _0x310023(0x1c6);
const _0x56145c = _0x310023(0x1c7);
}
}
stringArrayWrappersParametersMaxCount
Type: number Default: 2
⚠️ l'option stringArray doit être activée
⚠️ Actuellement, cette option n'affecte que les wrappers ajoutés par la valeur function de l'option stringArrayWrappersType
Permet de contrôler le nombre maximal de paramètres des wrappers du tableau de chaînes.
La valeur par défaut et minimale est 2. Valeur recommandée entre 2 et 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ les options stringArray et stringArrayWrappersCount doivent être activées
Permet de sélectionner le type des wrappers ajoutés par l'option stringArrayWrappersCount.
Valeurs disponibles :
'variable': ajoute des wrappers de type variable en haut de chaque portée. Performances rapides.'function': ajoute des wrappers de type fonction à des positions aléatoires dans chaque portée. Performances plus lentes qu'avecvariable, mais offre une obfuscation plus stricte.
Il est fortement recommandé d'utiliser les wrappers function pour une obfuscation plus poussée lorsque la perte de performances n'a pas d'impact important sur l'application obfusquée.
Exemple avec la valeur 'function' :
// input
const foo = 'foo';
function test () {
const bar = 'bar';
console.log(foo, bar);
}
test();
// output
const a = [
'log',
'bar',
'foo'
];
const foo = d(0x567, 0x568);
function b(c, d) {
b = function (e, f) {
e = e - 0x185;
let g = a[e];
return g;
};
return b(c, d);
}
function test() {
const c = e(0x51c, 0x51b);
function e (c, g) {
return b(c - 0x396, g);
}
console[f(0x51b, 0x51d)](foo, c);
function f (c, g) {
return b(c - 0x396, g);
}
}
function d (c, g) {
return b(g - 0x3e1, c);
}
test();
stringArrayThreshold
Type: number Default: 0.8 Min: 0 Max: 1
⚠️ l'option stringArray doit être activée
Ce paramètre permet d'ajuster la probabilité (de 0 à 1) qu'un littéral de chaîne soit inséré dans le stringArray.
Ce paramètre est particulièrement utile pour les codes volumineux, car il génère de nombreux appels au string array et peut ralentir votre code.
stringArrayThreshold: 0 équivaut à stringArray: false.
strictMode
Type: boolean | null Default: null
Permet de spécifier la façon dont l'obfuscateur traite le code vis-à-vis du mode strict de JavaScript.
Valeurs disponibles :
null(par défaut) - détecte automatiquement le mode strict à partir du code. Si le code contient une directive'use strict'explicite, une syntaxe de module ES ou des méthodes de classe, il est traité en mode strict. Sinon, le mode non strict (sloppy) est supposé.true- force le traitement en mode strict pour tout le code, même sans directive'use strict'explicite. À utiliser lorsque votre code s'exécutera dans un contexte de mode strict (par exemple dans des modules ES, des bundlers ou des frameworks modernes).false- seuls les indicateurs de mode strict explicites ('use strict', modules ES, méthodes de classe) sont traités comme du mode strict. L'héritage de la portée parente s'applique toujours conformément à la spécification JS.
target
Type: string Default: browser
Permet de définir l'environnement cible du code obfusqué.
Valeurs disponibles :
browser(par défaut) — environnement de page web standard. Le code produit est identique à celui denode, mais certaines options propres au navigateur ne peuvent pas être utilisées avec la ciblenodebrowser-no-eval— identique àbrowser, mais la sortie n'utilise paseval(). À utiliser lorsque la page cible applique une Content Security Policy qui interditeval/unsafe-eval.node— environnement Node.js. Les options propres au navigateur sont désactivées (elles requièrentwindow/documentet seraient sans effet ou lèveraient une erreur sous Node). Certaines défensesvmSelfDefendingqui reposent sur des API exclusivement navigateur — détection de navigateur headless, restauration d'un realm propre via iframe, contrôles anti-inspecteur/DOM — ne sont pas générées pour cette cible.service-worker— contexte Service Worker. Pas dewindow, pas dedocument, un globalselfdifférent.userscript— bac à sable d'un gestionnaire de userscripts (Tampermonkey, par exemple). Les défensesvmSelfDefendingsont ajustées en conséquence.bytenode— code Node.js qui sera compilé avec le chargeur bytenode (bytecode V8 mis en cache.jsc) après l'obfuscation. L'obfuscateur lui-même n'invoque pasbytenode; il produit un JavaScript obfusqué par VM dont le runtime est structuré pour survivre à l'étape de compilation de bytenode, et les défensesvmSelfDefendingsont ajustées en conséquence. Exécutez vous-mêmebytenodesur la sortie obfusquée pour produire le fichier.jscfinal.
transformObjectKeys
Type: boolean Default: false
Active la transformation des clés d'objet.
Exemple :
// input
(function(){
var object = {
foo: 'test1',
bar: {
baz: 'test2'
}
};
})();
// output
var _0x4735 = [
'foo',
'baz',
'bar',
'test1',
'test2'
];
function _0x390c(_0x33d6b6, _0x4735f4) {
_0x390c = function (_0x390c37, _0x1eed85) {
_0x390c37 = _0x390c37 - 0x198;
var _0x2275f8 = _0x4735[_0x390c37];
return _0x2275f8;
};
return _0x390c(_0x33d6b6, _0x4735f4);
}
(function () {
var _0x17d1b7 = _0x390c;
var _0xc9b6bb = {};
_0xc9b6bb[_0x17d1b7(0x199)] = _0x17d1b7(0x19c);
var _0x3d959a = {};
_0x3d959a[_0x17d1b7(0x198)] = _0x17d1b7(0x19b);
_0x3d959a[_0x17d1b7(0x19a)] = _0xc9b6bb;
var _0x41fd86 = _0x3d959a;
}());
warnings
Type: string | object Default: all
Contrôle quels avertissements d'obfuscation non fatals sont émis via la méthode ObfuscationResult.getWarnings().
Valeurs disponibles :
'all'(par défaut) — chaque avertissement est émis.'none'— tous les avertissements sont supprimés.- un objet associant des types d'avertissement à des booléens — un type associé à
falseest supprimé ; tout type absent (ou associé àtrue) reste actif. Par exemple,{ "VMGlobalFunctionNamesNotRenamed": false }conserve tous les avertissements sauf celui-ci.
Types d'avertissement :
VMGlobalFunctionNamesNotRenamed— sousvmObfuscation, les noms des déclarations de fonctions de premier niveau, des déclarations de classes et des variables auxquelles est affectée une expression de fonction/fléchée/classe ont été conservés tels quels (l'optionrenameGlobalsest désactivée et le code n'est pas encapsulé dans une IIFE) ; ils restent donc lisibles dans la sortie même si les corps sont masqués sous forme de bytecode. Les noms exportés ne sont pas signalés.VMTopLevelInitializerNotVirtualized— des initialiseurs de variables de premier niveau sont restés en JavaScript ordinaire sous obfuscation VM parce quevmWrapTopLevelInitializersest désactivé ou n'a pas pu les virtualiser.DynamicCodeRenameRisk— le code construit une fonction à partir d'une chaîne à l'exécution (evaldirect, constructeurFunction, oufn.toString()injecté dans un<script>/Worker), ce qui peut référencer des identifiants que l'obfuscateur a renommés.VMDynamicCodeSkipped— une fonction a été exclue du bytecoding VM parce qu'elle contient unevaldirect / unnew Functiondynamique /Function(voirvmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— avecvmAsyncExecutoractivé, une fonction que vous aviez explicitement marquée en modecomments'est avérée synchrone et a été ignorée (seules les fonctions asynchrones sont virtualisées dans ce mode).VMAsyncGeneratorSkippedInAsyncMode— avecvmAsyncExecutoret un getter de clé asynchrone actif, un générateur asynchrone marqué n'a pas pu être virtualisé (il doit renvoyer son itérateur de façon synchrone).BrowserTargetWithNodeStyleCode— le code semble cibler Node.js (par exemplerequire('fs'),__dirname,process.argv) alors que l'optiontargetest réglée sur un environnement de type navigateur.
vmObfuscation
Type: boolean Default: false
Active l'obfuscation en bytecode basée sur une VM. Lorsqu'elle est activée, les fonctions JavaScript sont compilées en bytecode sur mesure qui s'exécute sur une machine virtuelle embarquée. Cela offre le plus haut niveau de protection, car la logique du code d'origine est entièrement transformée.
Exemple :
Un code lisible comme return qty * price devient une liste de nombres comme [0x15,0x03,0x17,...] que seul l'interpréteur VM embarqué peut exécuter. La logique d'origine n'est plus visible sous forme de JavaScript.
vmTargetFunctions
Type: string[] Default: []
Indique précisément, par leur nom, quelles fonctions de premier niveau doivent bénéficier de la protection VM.
Exemple :
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Résultat : seules ces trois fonctions sont protégées par VM. Tout le reste demeure du JavaScript ordinaire (mais toujours obfusqué). Idéal pour protéger des vérifications de licence sensibles ou une logique d'authentification tout en gardant le reste de votre code léger.
vmExcludeFunctions
Type: string[] Default: []
Indique les fonctions de premier niveau qui ne doivent jamais bénéficier de la protection VM. Cette option a priorité sur les autres réglages.
Exemple :
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Quand l'utiliser : les fonctions de premier niveau critiques pour les performances (boucles d'animation, traitement de données en temps réel) peuvent être exclues afin d'éviter la surcharge de la VM tout en protégeant tout le reste.
vmTargetFunctionsMode
Type: string Default: root
Contrôle la façon dont les fonctions/méthodes sont sélectionnées pour l'obfuscation VM.
Exemple - mode Comment :
// Source code
function regularFunction() {
return 'not virtualized';
}
/* javascript-obfuscator:vm */
function sensitiveFunction() {
return 'this will be VM-protected';
}
function outer() {
/* javascript-obfuscator:vm */
function nestedSensitive() {
return 'nested but still VM-protected';
}
return nestedSensitive();
}
// Obfuscator options
{
vmObfuscation: true,
vmTargetFunctionsMode: 'comment'
}
Quand l'utiliser : lorsque vous avez besoin d'un contrôle chirurgical sur les fonctions qui bénéficient de la protection VM, en particulier des fonctions imbriquées contenant une logique sensible. Contrairement à vmTargetFunctions, qui ne fonctionne qu'avec des fonctions nommées de premier niveau, le mode comment vous permet de protéger n'importe quelle fonction, où qu'elle se trouve dans votre code.
vmForceCompileDynamicCode
Type: boolean Default: false
Contrôle ce que l'obfuscation VM fait d'une fonction contenant un appel direct à eval, new Function(...) ou Function(...).
Par défaut, une telle fonction (ainsi que toutes les fonctions qui y sont définies) est exclue du bytecoding VM et un avertissement VMDynamicCodeSkipped est signalé via result.getWarnings(). En effet, le source construit à l'exécution peut référencer des identifiants de la chaîne de portées environnante — des identifiants que l'obfuscateur a renommés.
Lorsqu'elle vaut true, la fonction est tout de même convertie en bytecode et l'avertissement VMDynamicCodeSkipped n'est plus émis.
L'avertissement distinct DynamicCodeRenameRisk continue de se déclencher quelle que soit cette option, car le risque de renommage qu'il décrit est indépendant de l'exclusion VM — activer cette option ne rend pas le motif sous-jacent plus sûr pour autant.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
Avec l'option désactivée (par défaut), loadConfig reste en JavaScript ordinaire. Avec l'option activée, loadConfig est compilée en bytecode VM comme n'importe quelle autre fonction. Utilisez-la lorsque vous avez audité le site d'appel et que vous savez que le code construit à l'exécution ne dépend pas d'identifiants renommés par une closure.
vmWrapTopLevelInitializers
Type: boolean Default: false
Encapsule certains initialiseurs de variables de premier niveau dans des IIFE (expressions de fonction immédiatement invoquées) afin qu'ils puissent être obfusqués par VM.
Ce qu'elle fait : Sans cette option, les constantes et variables de premier niveau restent visibles dans la sortie :
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
Avec cette option activée, l'initialiseur est encapsulé dans une IIFE qui est obfusquée par VM :
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Remarque : cette option ne fonctionne que lorsque vmTargetFunctionsMode vaut 'root' (la valeur par défaut).
Avertissements : chaque fois qu'un initialiseur de premier niveau se retrouve en JavaScript ordinaire sous obfuscation VM, un avertissement VMTopLevelInitializerNotVirtualized listant les noms des variables concernées est signalé. Cela couvre : cette option désactivée, les initialiseurs que cette option a dû ignorer (chacun accompagné de sa raison — par exemple l'initialiseur référence un déclarateur voisin ou contient un await de premier niveau), et le mode vmAsyncExecutor où les wrappers synchrones ne peuvent pas du tout être virtualisés.
vmDynamicOpcodes
Type: boolean Default: false
Rend l'interpréteur VM plus petit et unique à chaque build.
Ce qu'elle fait :
- Filtre les instructions inutilisées - Si votre code n'utilise pas de classes, les instructions liées aux classes sont entièrement supprimées
- Rend la structure aléatoire - L'ordre des gestionnaires d'instructions est mélangé à chaque build
En conséquence, la sortie est plus petite et chaque build a une apparence différente.
vmBytecodeEncoding
Type: boolean Default: false
Encode chaque instruction du bytecode. Les instructions sont décodées une par une pendant l'exécution.
vmBytecodeArrayEncoding
Type: boolean Default: false
Encode l'intégralité du tableau de bytecode en un seul bloc. Le tableau est décodé une seule fois au démarrage, avant le début de l'exécution. À utiliser conjointement avec vmBytecodeEncoding pour obtenir deux couches de protection.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Clé de chiffrement personnalisée pour l'encodage du tableau de bytecode. Lorsqu'elle est définie, cette clé est utilisée à la place de la clé par défaut dérivée de l'environnement. La clé doit être fournie à l'exécution via vmBytecodeArrayEncodingKeyGetter.
Cette option externalise la clé de chiffrement : elle n'est pas intégrée au code obfusqué lui-même. Bien que la clé reste accessible à l'exécution (et ne soit donc pas véritablement secrète), cette séparation empêche les outils d'analyse statique de retrouver la clé en examinant le seul code.
Important : la clé doit être disponible de façon synchrone au chargement du code obfusqué. Utilisez un stockage synchrone comme les cookies, localStorage, sessionStorage, des variables globales ou des éléments du DOM (par exemple des balises meta injectées par le serveur). Les méthodes asynchrones comme fetch() ne peuvent pas être utilisées directement dans l'expression du getter de clé.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Expression JavaScript synchrone qui renvoie la clé de chiffrement à l'exécution. Cette expression est évaluée au chargement du code obfusqué et doit renvoyer la même clé que celle fournie dans vmBytecodeArrayEncodingKey. Pour résoudre la clé de façon asynchrone (une Promise), activez vmAsyncExecutor.
Remarque : un getter renvoyant une Promise nécessite vmAsyncExecutor. Cela ne peut pas être vérifié au moment du build ; un getter renvoyant une Promise avec vmAsyncExecutor désactivé échoue donc à l'exécution — le décodeur reçoit la Promise au lieu de la clé.
Le code obfusqué ne fonctionne que si le getter de clé renvoie exactement la même clé que celle utilisée lors de l'obfuscation. Si les clés ne correspondent pas, le déchiffrement échoue et le code produit des résultats erronés ou des erreurs. Si le getter de clé renvoie undefined, null ou une chaîne vide, le code lève une erreur : "VM decryption key not available".
Important : ne conservez pas la clé dans le même fichier/script que le code obfusqué — l'y intégrer permet à un simple examen statique du bundle de la retrouver. Stockez-la plutôt dans une source distincte : cookies définis par le serveur, localStorage renseigné par un autre script, balise meta HTML injectée par le serveur, variable globale définie par un autre script, ou (avec vmAsyncExecutor) récupérée depuis votre backend à l'exécution.
Lorsque la clé est récupérée depuis votre backend (via vmAsyncExecutor), ajoutez des contrôles fondés sur la session ou l'origine sur ce point de terminaison : renvoyez la bonne clé aux utilisateurs réels (session valide, Origin/Referer attendus) et une clé factice aux requêtes suspectes (par exemple une origine localhost/inattendue, absence de session). Les utilisateurs réels s'exécutent normalement ; une copie exécutée en dehors de votre environnement obtient une clé qui ne déchiffre rien. La logique exacte dépend de votre site.
Exemples :
// From cookie
vmBytecodeArrayEncodingKeyGetter: "document.cookie.match(/vmKey=([^;]+)/)?.[1]"
// From localStorage
vmBytecodeArrayEncodingKeyGetter: "localStorage.getItem('vmKey')"
// From global variable
vmBytecodeArrayEncodingKeyGetter: "window.__VM_KEY__"
// From meta tag (server-injected)
vmBytecodeArrayEncodingKeyGetter: "document.querySelector('meta[name=\"vm-key\"]').content"
// From nested object
vmBytecodeArrayEncodingKeyGetter: "window.config.encryption.key"
// From backend, async (requires vmAsyncExecutor)
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
Exemple d'utilisation :
// Build time
JavaScriptObfuscator.obfuscate(code, {
vmObfuscation: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: 'mySecretKey123',
vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'
});
// Runtime - key must be set before obfuscated code runs
window.__VM_KEY__ = 'mySecretKey123';
vmAsyncExecutor
Type: boolean Default: false
Active l'exécuteur VM asynchrone, qui permet à vmBytecodeArrayEncodingKeyGetter de renvoyer une Promise (un getter de clé asynchrone) — la clé de déchiffrement peut ainsi être récupérée à l'exécution (requête réseau, IndexedDB, etc.) au lieu de devoir être disponible de façon synchrone au chargement du code.
Fortement recommandé pour les bases de code entièrement asynchrones. Dans ce mode, seules les fonctions async sont virtualisées — une fonction synchrone ne peut pas être rendue asynchrone sans transformer sa valeur de retour en Promise et casser ses appelants — de sorte qu'un code async de bout en bout obtient la meilleure couverture. Cela fonctionne tout de même lorsque la racine est synchrone (par exemple une IIFE synchrone / un wrapper UMD) : les fonctions async les plus externes qu'elle contient sont protégées, et les parties synchrones sont laissées telles quelles.
Ce qui est transformé : chaque fonction async la plus externe, où qu'elle apparaisse (y compris imbriquée dans des wrappers synchrones). L'async la plus externe de chaque chaîne est l'unité protégée — tout ce qu'elle contient, synchrone comme asynchrone, y est compilé. Les fonctions synchrones et les générateurs simples restent non obfusqués.
function foo() { // sync — left as-is
function bar() {} // sync — left as-is
async function baz() { // transformed
// any code here, including calls to other async or sync functions
}
async function bark() { // transformed
// any code here, including calls to other async or sync functions
}
}
Exclusions et avertissements. Les générateurs asynchrones restent eux aussi non obfusqués lorsqu'un getter de clé asynchrone est actif (un générateur asynchrone doit renvoyer son itérateur de façon synchrone et ne peut pas attendre la clé). Dans le mode par défaut vmTargetFunctionsMode: 'root', les exclusions sont silencieuses (la sélection est automatique) ; en mode comment, un avertissement est émis via ObfuscationResult.getWarnings() chaque fois qu'une fonction que vous avez explicitement marquée ne peut pas être virtualisée — elle s'est avérée synchrone, ou il s'agit d'un générateur asynchrone sous un getter de clé asynchrone.
Le getter de clé asynchrone nécessite en outre vmBytecodeArrayEncoding avec un vmBytecodeArrayEncodingKeyGetter.
Exemple d'utilisation :
JavaScriptObfuscator.obfuscate(code, {
vmObfuscation: true,
vmAsyncExecutor: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: 'mySecretKey123',
// the key getter may now return a Promise
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
});
vmJumpsEncoding
Type: boolean Default: false
Encode les cibles de saut dans le bytecode. Les décalages de saut sont calculés à l'exécution, masquant la structure du flux de contrôle (if/else, boucles, etc.) à l'analyse statique.
vmMacroOps
Type: boolean Default: false
Combine des séquences d'instructions courantes en opcodes « macro » uniques. Par exemple, LOAD + ADD + STORE peut devenir une seule instruction MACRO_ADD_TO_VAR. Cela déjoue la reconnaissance de motifs et peut améliorer les performances.
vmDebugProtection
Type: boolean Default: false
Ajoute au runtime de la VM des défenses multicouches anti-débogage, anti-analyse et anti-LLM. Fonctionne au mieux avec les cibles browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Ajoute au runtime de la VM une protection multicouche de détection des altérations, anti-hooking et anti-rétro-ingénierie.
⚠️ Cette option active de force vmBytecodeArrayEncoding.
⚠️ Détection d'environnements sensibles. Cette option lie le code obfusqué à son environnement d'exécution cible et utilise un fingerprinting avancé du navigateur pour détecter les outils d'automatisation. Un code protégé par cette option se cassera intentionnellement lorsqu'il sera exécuté dans :
- Des navigateurs headless (Chrome/Chromium headless, PhantomJS)
- Des outils d'automatisation de navigateur (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (lorsque
targetvautbrowser) - jsdom ou d'autres émulations du DOM côté serveur
- Des environnements où des fonctions natives du navigateur ont été hookées ou remplacées
Le code fonctionnera correctement dans les navigateurs classiques (Chrome, Firefox, Safari, Edge), y compris lorsqu'il est chargé dans des iframes, des extensions de navigateur (content scripts) et des Web Workers. Si vous devez exécuter des tests automatisés sur du code protégé, désactivez vmSelfDefending pour les builds de test — cette option est conçue pour empêcher l'analyse automatisée et ne peut pas être utilisée en toute sécurité avec un quelconque framework d'automatisation.
Il est fortement recommandé de l'utiliser conjointement avec vmDebugProtection, vmBytecodeArrayEncodingKey et vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook prend un objet à deux clés : name (obligatoire) et aliases (facultatif).
name est une fonction globale définie par votre page hôte qu'une défense de la VM (vmDebugProtection / vmSelfDefending) appelle avec un objet signal lorsqu'elle détecte un signal hostile — un débogueur ou un inspecteur, un navigateur headless / d'automatisation, un processus d'agent de codage IA, un domaine non autorisé, etc. Utilisez-la pour remonter l'événement vers votre backend (par exemple via navigator.sendBeacon). Le hook est un simple puits de télémétrie : sa valeur de retour est ignorée, et un hook absent ou qui lève une exception est un no-op silencieux qui ne peut jamais désactiver une défense. Pour changer ce que fait une défense lors d'une détection, utilisez vmDefenseReaction.
aliases renomme facultativement les champs de cet objet signal — abordé plus bas dans Renommer les champs du signal.
L'objet signal. Le hook reçoit un unique signal :
source— le détecteur précis qui s'est déclenché (voir le tableau).category— le groupe sous lequel il remonte :automation(navigateurs non humains),debugger(un débogueur/inspecteur est actif),sandbox(hôte instrumenté/factice),domain(violation du verrouillage par domaine),tamper(fonctions intégrées modifiées à l'exécution) ouintegrity(le code propre de la VM a été altéré).score/threshold— l'intensité du déclenchement du détecteur et la valeur qu'il devait atteindre ; le hook ne se déclenche qu'une foisscore >= threshold. La plupart des contrôles sont tout ou rien (un unique signal décisif) ;headlessadditionne plusieurs signaux liés à la forme du navigateur, si bien que sonscoreest généralement supérieur à sonthreshold.
Enregistrement du hook. Définissez-le comme une simple globale avant le chargement du bundle obfusqué — le runtime de la VM et ses défenses s'exécutent avant votre programme (protégé), de sorte que de nombreuses détections se produisent au démarrage :
// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }
Un hook défini à l'intérieur du source obfusqué est enregistré trop tard pour intercepter les détections du démarrage et, s'il est compilé par la VM, il reste inaccessible tant que votre programme n'a pas démarré. Il reste sans danger dans tous les cas (un hook absent est un no-op, et un garde-fou anti-réentrance empêche tout emballement), mais pour une couverture complète, enregistrez-le en amont. Pour tout de même protéger votre logique de remontée, gardez comme hook enregistré un tampon d'une ligne ((window.__vmDet = window.__vmDet || []).push(signal)) et lisez/envoyez ce tampon depuis votre code obfusqué.
Renommer les champs du signal (aliases). Les valeurs source/category par défaut sont des noms descriptifs : quiconque instrumente le callback (ou lit la sortie) peut donc reconnaître la protection et le détecteur qui s'est déclenché. aliases remplace les noms des champs du signal par des jetons opaques de votre choix, appliqués à l'intérieur de la VM avant l'émission du signal, de sorte que ces noms n'apparaissent jamais dans la sortie ni ne parviennent au callback. Votre application connaît sa propre correspondance et transmet les jetons à votre backend.
Les alias se définissent champ par champ, en séparant le renommage des clés de celui des valeurs : chaque champ accepte une key (le nom de propriété que reçoit le callback) ; les champs de type chaîne source et category acceptent en plus une table values, tandis que score / threshold sont des nombres et n'acceptent qu'une key. Les noms que vous pouvez mapper (tout autre est rejeté au moment du build) :
- clés de champ —
source,category,score,threshold - valeurs de
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - valeurs de
category—automation,debugger,sandbox,domain,tamper,integrity
vmDefenseHook: {
name: '__vmDetection',
aliases: {
source: { key: 'a8Qm', values: { headless: 'xP4m9Q' } },
category: { key: 'p3Tx', values: { automation: 'bQ7s1M' } },
score: { key: 's1' },
threshold: { key: 't1' }
}
// the callback now receives e.g. { a8Qm: 'xP4m9Q', p3Tx: 'bQ7s1M', s1: <score>, t1: <threshold> }
}
Il s'agit d'une gêne à l'identification, pas d'un secret — la correspondance peut toujours être déduite par tâtonnements répétés — de sorte que son seul bénéfice est de ne pas exposer des noms stables et explicites. Les entrées non renseignées conservent leur nom par défaut.
Une chaîne simple (vmDefenseHook: '__vmDetection') est acceptée comme raccourci de { name: '__vmDetection' } mais est dépréciée — préférez la forme objet.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Configure la façon dont chaque catégorie de détection réagit. Elle n'active rien — les défenses elles-mêmes sont activées par vmSelfDefending, vmDebugProtection et vmDomainLock ; cette option ne fait que choisir comment réagit une défense déjà activée. La catégorie est l'unité de contrôle — chaque détecteur d'une catégorie applique la réaction de cette catégorie.
Chaque catégorie regroupe les détecteurs qui surveillent un même type de condition hostile. Une catégorie ne réagit que lorsque l'option qui émet ses détecteurs est activée :
Chaque catégorie correspond à une ou plusieurs des options vmSelfDefending, vmDebugProtection et vmDomainLock ; il n'existe aucune catégorie en dehors de ces trois options, et une réaction définie pour une catégorie dont l'option est désactivée n'a tout simplement aucun effet.
Les clés sont ces six noms de catégories, ou default (valeur de repli pour les catégories non spécifiées). Les valeurs sont :
break— rompre immédiatementdecoy— continuer à s'exécuter sur un état empoisonné, en produisant silencieusement des résultats erronésnone— ne rien faire localement (télémétrie uniquement)
Les valeurs par défaut par catégorie sont indiquées ci-dessus ; une catégorie que vous ne définissez pas (ou que vous laissez à sa valeur par défaut) utilise cette valeur par défaut. default atteint toutes les catégories, y compris celles qui sont correctes par construction (integrity, tamper) ; { default: 'none' } produit donc un build véritablement non intrusif, purement télémétrique :
vmDefenseReaction: { default: 'none' } // never break — pair with vmDefenseHook
vmDefenseReaction: { automation: 'none', domain: 'break' } // tolerate automation FPs, still break on a bad domain
vmStatefulOpcodes
Type: boolean Default: false
Fait dépendre la signification des opcodes de leur position dans le bytecode. Chaque position possède une correspondance opcode-vers-gestionnaire différente, dérivée d'une graine, de sorte qu'un même numéro d'opcode effectue des opérations différentes selon la position.
vmCallContextOpcodes
Type: boolean Default: false
Fait dépendre une fonction protégée de l'endroit d'où elle est appelée, de sorte qu'elle ne peut pas être extraite du code puis exécutée ou analysée isolément — elle ne se comporte correctement que lorsqu'elle est invoquée via ses véritables sites d'appel dans le programme. Cette option affecte les performances à l'exécution.
Actuellement, seules les constructions suivantes sont prises en charge :
- les déclarations de fonction (
function f() {}) ; - les expressions de fonction et les fonctions fléchées affectées à une variable (
const f = () => {}) ; - les méthodes privées d'instance (
this.#m()).
Dans tous les cas, la fonction doit toujours être atteinte par un appel direct (f(), this.#m()). Si elle est stockée dans une autre variable, passée en argument ou utilisée d'une autre manière comme valeur, elle reste non protégée. Les fonctions asynchrones sont prises en charge ; les générateurs ne le sont pas.
Cette option est expérimentale et peut casser votre code ; testez donc soigneusement la sortie avant de l'utiliser.
vmStackEncoding
Type: boolean Default: false
Chiffre les valeurs présentes sur la pile de la VM pendant l'exécution. Les valeurs sont encodées lorsqu'elles sont empilées et décodées lorsqu'elles sont dépilées, de sorte qu'une inspection de la mémoire montre des données chiffrées au lieu des valeurs réelles.
Cette option affecte fortement les performances.
vmCompactDispatcher
Type: boolean Default: false
Utilise un seul exécuteur VM au lieu de deux exécuteurs (synchrone + générateur). Réduit la taille du code obfusqué mais ajoute une surcharge d'environ 20 % sur un code fortement récursif.
false(par défaut) : deux exécuteurs — performances optimales, sortie plus volumineusetrue: un seul exécuteur — sortie plus petite, légèrement plus lente
vmStringArrayBytecodeOnly
Type: boolean Default: false
Lorsqu'elle est activée, le tableau de chaînes n'extrait que les chaînes issues des données de bytecode — aucune autre chaîne du code n'est transformée. Cela active de force stringArray même s'il n'est pas explicitement défini.
Pourquoi l'utiliser : extraire toutes les chaînes du runtime de la VM vers un tableau de chaînes est lent. Cette option ne cible que le contenu du bytecode pour l'extraction dans le tableau de chaînes, améliorant les performances tout en protégeant les constantes du bytecode.
- Lorsque
vmBytecodeArrayEncoding: false— les chaînes présentes dans les pools de constantes du bytecode (tableauxc) sont extraites - Lorsque
vmBytecodeArrayEncoding: true— les chaînes de bytecode encodées en base64 au niveau supérieur sont extraites stringArrayThresholdcontinue de contrôler le pourcentage de ces chaînes de bytecode qui sont extraites
vmDomainLock
Type: string[] Default: []
⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'
Restreint le code obfusqué à des domaines et/ou sous-domaines précis, et est bien plus difficile à localiser et à retirer que domainLock.
Si le code source n'est pas exécuté sur les domaines spécifiés par cette option, le navigateur est redirigé vers l'URL passée à vmDomainLockRedirectUrl, et les appels protégés ultérieurs renverront des résultats incorrects même si la redirection est supprimée.
Domaines et sous-domaines multiples
Il est possible de verrouiller votre code sur plusieurs domaines ou sous-domaines. Par exemple, pour le verrouiller de sorte qu'il ne s'exécute que sur www.example.com, ajoutez www.example.com. Pour qu'il fonctionne sur le domaine racine ainsi que sur tous ses sous-domaines (example.com, sub.example.com), utilisez .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'
Permet de rediriger le navigateur vers une URL fournie si le code source n'est pas exécuté sur les domaines spécifiés par vmDomainLock.
Options de préréglage
Obfuscation élevée, performances faibles
Les performances seront bien plus lentes que sans obfuscation
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
deadCodeInjection: true,
deadCodeInjectionThreshold: 1,
debugProtection: true,
debugProtectionInterval: 4000,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 5,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayEncoding: ['rc4'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersType: 'function',
stringArrayThreshold: 1,
transformObjectKeys: true
}
Obfuscation moyenne, performances optimales
Les performances seront plus lentes que sans obfuscation
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.75,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 10,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 0.75,
stringArrayEncoding: ['base64'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 2,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 4,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.75,
transformObjectKeys: true
}
Obfuscation faible, performances élevées
Les performances resteront à un niveau relativement normal
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: false,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: false,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75
}
Préréglage par défaut, performances élevées
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: false,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
selfDefending: false,
simplify: true,
splitStrings: false,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: false,
stringArrayCallsTransformThreshold: 0.5,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75
}
Obfuscation VM Ultra High (sécurité maximale)
Ce préréglage active l'obfuscation en bytecode basée sur une VM avec toutes les fonctionnalités de durcissement, y compris la répartition indirecte. Offre la protection la plus forte, mais avec une taille de sortie plus importante et une exécution bien plus lente.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: true,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: true,
vmCallContextOpcodes: false,
vmStackEncoding: true,
vmCompactDispatcher: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.5,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.5,
debugProtection: true,
debugProtectionInterval: 4000,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 5,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayEncoding: ['rc4'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.5,
transformObjectKeys: true
}
VM Anti-LLM (protection contre les agents IA)
Ce préréglage est spécifiquement conçu pour empêcher les agents IA et les LLM de rétro-concevoir du code en bytecode VM. Basé sur vm-default, avec l'auto-défense et la protection anti-débogage activées. Plus léger que vm-high-obfuscation, mais spécifiquement durci contre l'analyse automatisée.
{
optionsPreset: 'vm-anti-llm'
}
Inclut :
- l'obfuscation en bytecode VM avec tableau de chaînes (depuis
vm-default) vmSelfDefending— détection anti-hook, hash d'intégrité, empreinte de source, vérification d'un realm propre via iframe, dérivation de clé par chiffrement ARXvmDebugProtection— contrôles anti-débogage dans la boucle de répartition de la VMdebugProtection: false— pas de protection anti-débogage héritée (la protection anti-débogage de la VM est supérieure)
Obfuscation VM High (sécurité la plus élevée)
Ce préréglage active l'obfuscation en bytecode basée sur une VM avec la plupart des fonctionnalités de durcissement. Offre une protection forte avec de meilleures performances que le préréglage ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: true,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: true,
vmCallContextOpcodes: false,
vmStackEncoding: true,
vmCompactDispatcher: false
}
Obfuscation VM Medium (sécurité équilibrée)
Ce préréglage active l'obfuscation en bytecode basée sur une VM avec un ensemble équilibré de fonctionnalités de durcissement. Bon compromis entre sécurité et performances.
{
optionsPreset: 'vm-medium-obfuscation'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: false,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false
}
Obfuscation VM Low (sécurité de base, meilleures performances)
Ce préréglage active une obfuscation en bytecode VM de base, sans fonctionnalités de durcissement supplémentaires. Bon équilibre entre sécurité et taille de sortie.
{
optionsPreset: 'vm-low-obfuscation'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: false,
vmBytecodeEncoding: false,
vmBytecodeArrayEncoding: false,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: false,
vmMacroOps: false,
vmDebugProtection: false,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false
}
VM Default (VM + protection du tableau de chaînes)
Ce préréglage combine une obfuscation en bytecode VM de base avec la protection par tableau de chaînes. Bon point de départ pour l'obfuscation VM avec protection des chaînes.
{
optionsPreset: 'vm-default'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: false,
vmBytecodeArrayEncoding: true,
vmStringArrayBytecodeOnly: true,
vmAsyncExecutor: false,
vmJumpsEncoding: false,
vmMacroOps: false,
vmDebugProtection: false,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false,
stringArray: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayThreshold: 1,
stringArrayIndexShift: true,
stringArrayIndexesType: ['hexadecimal-number'],
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 1,
stringArrayWrappersCount: 3,
stringArrayWrappersType: 'function',
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayEncoding: ['base64'],
splitStrings: true,
splitStringsChunkLength: 6
}
compact
Type: boolean Default: true
Sortie de code compacte sur une seule ligne.
config
Type: string Default: ``
Nom du fichier de configuration JS/JSON contenant les options de l'obfuscateur. Ces options seront remplacées par celles passées directement en ligne de commande (CLI).
controlFlowFlattening
Type: boolean Default: false
⚠️ Cette option affecte fortement les performances, jusqu'à une exécution 1,5x plus lente. Utilisez controlFlowFlatteningThreshold pour définir le pourcentage de nœuds concernés par l'aplatissement du flux de contrôle.
Active l'aplatissement du flux de contrôle du code. L'aplatissement du flux de contrôle est une transformation de la structure du code source qui en complique la compréhension.
Exemple :
// input
(function(){
function foo () {
return function () {
var sum = 1 + 2;
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
console.log(6);
}
}
foo()();
})();
// output
(function () {
function _0x3bfc5c() {
return function () {
var _0x3260a5 = {
'WtABe': '4|0|6|5|3|2|1',
'GokKo': function _0xf87260(_0x427a8e, _0x43354c) {
return _0x427a8e + _0x43354c;
}
};
var _0x1ad4d6 = _0x3260a5['WtABe']['split']('|'), _0x1a7b12 = 0x0;
while (!![]) {
switch (_0x1ad4d6[_0x1a7b12++]) {
case '0':
console['log'](0x1);
continue;
case '1':
console['log'](0x6);
continue;
case '2':
console['log'](0x5);
continue;
case '3':
console['log'](0x4);
continue;
case '4':
var _0x1f2f2f = _0x3260a5['GokKo'](0x1, 0x2);
continue;
case '5':
console['log'](0x3);
continue;
case '6':
console['log'](0x2);
continue;
}
break;
}
};
}
_0x3bfc5c()();
}());
controlFlowFlatteningThreshold
Type: number Default: 0.75 Min: 0 Max: 1
Probabilité que la transformation controlFlowFlattening soit appliquée à un nœud donné.
Ce paramètre est particulièrement utile pour les codes volumineux, car un grand nombre de transformations du flux de contrôle peut ralentir votre code et en augmenter la taille.
controlFlowFlatteningThreshold: 0 équivaut à controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Augmente considérablement la taille du code obfusqué (jusqu'à 200 %) ; à n'utiliser que si la taille du code obfusqué n'a pas d'importance. Utilisez deadCodeInjectionThreshold pour définir le pourcentage de nœuds concernés par l'injection de code mort.
⚠️ Cette option active de force l'option stringArray.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé.
Avec cette option, des blocs aléatoires de code mort sont ajoutés au code obfusqué.
Exemple :
// input
(function(){
if (true) {
var foo = function () {
console.log('abc');
};
var bar = function () {
console.log('def');
};
var baz = function () {
console.log('ghi');
};
var bark = function () {
console.log('jkl');
};
var hawk = function () {
console.log('mno');
};
foo();
bar();
baz();
bark();
hawk();
}
})();
// output
var _0x37b8 = [
'YBCtz',
'GlrkA',
'urPbb',
'abc',
'NMIhC',
'yZgAj',
'zrAId',
'EtyJA',
'log',
'mno',
'jkl',
'def',
'Quzya',
'IWbBa',
'ghi'
];
function _0x43a7(_0x12cf56, _0x587376) {
_0x43a7 = function (_0x2f87a8, _0x47eac2) {
_0x2f87a8 = _0x2f87a8 - (0x16a7 * 0x1 + 0x5 * 0x151 + -0x1c92);
var _0x341e03 = _0x37b8[_0x2f87a8];
return _0x341e03;
};
return _0x43a7(_0x12cf56, _0x587376);
}
(function () {
if (!![]) {
var _0xbbe28f = function () {
var _0x2fc85f = _0x43a7;
if (_0x2fc85f(0xaf) === _0x2fc85f(0xae)) {
_0x1dd94f[_0x2fc85f(0xb2)](_0x2fc85f(0xb5));
} else {
console[_0x2fc85f(0xb2)](_0x2fc85f(0xad));
}
};
var _0x5e46bc = function () {
var _0x15b472 = _0x43a7;
if (_0x15b472(0xb6) !== _0x15b472(0xaa)) {
console[_0x15b472(0xb2)](_0x15b472(0xb5));
} else {
_0x47eac2[_0x15b472(0xb2)](_0x15b472(0xad));
}
};
var _0x3669e8 = function () {
var _0x47a442 = _0x43a7;
if (_0x47a442(0xb7) !== _0x47a442(0xb0)) {
console[_0x47a442(0xb2)](_0x47a442(0xb8));
} else {
_0x24e0bf[_0x47a442(0xb2)](_0x47a442(0xb3));
}
};
var _0x28b05a = function () {
var _0x497902 = _0x43a7;
if (_0x497902(0xb1) === _0x497902(0xb1)) {
console[_0x497902(0xb2)](_0x497902(0xb4));
} else {
_0x59c9c6[_0x497902(0xb2)](_0x497902(0xb4));
}
};
var _0x402a54 = function () {
var _0x1906b7 = _0x43a7;
if (_0x1906b7(0xab) === _0x1906b7(0xac)) {
_0xb89cd0[_0x1906b7(0xb2)](_0x1906b7(0xb8));
} else {
console[_0x1906b7(0xb2)](_0x1906b7(0xb3));
}
};
_0xbbe28f();
_0x5e46bc();
_0x3669e8();
_0x28b05a();
_0x402a54();
}
}());
deadCodeInjectionThreshold
Type: number Default: 0.4 Min: 0 Max: 1
Permet de définir le pourcentage de nœuds concernés par deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Peut figer votre navigateur si vous ouvrez les outils de développement.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmDebugProtection.
Cette option rend presque impossible l'utilisation de la fonction debugger des outils de développement (aussi bien sur les navigateurs basés sur WebKit que sur Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Peut figer votre navigateur ! À utiliser à vos risques et périls.
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmDebugProtection.
Si cette option est définie, un intervalle en millisecondes est utilisé pour forcer le mode débogage sur l'onglet Console, rendant plus difficile l'utilisation des autres fonctionnalités des outils de développement. Fonctionne si debugProtection est activé. La valeur recommandée est comprise entre 2000 et 4000 millisecondes.
disableConsoleOutput
Type: boolean Default: false
⚠️ Cette option désactive les appels à console de façon globale pour tous les scripts
Désactive l'utilisation de console.log, console.info, console.error, console.warn, console.debug, console.exception et console.trace en les remplaçant par des fonctions vides. Cela rend l'utilisation du débogueur plus difficile.
domainLock
Type: string[] Default: []
⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'
Permet d'exécuter le code source obfusqué uniquement sur des domaines et/ou sous-domaines précis. Cela rend très difficile le simple copier-coller de votre code source pour l'exécuter ailleurs.
Si le code source n'est pas exécuté sur les domaines spécifiés par cette option, le navigateur est redirigé vers l'URL passée à l'option domainLockRedirectUrl.
Domaines et sous-domaines multiples
Il est possible de verrouiller votre code sur plusieurs domaines ou sous-domaines. Par exemple, pour le verrouiller de sorte qu'il ne s'exécute que sur www.example.com, ajoutez www.example.com. Pour qu'il fonctionne sur le domaine racine ainsi que sur tous ses sous-domaines (example.com, sub.example.com), utilisez .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'
Permet de rediriger le navigateur vers une URL fournie si le code source n'est pas exécuté sur les domaines spécifiés par domainLock
exclude
Type: string[] Default: []
Noms de fichiers ou motifs glob indiquant les fichiers à exclure de l'obfuscation.
forceTransformStrings
Type: string[] Default: []
Force la transformation des littéraux de chaîne correspondant aux motifs RegExp fournis.
⚠️ Cette option n'affecte que les chaînes qui ne devraient pas être transformées par stringArrayThreshold (ou d'éventuels autres seuils à l'avenir)
Cette option a priorité sur l'option reservedStrings, mais pas sur les conditional comments.
Exemple :
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
L'objectif principal de cette option est de pouvoir réutiliser les mêmes noms d'identifiants lors de l'obfuscation de plusieurs sources/fichiers.
Actuellement, deux types d'identifiants sont pris en charge :
- Identifiants globaux :
- Tous les identifiants globaux sont écrits dans le cache ;
- Tous les identifiants globaux non déclarés correspondants sont remplacés par les valeurs du cache.
- Identifiants de propriété, uniquement lorsque l'option
renamePropertiesest activée :- Tous les identifiants de propriété sont écrits dans le cache ;
- Tous les identifiants de propriété correspondants sont remplacés par les valeurs du cache.
API Node.js
Si la valeur null est passée, le cache est entièrement désactivé.
Si un objet vide ({}) est passé, l'écriture des noms d'identifiants dans l'objet-cache (type TIdentifierNamesCache) est activée. Cet objet-cache est accessible via l'appel de la méthode getIdentifierNamesCache de l'objet ObfuscationResult.
L'objet-cache obtenu peut ensuite être utilisé comme valeur de l'option identifierNamesGenerator afin de réutiliser ces noms lors de l'obfuscation de tous les identifiants correspondants des sources suivantes.
Exemple :
const source1ObfuscationResult = JavaScriptObfuscator.obfuscate(
`
function foo(arg) {
console.log(arg)
}
function bar() {
var bark = 2;
}
`,
{
compact: false,
identifierNamesCache: {},
renameGlobals: true
}
)
console.log(source1ObfuscationResult.getIdentifierNamesCache());
/*
{
globalIdentifiers: {
foo: '_0x5de86d',
bar: '_0x2a943b'
}
}
*/
const source2ObfuscationResult = JavaScriptObfuscator.obfuscate(
`
// Expecting that these global functions are defined in another obfuscated file
foo(1);
bar();
// Expecting that this global function is defined in third-party package
baz();
`,
{
compact: false,
identifierNamesCache: source1ObfuscationResult.getIdentifierNamesCache(),
renameGlobals: true
}
)
console.log(source2ObfuscationResult.getObfuscatedCode());
/*
_0x5de86d(0x1);
_0x2a943b();
baz();
*/
CLI
La CLI dispose d'une option différente, --identifier-names-cache-path, qui permet de définir le chemin d'un fichier .json existant servant à lire et écrire le cache des noms d'identifiants.
Si le chemin d'un fichier vide est passé, le cache des noms d'identifiants y sera écrit.
Ce fichier contenant un cache existant peut être réutilisé comme valeur de l'option --identifier-names-cache-path afin de réutiliser ces noms lors de l'obfuscation de tous les identifiants correspondants des fichiers suivants.
identifierNamesGenerator
Type: string Default: hexadecimal
Définit le générateur de noms d'identifiants.
Valeurs disponibles :
dictionary: noms d'identifiants issus de la listeidentifiersDictionaryhexadecimal: noms d'identifiants du type_0xabc123mangled: noms d'identifiants courts commea,b,cmangled-shuffled: identique àmangled, mais avec un alphabet mélangé
identifiersDictionary
Type: string[] Default: []
Définit le dictionnaire d'identifiants pour l'option identifierNamesGenerator : dictionary. Chaque identifiant du dictionnaire sera utilisé en plusieurs variantes, avec une casse différente pour chaque caractère. Le nombre d'identifiants du dictionnaire doit donc dépendre du nombre d'identifiants présents dans le code source d'origine.
identifiersPrefix
Type: string Default: ''
Définit un préfixe pour tous les identifiants globaux.
Utilisez cette option lorsque vous obfusquez plusieurs fichiers. Elle permet d'éviter les conflits entre les identifiants globaux de ces fichiers. Le préfixe doit être différent pour chaque fichier.
randomIdentifiersPrefix
Type: boolean Default: false
Ajoute un préfixe aléatoire dérivé de la graine (6 caractères alphanumériques) à tous les identifiants globaux. Utilisez cette option pour éviter les collisions entre des bundles obfusqués séparément et chargés dans la même portée globale — elle évite d'avoir à choisir manuellement un identifiersPrefix unique pour chaque bundle.
- La valeur aléatoire est dérivée de l'option
seedet du hash du code source ; des builds reproductibles avec la même graine produisent donc le même préfixe. - Combinée à
identifiersPrefix, les caractères aléatoires sont ajoutés à la suite du préfixe fourni par l'utilisateur (par exemplemyApp+aBc123aléatoire →myAppaBc123). - Combinée à
vmObfuscation, la valeur aléatoire remplace le préfixevmpar défaut — le caractère aléatoire garantit déjà l'unicité.
ignoreImports
Type: boolean Default: false
Empêche l'obfuscation des imports require. Peut être utile dans certains cas où, pour une raison ou une autre, l'environnement d'exécution exige que ces imports utilisent uniquement des chaînes statiques.
inputFileName
Type: string Default: ''
Permet de définir le nom du fichier d'entrée contenant le code source. Ce nom est utilisé en interne pour la génération de la source map.
Requis lors de l'utilisation de l'API NodeJS lorsque l'option sourceMapSourcesMode a la valeur sources.
log
Type: boolean Default: false
Active la journalisation des informations dans la console.
numbersToExpressions
Type: boolean Default: false
Active la conversion des nombres en expressions.
Exemple :
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Permet de définir un préréglage d'options.
Valeurs disponibles :
vm-default;vm-low-obfuscation;vm-medium-obfuscation;vm-high-obfuscation;vm-ultra-high-obfuscation;vm-anti-llm;default;low-obfuscation;medium-obfuscation;high-obfuscation.
Toutes les options supplémentaires seront fusionnées avec le préréglage d'options sélectionné.
parseHtml
Type: boolean Default: false
Active l'obfuscation du JavaScript contenu dans les balises HTML <script>.
Lorsqu'elle est activée, l'obfuscateur :
- Détecte automatiquement si l'entrée est du HTML (en recherchant les balises
<!DOCTYPE,<html>,<head>,<body>ou<script>) - Extrait le JavaScript des balises
<script>marquées par l'attributdata-javascript-obfuscator - Obfusque chaque script marqué individuellement tout en préservant la structure HTML
- Réinjecte le code obfusqué à ses positions d'origine
Important : seuls les scripts portant l'attribut data-javascript-obfuscator sont obfusqués. Chaque script marqué est obfusqué de façon individuelle et indépendante. Cela signifie que :
- Le code contenu dans les balises de script marquées doit être isolé : il ne doit PAS référencer de variables, fonctions ou classes définies dans d'autres balises de script marquées
- Les scripts non marqués peuvent tout de même accéder aux globales définies par les scripts marqués (via des déclarations
varou des affectations explicites àglobalThis) - Cela vous donne un contrôle explicite sur les scripts à protéger
Obfusqués (doivent porter l'attribut data-javascript-obfuscator) :
<script data-javascript-obfuscator>- scripts ordinaires<script type="text/javascript" data-javascript-obfuscator>- scripts au type explicite- Scripts comportant des attributs supplémentaires (
id,class, autresdata-*, etc.)
Ignorés (laissés inchangés) :
- Scripts sans l'attribut
data-javascript-obfuscator <script type="module">- modules ES (même avec l'attribut)<script src="...">- scripts externes (même avec l'attribut)- Balises de script vides
Remarque : aucune source map n'est générée lorsque parseHtml est activé, car elle ne correspondrait pas correctement à la sortie HTML.
Exemple :
// input
const html = `<!DOCTYPE html>
<html>
<body>
<!-- This script will NOT be obfuscated -->
<script>
var helper = 'utility';
</script>
<!-- This script WILL be obfuscated -->
<script data-javascript-obfuscator>
var greeting = 'Hello World';
console.log(greeting);
</script>
</body>
</html>`;
JavaScriptObfuscator.obfuscate(html, {
parseHtml: true,
stringArray: true
});
// output: HTML with only the marked script obfuscated
renameGlobals
Type: boolean Default: false
⚠️ cette option peut casser votre code. Ne l'activez que si vous savez ce qu'elle fait !
Active l'obfuscation des noms de variables et de fonctions globales avec déclaration.
Lorsque cette option est désactivée et que le code d'entrée déclare des fonctions ou des classes dans la portée globale (c'est-à-dire que le code n'est pas encapsulé dans une IIFE), leurs noms sont conservés tels quels dans la sortie obfusquée — d'autres scripts peuvent y faire référence par leur nom. Sous vmObfuscation, un avertissement VMGlobalFunctionNamesNotRenamed listant ces noms est signalé, car le corps de la fonction est masqué sous forme de bytecode tandis que le nom lisible de premier niveau révèle toujours ce que fait le code (par exemple à un LLM). Pour éviter cette exposition, encapsulez le code dans une IIFE ou activez cette option.
renameProperties
Type: boolean Default: false
⚠️ cette option PEUT casser votre code. Ne l'activez que si vous savez ce qu'elle fait !
Active le renommage des noms de propriétés. Toutes les propriétés DOM intégrées ainsi que les propriétés des classes JavaScript de base sont ignorées.
Pour basculer entre les modes safe et unsafe de cette option, utilisez l'option renamePropertiesMode.
Pour définir le format des noms de propriétés renommés, utilisez l'option identifierNamesGenerator.
Pour contrôler quelles propriétés seront renommées, utilisez l'option reservedNames.
Exemple :
// input
(function () {
const foo = {
prop1: 1,
prop2: 2,
calc: function () {
return this.prop1 + this.prop2;
}
};
console.log(foo.calc());
})();
// output
(function () {
const _0x46529b = {
'_0x10cec7': 0x1,
'_0xc1c0ca': 0x2,
'_0x4b961d': function () {
return this['_0x10cec7'] + this['_0xc1c0ca'];
}
};
console['log'](_0x46529b['_0x4b961d']());
}());
renamePropertiesMode
Type: string Default: safe
⚠️ Même en mode safe, l'option renameProperties PEUT casser votre code.
Spécifie le mode de l'option renameProperties :
safe- comportement par défaut depuis la version2.11.0. Tente de renommer les propriétés de façon plus sûre afin d'éviter les erreurs d'exécution. Dans ce mode, certaines propriétés sont exclues du renommage.unsafe- comportement par défaut avant la version2.11.0. Renomme les propriétés de façon non sécurisée, sans aucune restriction.
Si un fichier utilise des propriétés d'un autre fichier, utilisez l'option identifierNamesCache pour conserver les mêmes noms de propriétés entre ces fichiers.
reservedNames
Type: string[] Default: []
Désactive l'obfuscation et la génération des identifiants correspondant aux motifs RegExp fournis.
Exemple :
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Désactive la transformation des littéraux de chaîne correspondant aux motifs RegExp fournis. Les chaînes correspondantes resteront visibles dans la sortie obfusquée.
Avec l'obfuscation VM, les chaînes réservées sont stockées dans un tableau distinct non chiffré afin de rester visibles. C'est utile pour les chaînes qui doivent rester lisibles, comme les points de terminaison d'API pour la supervision ou les identifiants de bibliothèques.
Exemple :
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Cette option définit la graine du générateur aléatoire. C'est utile pour obtenir des résultats reproductibles.
Si la graine vaut 0, le générateur aléatoire fonctionne sans graine.
selfDefending
Type: boolean Default: false
⚠️ Ne modifiez d'aucune façon le code obfusqué après l'obfuscation avec cette option, car toute modification comme une minification du code peut déclencher l'auto-défense et le code cessera de fonctionner !
⚠️ Cette option force la valeur compact à true
⚠️ Cette option est silencieusement désactivée lorsque vmObfuscation est activé. Utilisez plutôt vmSelfDefending.
Cette option rend le code de sortie résistant à la mise en forme et au renommage des variables. Si l'on tente d'utiliser un embellisseur JavaScript sur le code obfusqué, celui-ci cessera de fonctionner, ce qui le rend plus difficile à comprendre et à modifier.
simplify
Type: boolean Default: true
Active une obfuscation supplémentaire du code par simplification.
⚠️ dans les prochaines versions, l'obfuscation des littéraux boolean (true => !![]) sera déplacée sous cette option.
Exemple :
// input
if (condition1) {
const foo = 1;
const bar = 2;
console.log(foo);
return bar;
} else if (condition2) {
console.log(1);
console.log(2);
console.log(3);
return 4;
} else {
return 5;
}
// output
if (condition1) {
const foo = 0x1, bar = 0x2;
return console['log'](foo), bar;
} else
return condition2 ? (console['log'](0x1), console['log'](0x2), console['log'](0x3), 0x4) : 0x5;
sourceMap
Type: boolean Default: false
Active la génération d'une source map pour le code obfusqué.
Les source maps peuvent vous aider à déboguer votre code source JavaScript obfusqué. Si vous souhaitez ou devez déboguer en production, vous pouvez téléverser le fichier de source map distinct vers un emplacement secret, puis y diriger votre navigateur.
sourceMapBaseUrl
Type: string Default: ``
Définit l'URL de base de l'URL d'import de la source map lorsque sourceMapMode: 'separate'.
Exemple en CLI :
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Résultat :
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Définit le nom du fichier de sortie de la source map lorsque sourceMapMode: 'separate'.
Exemple en CLI :
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Résultat :
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Spécifie le mode de génération de la source map :
inline- ajoute la source map à la fin de chaque fichier .js ;separate- génère un fichier '.map' correspondant contenant la source map. Si vous exécutez l'obfuscateur via la CLI, un lien vers le fichier de source map est ajouté à la fin du fichier de code obfusqué ://# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Permet de contrôler les champs sources et sourcesContent de la source map :
sources-content- ajoute un champsourcesfactice et un champsourcesContentcontenant le code source d'origine ;sources- ajoute un champsourcesavec une description de source valide, sans ajouter de champsourcesContent. Avec l'API NodeJS, il est nécessaire de définir l'optioninputFileName, qui sera utilisée comme valeur du champsources.
splitStrings
Type: boolean Default: false
Découpe les chaînes littérales en morceaux dont la longueur correspond à la valeur de l'option splitStringsChunkLength.
Exemple :
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Définit la longueur des morceaux de l'option splitStrings.
stringArray
Type: boolean Default: true
Retire les littéraux de chaîne et les place dans un tableau spécial. Par exemple, la chaîne "Hello World" dans var m = "Hello World"; sera remplacée par quelque chose comme var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ l'option stringArray doit être activée
Active la transformation des appels au stringArray. Tous les arguments de ces appels peuvent être extraits vers un autre objet selon la valeur de stringArrayCallsTransformThreshold.
Cela rend encore plus difficile la détection automatique des appels au tableau de chaînes.
Exemple :
function foo() {
var k = {
c: 0x2f2,
d: '0x396',
e: '0x397',
f: '0x39a',
g: '0x39d',
h: 0x398,
l: 0x394,
m: '0x39b',
n: '0x39f',
o: 0x395,
p: 0x395,
q: 0x399,
r: '0x399'
};
var c = i(k.d, k.e);
var d = i(k.f, k.g);
var e = i(k.h, k.l);
var f = i(k.m, k.n);
function i(c, d) {
return b(c - k.c, d);
}
var g = i(k.o, k.p);
var h = i(k.q, k.r);
}
function j(c, d) {
var l = { c: 0x14b };
return b(c - -l.c, d);
}
console[j(-'0xa6', -'0xa6')](foo());
function b(c, d) {
var e = a();
b = function (f, g) {
f = f - 0xa3;
var h = e[f];
return h;
};
return b(c, d);
}
function a() {
var m = [
'string5',
'string1',
'log',
'string3',
'string6',
'string2',
'string4'
];
a = function () {
return m;
};
return a();
}
stringArrayCallsTransformThreshold
Type: number Default: 0.5
⚠️ les options stringArray et stringArrayCallsTransformThreshold doivent être activées
Ce paramètre permet d'ajuster la probabilité (de 0 à 1) que les appels au tableau de chaînes soient transformés.
stringArrayEncoding
Type: string[] Default: []
⚠️ l'option stringArray doit être activée
Cette option peut ralentir votre script.
Encode tous les littéraux de chaîne du stringArray à l'aide de base64 ou rc4 et insère un code spécial servant à les décoder à l'exécution.
Chaque valeur du stringArray sera encodée selon un encodage choisi aléatoirement dans la liste fournie. Cela permet d'utiliser plusieurs encodages.
Valeurs disponibles :
'none'(boolean) : n'encode pas la valeur dustringArray'base64'(string) : encode la valeur dustringArrayavecbase64'rc4'(string) : encode la valeur dustringArrayavecrc4. Environ 30 à 50 % plus lent quebase64, mais rend plus difficile la récupération des valeurs initiales.
Par exemple, avec les valeurs d'option suivantes, certaines valeurs du stringArray ne seront pas encodées, et d'autres seront encodées avec base64 et rc4 :
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ l'option stringArray doit être activée
Permet de contrôler le type des index d'appel au tableau de chaînes.
Chaque index d'appel au stringArray sera transformé selon un type choisi aléatoirement dans la liste fournie. Cela permet d'utiliser plusieurs types.
Valeurs disponibles :
'hexadecimal-number'(default) : transforme les index d'appel au tableau de chaînes en nombres hexadécimaux'hexadecimal-numeric-string': transforme les index d'appel au tableau de chaînes en chaînes numériques hexadécimales
Avant la version 2.9.0, javascript-obfuscator transformait tous les index d'appel au tableau de chaînes avec le type hexadecimal-numeric-string. Cela rend la déobfuscation manuelle légèrement plus difficile, mais permet une détection facile de ces appels par les déobfuscateurs automatiques.
Le nouveau type hexadecimal-number vise à rendre plus difficile la détection automatique des motifs d'appel au tableau de chaînes dans le code.
D'autres types seront ajoutés à l'avenir.
stringArrayIndexShift
Type: boolean Default: true
⚠️ l'option stringArray doit être activée
Active un décalage d'index supplémentaire pour tous les appels au tableau de chaînes
stringArrayRotate
Type: boolean Default: true
⚠️ stringArray doit être activé
Décale le tableau stringArray d'un nombre de positions fixe et aléatoire (généré lors de l'obfuscation du code). Cela rend plus difficile la mise en correspondance de l'ordre des chaînes retirées avec leur emplacement d'origine.
stringArrayShuffle
Type: boolean Default: true
⚠️ stringArray doit être activé
Mélange aléatoirement les éléments du tableau stringArray.
stringArrayWrappersCount
Type: number Default: 1
⚠️ l'option stringArray doit être activée
Définit le nombre de wrappers du string array dans chaque portée racine ou de fonction.
Le nombre réel de wrappers dans chaque portée est limité par le nombre de nœuds literal présents dans cette portée.
Exemple :
// Input
const foo = 'foo';
const bar = 'bar';
function test () {
const baz = 'baz';
const bark = 'bark';
const hawk = 'hawk';
}
const eagle = 'eagle';
// Output, stringArrayWrappersCount: 5
const _0x3f6c = [
'bark',
'bar',
'foo',
'eagle',
'hawk',
'baz'
];
const _0x48f96e = _0x2e13;
const _0x4dfed8 = _0x2e13;
const _0x55e970 = _0x2e13;
function _0x2e13(_0x33c4f5, _0x3f6c62) {
_0x2e13 = function (_0x2e1388, _0x60b1e) {
_0x2e1388 = _0x2e1388 - 0xe2;
let _0x53d475 = _0x3f6c[_0x2e1388];
return _0x53d475;
};
return _0x2e13(_0x33c4f5, _0x3f6c62);
}
const foo = _0x48f96e(0xe4);
const bar = _0x4dfed8(0xe3);
function test() {
const _0x1c262f = _0x2e13;
const _0x54d7a4 = _0x2e13;
const _0x5142fe = _0x2e13;
const _0x1392b0 = _0x1c262f(0xe7);
const _0x201a58 = _0x1c262f(0xe2);
const _0xd3a7fb = _0x1c262f(0xe6);
}
const eagle = _0x48f96e(0xe5);
stringArrayWrappersChainedCalls
Type: boolean Default: true
⚠️ les options stringArray et stringArrayWrappersCount doivent être activées
Active les appels chaînés entre les wrappers du string array.
Exemple :
// Input
const foo = 'foo';
const bar = 'bar';
function test () {
const baz = 'baz';
const bark = 'bark';
function test1() {
const hawk = 'hawk';
const eagle = 'eagle';
}
}
// Output, stringArrayWrappersCount: 5, stringArrayWrappersChainedCalls: true
const _0x40c2 = [
'bar',
'bark',
'hawk',
'eagle',
'foo',
'baz'
];
const _0x31c087 = _0x3280;
const _0x31759a = _0x3280;
function _0x3280(_0x1f52ee, _0x40c2a2) {
_0x3280 = function (_0x3280a4, _0xf07b02) {
_0x3280a4 = _0x3280a4 - 0x1c4;
let _0x57a182 = _0x40c2[_0x3280a4];
return _0x57a182;
};
return _0x3280(_0x1f52ee, _0x40c2a2);
}
const foo = _0x31c087(0x1c8);
const bar = _0x31c087(0x1c4);
function test() {
const _0x848719 = _0x31759a;
const _0x2693bf = _0x31c087;
const _0x2c08e8 = _0x848719(0x1c9);
const _0x359365 = _0x2693bf(0x1c5);
function _0x175e90() {
const _0x310023 = _0x848719;
const _0x2302ef = _0x2693bf;
const _0x237437 = _0x310023(0x1c6);
const _0x56145c = _0x310023(0x1c7);
}
}
stringArrayWrappersParametersMaxCount
Type: number Default: 2
⚠️ l'option stringArray doit être activée
⚠️ Actuellement, cette option n'affecte que les wrappers ajoutés par la valeur function de l'option stringArrayWrappersType
Permet de contrôler le nombre maximal de paramètres des wrappers du tableau de chaînes.
La valeur par défaut et minimale est 2. Valeur recommandée entre 2 et 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ les options stringArray et stringArrayWrappersCount doivent être activées
Permet de sélectionner le type des wrappers ajoutés par l'option stringArrayWrappersCount.
Valeurs disponibles :
'variable': ajoute des wrappers de type variable en haut de chaque portée. Performances rapides.'function': ajoute des wrappers de type fonction à des positions aléatoires dans chaque portée. Performances plus lentes qu'avecvariable, mais offre une obfuscation plus stricte.
Il est fortement recommandé d'utiliser les wrappers function pour une obfuscation plus poussée lorsque la perte de performances n'a pas d'impact important sur l'application obfusquée.
Exemple avec la valeur 'function' :
// input
const foo = 'foo';
function test () {
const bar = 'bar';
console.log(foo, bar);
}
test();
// output
const a = [
'log',
'bar',
'foo'
];
const foo = d(0x567, 0x568);
function b(c, d) {
b = function (e, f) {
e = e - 0x185;
let g = a[e];
return g;
};
return b(c, d);
}
function test() {
const c = e(0x51c, 0x51b);
function e (c, g) {
return b(c - 0x396, g);
}
console[f(0x51b, 0x51d)](foo, c);
function f (c, g) {
return b(c - 0x396, g);
}
}
function d (c, g) {
return b(g - 0x3e1, c);
}
test();
stringArrayThreshold
Type: number Default: 0.8 Min: 0 Max: 1
⚠️ l'option stringArray doit être activée
Ce paramètre permet d'ajuster la probabilité (de 0 à 1) qu'un littéral de chaîne soit inséré dans le stringArray.
Ce paramètre est particulièrement utile pour les codes volumineux, car il génère de nombreux appels au string array et peut ralentir votre code.
stringArrayThreshold: 0 équivaut à stringArray: false.
strictMode
Type: boolean | null Default: null
Permet de spécifier la façon dont l'obfuscateur traite le code vis-à-vis du mode strict de JavaScript.
Valeurs disponibles :
null(par défaut) - détecte automatiquement le mode strict à partir du code. Si le code contient une directive'use strict'explicite, une syntaxe de module ES ou des méthodes de classe, il est traité en mode strict. Sinon, le mode non strict (sloppy) est supposé.true- force le traitement en mode strict pour tout le code, même sans directive'use strict'explicite. À utiliser lorsque votre code s'exécutera dans un contexte de mode strict (par exemple dans des modules ES, des bundlers ou des frameworks modernes).false- seuls les indicateurs de mode strict explicites ('use strict', modules ES, méthodes de classe) sont traités comme du mode strict. L'héritage de la portée parente s'applique toujours conformément à la spécification JS.
target
Type: string Default: browser
Permet de définir l'environnement cible du code obfusqué.
Valeurs disponibles :
browser(par défaut) — environnement de page web standard. Le code produit est identique à celui denode, mais certaines options propres au navigateur ne peuvent pas être utilisées avec la ciblenodebrowser-no-eval— identique àbrowser, mais la sortie n'utilise paseval(). À utiliser lorsque la page cible applique une Content Security Policy qui interditeval/unsafe-eval.node— environnement Node.js. Les options propres au navigateur sont désactivées (elles requièrentwindow/documentet seraient sans effet ou lèveraient une erreur sous Node). Certaines défensesvmSelfDefendingqui reposent sur des API exclusivement navigateur — détection de navigateur headless, restauration d'un realm propre via iframe, contrôles anti-inspecteur/DOM — ne sont pas générées pour cette cible.service-worker— contexte Service Worker. Pas dewindow, pas dedocument, un globalselfdifférent.userscript— bac à sable d'un gestionnaire de userscripts (Tampermonkey, par exemple). Les défensesvmSelfDefendingsont ajustées en conséquence.bytenode— code Node.js qui sera compilé avec le chargeur bytenode (bytecode V8 mis en cache.jsc) après l'obfuscation. L'obfuscateur lui-même n'invoque pasbytenode; il produit un JavaScript obfusqué par VM dont le runtime est structuré pour survivre à l'étape de compilation de bytenode, et les défensesvmSelfDefendingsont ajustées en conséquence. Exécutez vous-mêmebytenodesur la sortie obfusquée pour produire le fichier.jscfinal.
transformObjectKeys
Type: boolean Default: false
Active la transformation des clés d'objet.
Exemple :
// input
(function(){
var object = {
foo: 'test1',
bar: {
baz: 'test2'
}
};
})();
// output
var _0x4735 = [
'foo',
'baz',
'bar',
'test1',
'test2'
];
function _0x390c(_0x33d6b6, _0x4735f4) {
_0x390c = function (_0x390c37, _0x1eed85) {
_0x390c37 = _0x390c37 - 0x198;
var _0x2275f8 = _0x4735[_0x390c37];
return _0x2275f8;
};
return _0x390c(_0x33d6b6, _0x4735f4);
}
(function () {
var _0x17d1b7 = _0x390c;
var _0xc9b6bb = {};
_0xc9b6bb[_0x17d1b7(0x199)] = _0x17d1b7(0x19c);
var _0x3d959a = {};
_0x3d959a[_0x17d1b7(0x198)] = _0x17d1b7(0x19b);
_0x3d959a[_0x17d1b7(0x19a)] = _0xc9b6bb;
var _0x41fd86 = _0x3d959a;
}());
warnings
Type: string | object Default: all
Contrôle quels avertissements d'obfuscation non fatals sont émis via la méthode ObfuscationResult.getWarnings().
Valeurs disponibles :
'all'(par défaut) — chaque avertissement est émis.'none'— tous les avertissements sont supprimés.- un objet associant des types d'avertissement à des booléens — un type associé à
falseest supprimé ; tout type absent (ou associé àtrue) reste actif. Par exemple,{ "VMGlobalFunctionNamesNotRenamed": false }conserve tous les avertissements sauf celui-ci.
Types d'avertissement :
VMGlobalFunctionNamesNotRenamed— sousvmObfuscation, les noms des déclarations de fonctions de premier niveau, des déclarations de classes et des variables auxquelles est affectée une expression de fonction/fléchée/classe ont été conservés tels quels (l'optionrenameGlobalsest désactivée et le code n'est pas encapsulé dans une IIFE) ; ils restent donc lisibles dans la sortie même si les corps sont masqués sous forme de bytecode. Les noms exportés ne sont pas signalés.VMTopLevelInitializerNotVirtualized— des initialiseurs de variables de premier niveau sont restés en JavaScript ordinaire sous obfuscation VM parce quevmWrapTopLevelInitializersest désactivé ou n'a pas pu les virtualiser.DynamicCodeRenameRisk— le code construit une fonction à partir d'une chaîne à l'exécution (evaldirect, constructeurFunction, oufn.toString()injecté dans un<script>/Worker), ce qui peut référencer des identifiants que l'obfuscateur a renommés.VMDynamicCodeSkipped— une fonction a été exclue du bytecoding VM parce qu'elle contient unevaldirect / unnew Functiondynamique /Function(voirvmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— avecvmAsyncExecutoractivé, une fonction que vous aviez explicitement marquée en modecomments'est avérée synchrone et a été ignorée (seules les fonctions asynchrones sont virtualisées dans ce mode).VMAsyncGeneratorSkippedInAsyncMode— avecvmAsyncExecutoret un getter de clé asynchrone actif, un générateur asynchrone marqué n'a pas pu être virtualisé (il doit renvoyer son itérateur de façon synchrone).BrowserTargetWithNodeStyleCode— le code semble cibler Node.js (par exemplerequire('fs'),__dirname,process.argv) alors que l'optiontargetest réglée sur un environnement de type navigateur.
vmObfuscation
Type: boolean Default: false
Active l'obfuscation en bytecode basée sur une VM. Lorsqu'elle est activée, les fonctions JavaScript sont compilées en bytecode sur mesure qui s'exécute sur une machine virtuelle embarquée. Cela offre le plus haut niveau de protection, car la logique du code d'origine est entièrement transformée.
Exemple :
Un code lisible comme return qty * price devient une liste de nombres comme [0x15,0x03,0x17,...] que seul l'interpréteur VM embarqué peut exécuter. La logique d'origine n'est plus visible sous forme de JavaScript.
vmTargetFunctions
Type: string[] Default: []
Indique précisément, par leur nom, quelles fonctions de premier niveau doivent bénéficier de la protection VM.
Exemple :
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Résultat : seules ces trois fonctions sont protégées par VM. Tout le reste demeure du JavaScript ordinaire (mais toujours obfusqué). Idéal pour protéger des vérifications de licence sensibles ou une logique d'authentification tout en gardant le reste de votre code léger.
vmExcludeFunctions
Type: string[] Default: []
Indique les fonctions de premier niveau qui ne doivent jamais bénéficier de la protection VM. Cette option a priorité sur les autres réglages.
Exemple :
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Quand l'utiliser : les fonctions de premier niveau critiques pour les performances (boucles d'animation, traitement de données en temps réel) peuvent être exclues afin d'éviter la surcharge de la VM tout en protégeant tout le reste.
vmTargetFunctionsMode
Type: string Default: root
Contrôle la façon dont les fonctions/méthodes sont sélectionnées pour l'obfuscation VM.
Exemple - mode Comment :
// Source code
function regularFunction() {
return 'not virtualized';
}
/* javascript-obfuscator:vm */
function sensitiveFunction() {
return 'this will be VM-protected';
}
function outer() {
/* javascript-obfuscator:vm */
function nestedSensitive() {
return 'nested but still VM-protected';
}
return nestedSensitive();
}
// Obfuscator options
{
vmObfuscation: true,
vmTargetFunctionsMode: 'comment'
}
Quand l'utiliser : lorsque vous avez besoin d'un contrôle chirurgical sur les fonctions qui bénéficient de la protection VM, en particulier des fonctions imbriquées contenant une logique sensible. Contrairement à vmTargetFunctions, qui ne fonctionne qu'avec des fonctions nommées de premier niveau, le mode comment vous permet de protéger n'importe quelle fonction, où qu'elle se trouve dans votre code.
vmForceCompileDynamicCode
Type: boolean Default: false
Contrôle ce que l'obfuscation VM fait d'une fonction contenant un appel direct à eval, new Function(...) ou Function(...).
Par défaut, une telle fonction (ainsi que toutes les fonctions qui y sont définies) est exclue du bytecoding VM et un avertissement VMDynamicCodeSkipped est signalé via result.getWarnings(). En effet, le source construit à l'exécution peut référencer des identifiants de la chaîne de portées environnante — des identifiants que l'obfuscateur a renommés.
Lorsqu'elle vaut true, la fonction est tout de même convertie en bytecode et l'avertissement VMDynamicCodeSkipped n'est plus émis.
L'avertissement distinct DynamicCodeRenameRisk continue de se déclencher quelle que soit cette option, car le risque de renommage qu'il décrit est indépendant de l'exclusion VM — activer cette option ne rend pas le motif sous-jacent plus sûr pour autant.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
Avec l'option désactivée (par défaut), loadConfig reste en JavaScript ordinaire. Avec l'option activée, loadConfig est compilée en bytecode VM comme n'importe quelle autre fonction. Utilisez-la lorsque vous avez audité le site d'appel et que vous savez que le code construit à l'exécution ne dépend pas d'identifiants renommés par une closure.
vmWrapTopLevelInitializers
Type: boolean Default: false
Encapsule certains initialiseurs de variables de premier niveau dans des IIFE (expressions de fonction immédiatement invoquées) afin qu'ils puissent être obfusqués par VM.
Ce qu'elle fait : Sans cette option, les constantes et variables de premier niveau restent visibles dans la sortie :
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
Avec cette option activée, l'initialiseur est encapsulé dans une IIFE qui est obfusquée par VM :
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Remarque : cette option ne fonctionne que lorsque vmTargetFunctionsMode vaut 'root' (la valeur par défaut).
Avertissements : chaque fois qu'un initialiseur de premier niveau se retrouve en JavaScript ordinaire sous obfuscation VM, un avertissement VMTopLevelInitializerNotVirtualized listant les noms des variables concernées est signalé. Cela couvre : cette option désactivée, les initialiseurs que cette option a dû ignorer (chacun accompagné de sa raison — par exemple l'initialiseur référence un déclarateur voisin ou contient un await de premier niveau), et le mode vmAsyncExecutor où les wrappers synchrones ne peuvent pas du tout être virtualisés.
vmDynamicOpcodes
Type: boolean Default: false
Rend l'interpréteur VM plus petit et unique à chaque build.
Ce qu'elle fait :
- Filtre les instructions inutilisées - Si votre code n'utilise pas de classes, les instructions liées aux classes sont entièrement supprimées
- Rend la structure aléatoire - L'ordre des gestionnaires d'instructions est mélangé à chaque build
En conséquence, la sortie est plus petite et chaque build a une apparence différente.
vmBytecodeEncoding
Type: boolean Default: false
Encode chaque instruction du bytecode. Les instructions sont décodées une par une pendant l'exécution.
vmBytecodeArrayEncoding
Type: boolean Default: false
Encode l'intégralité du tableau de bytecode en un seul bloc. Le tableau est décodé une seule fois au démarrage, avant le début de l'exécution. À utiliser conjointement avec vmBytecodeEncoding pour obtenir deux couches de protection.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Clé de chiffrement personnalisée pour l'encodage du tableau de bytecode. Lorsqu'elle est définie, cette clé est utilisée à la place de la clé par défaut dérivée de l'environnement. La clé doit être fournie à l'exécution via vmBytecodeArrayEncodingKeyGetter.
Cette option externalise la clé de chiffrement : elle n'est pas intégrée au code obfusqué lui-même. Bien que la clé reste accessible à l'exécution (et ne soit donc pas véritablement secrète), cette séparation empêche les outils d'analyse statique de retrouver la clé en examinant le seul code.
Important : la clé doit être disponible de façon synchrone au chargement du code obfusqué. Utilisez un stockage synchrone comme les cookies, localStorage, sessionStorage, des variables globales ou des éléments du DOM (par exemple des balises meta injectées par le serveur). Les méthodes asynchrones comme fetch() ne peuvent pas être utilisées directement dans l'expression du getter de clé.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Expression JavaScript synchrone qui renvoie la clé de chiffrement à l'exécution. Cette expression est évaluée au chargement du code obfusqué et doit renvoyer la même clé que celle fournie dans vmBytecodeArrayEncodingKey. Pour résoudre la clé de façon asynchrone (une Promise), activez vmAsyncExecutor.
Remarque : un getter renvoyant une Promise nécessite vmAsyncExecutor. Cela ne peut pas être vérifié au moment du build ; un getter renvoyant une Promise avec vmAsyncExecutor désactivé échoue donc à l'exécution — le décodeur reçoit la Promise au lieu de la clé.
Le code obfusqué ne fonctionne que si le getter de clé renvoie exactement la même clé que celle utilisée lors de l'obfuscation. Si les clés ne correspondent pas, le déchiffrement échoue et le code produit des résultats erronés ou des erreurs. Si le getter de clé renvoie undefined, null ou une chaîne vide, le code lève une erreur : "VM decryption key not available".
Important : ne conservez pas la clé dans le même fichier/script que le code obfusqué — l'y intégrer permet à un simple examen statique du bundle de la retrouver. Stockez-la plutôt dans une source distincte : cookies définis par le serveur, localStorage renseigné par un autre script, balise meta HTML injectée par le serveur, variable globale définie par un autre script, ou (avec vmAsyncExecutor) récupérée depuis votre backend à l'exécution.
Lorsque la clé est récupérée depuis votre backend (via vmAsyncExecutor), ajoutez des contrôles fondés sur la session ou l'origine sur ce point de terminaison : renvoyez la bonne clé aux utilisateurs réels (session valide, Origin/Referer attendus) et une clé factice aux requêtes suspectes (par exemple une origine localhost/inattendue, absence de session). Les utilisateurs réels s'exécutent normalement ; une copie exécutée en dehors de votre environnement obtient une clé qui ne déchiffre rien. La logique exacte dépend de votre site.
Exemples :
// From cookie
vmBytecodeArrayEncodingKeyGetter: "document.cookie.match(/vmKey=([^;]+)/)?.[1]"
// From localStorage
vmBytecodeArrayEncodingKeyGetter: "localStorage.getItem('vmKey')"
// From global variable
vmBytecodeArrayEncodingKeyGetter: "window.__VM_KEY__"
// From meta tag (server-injected)
vmBytecodeArrayEncodingKeyGetter: "document.querySelector('meta[name=\"vm-key\"]').content"
// From nested object
vmBytecodeArrayEncodingKeyGetter: "window.config.encryption.key"
// From backend, async (requires vmAsyncExecutor)
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
Exemple d'utilisation :
// Build time
JavaScriptObfuscator.obfuscate(code, {
vmObfuscation: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: 'mySecretKey123',
vmBytecodeArrayEncodingKeyGetter: 'window.__VM_KEY__'
});
// Runtime - key must be set before obfuscated code runs
window.__VM_KEY__ = 'mySecretKey123';
vmAsyncExecutor
Type: boolean Default: false
Active l'exécuteur VM asynchrone, qui permet à vmBytecodeArrayEncodingKeyGetter de renvoyer une Promise (un getter de clé asynchrone) — la clé de déchiffrement peut ainsi être récupérée à l'exécution (requête réseau, IndexedDB, etc.) au lieu de devoir être disponible de façon synchrone au chargement du code.
Fortement recommandé pour les bases de code entièrement asynchrones. Dans ce mode, seules les fonctions async sont virtualisées — une fonction synchrone ne peut pas être rendue asynchrone sans transformer sa valeur de retour en Promise et casser ses appelants — de sorte qu'un code async de bout en bout obtient la meilleure couverture. Cela fonctionne tout de même lorsque la racine est synchrone (par exemple une IIFE synchrone / un wrapper UMD) : les fonctions async les plus externes qu'elle contient sont protégées, et les parties synchrones sont laissées telles quelles.
Ce qui est transformé : chaque fonction async la plus externe, où qu'elle apparaisse (y compris imbriquée dans des wrappers synchrones). L'async la plus externe de chaque chaîne est l'unité protégée — tout ce qu'elle contient, synchrone comme asynchrone, y est compilé. Les fonctions synchrones et les générateurs simples restent non obfusqués.
function foo() { // sync — left as-is
function bar() {} // sync — left as-is
async function baz() { // transformed
// any code here, including calls to other async or sync functions
}
async function bark() { // transformed
// any code here, including calls to other async or sync functions
}
}
Exclusions et avertissements. Les générateurs asynchrones restent eux aussi non obfusqués lorsqu'un getter de clé asynchrone est actif (un générateur asynchrone doit renvoyer son itérateur de façon synchrone et ne peut pas attendre la clé). Dans le mode par défaut vmTargetFunctionsMode: 'root', les exclusions sont silencieuses (la sélection est automatique) ; en mode comment, un avertissement est émis via ObfuscationResult.getWarnings() chaque fois qu'une fonction que vous avez explicitement marquée ne peut pas être virtualisée — elle s'est avérée synchrone, ou il s'agit d'un générateur asynchrone sous un getter de clé asynchrone.
Le getter de clé asynchrone nécessite en outre vmBytecodeArrayEncoding avec un vmBytecodeArrayEncodingKeyGetter.
Exemple d'utilisation :
JavaScriptObfuscator.obfuscate(code, {
vmObfuscation: true,
vmAsyncExecutor: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: 'mySecretKey123',
// the key getter may now return a Promise
vmBytecodeArrayEncodingKeyGetter: 'fetch("/vm-key").then((res) => res.text())'
});
vmJumpsEncoding
Type: boolean Default: false
Encode les cibles de saut dans le bytecode. Les décalages de saut sont calculés à l'exécution, masquant la structure du flux de contrôle (if/else, boucles, etc.) à l'analyse statique.
vmMacroOps
Type: boolean Default: false
Combine des séquences d'instructions courantes en opcodes « macro » uniques. Par exemple, LOAD + ADD + STORE peut devenir une seule instruction MACRO_ADD_TO_VAR. Cela déjoue la reconnaissance de motifs et peut améliorer les performances.
vmDebugProtection
Type: boolean Default: false
Ajoute au runtime de la VM des défenses multicouches anti-débogage, anti-analyse et anti-LLM. Fonctionne au mieux avec les cibles browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Ajoute au runtime de la VM une protection multicouche de détection des altérations, anti-hooking et anti-rétro-ingénierie.
⚠️ Cette option active de force vmBytecodeArrayEncoding.
⚠️ Détection d'environnements sensibles. Cette option lie le code obfusqué à son environnement d'exécution cible et utilise un fingerprinting avancé du navigateur pour détecter les outils d'automatisation. Un code protégé par cette option se cassera intentionnellement lorsqu'il sera exécuté dans :
- Des navigateurs headless (Chrome/Chromium headless, PhantomJS)
- Des outils d'automatisation de navigateur (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (lorsque
targetvautbrowser) - jsdom ou d'autres émulations du DOM côté serveur
- Des environnements où des fonctions natives du navigateur ont été hookées ou remplacées
Le code fonctionnera correctement dans les navigateurs classiques (Chrome, Firefox, Safari, Edge), y compris lorsqu'il est chargé dans des iframes, des extensions de navigateur (content scripts) et des Web Workers. Si vous devez exécuter des tests automatisés sur du code protégé, désactivez vmSelfDefending pour les builds de test — cette option est conçue pour empêcher l'analyse automatisée et ne peut pas être utilisée en toute sécurité avec un quelconque framework d'automatisation.
Il est fortement recommandé de l'utiliser conjointement avec vmDebugProtection, vmBytecodeArrayEncodingKey et vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook prend un objet à deux clés : name (obligatoire) et aliases (facultatif).
name est une fonction globale définie par votre page hôte qu'une défense de la VM (vmDebugProtection / vmSelfDefending) appelle avec un objet signal lorsqu'elle détecte un signal hostile — un débogueur ou un inspecteur, un navigateur headless / d'automatisation, un processus d'agent de codage IA, un domaine non autorisé, etc. Utilisez-la pour remonter l'événement vers votre backend (par exemple via navigator.sendBeacon). Le hook est un simple puits de télémétrie : sa valeur de retour est ignorée, et un hook absent ou qui lève une exception est un no-op silencieux qui ne peut jamais désactiver une défense. Pour changer ce que fait une défense lors d'une détection, utilisez vmDefenseReaction.
aliases renomme facultativement les champs de cet objet signal — abordé plus bas dans Renommer les champs du signal.
L'objet signal. Le hook reçoit un unique signal :
source— le détecteur précis qui s'est déclenché (voir le tableau).category— le groupe sous lequel il remonte :automation(navigateurs non humains),debugger(un débogueur/inspecteur est actif),sandbox(hôte instrumenté/factice),domain(violation du verrouillage par domaine),tamper(fonctions intégrées modifiées à l'exécution) ouintegrity(le code propre de la VM a été altéré).score/threshold— l'intensité du déclenchement du détecteur et la valeur qu'il devait atteindre ; le hook ne se déclenche qu'une foisscore >= threshold. La plupart des contrôles sont tout ou rien (un unique signal décisif) ;headlessadditionne plusieurs signaux liés à la forme du navigateur, si bien que sonscoreest généralement supérieur à sonthreshold.
Enregistrement du hook. Définissez-le comme une simple globale avant le chargement du bundle obfusqué — le runtime de la VM et ses défenses s'exécutent avant votre programme (protégé), de sorte que de nombreuses détections se produisent au démarrage :
// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }
Un hook défini à l'intérieur du source obfusqué est enregistré trop tard pour intercepter les détections du démarrage et, s'il est compilé par la VM, il reste inaccessible tant que votre programme n'a pas démarré. Il reste sans danger dans tous les cas (un hook absent est un no-op, et un garde-fou anti-réentrance empêche tout emballement), mais pour une couverture complète, enregistrez-le en amont. Pour tout de même protéger votre logique de remontée, gardez comme hook enregistré un tampon d'une ligne ((window.__vmDet = window.__vmDet || []).push(signal)) et lisez/envoyez ce tampon depuis votre code obfusqué.
Renommer les champs du signal (aliases). Les valeurs source/category par défaut sont des noms descriptifs : quiconque instrumente le callback (ou lit la sortie) peut donc reconnaître la protection et le détecteur qui s'est déclenché. aliases remplace les noms des champs du signal par des jetons opaques de votre choix, appliqués à l'intérieur de la VM avant l'émission du signal, de sorte que ces noms n'apparaissent jamais dans la sortie ni ne parviennent au callback. Votre application connaît sa propre correspondance et transmet les jetons à votre backend.
Les alias se définissent champ par champ, en séparant le renommage des clés de celui des valeurs : chaque champ accepte une key (le nom de propriété que reçoit le callback) ; les champs de type chaîne source et category acceptent en plus une table values, tandis que score / threshold sont des nombres et n'acceptent qu'une key. Les noms que vous pouvez mapper (tout autre est rejeté au moment du build) :
- clés de champ —
source,category,score,threshold - valeurs de
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - valeurs de
category—automation,debugger,sandbox,domain,tamper,integrity
vmDefenseHook: {
name: '__vmDetection',
aliases: {
source: { key: 'a8Qm', values: { headless: 'xP4m9Q' } },
category: { key: 'p3Tx', values: { automation: 'bQ7s1M' } },
score: { key: 's1' },
threshold: { key: 't1' }
}
// the callback now receives e.g. { a8Qm: 'xP4m9Q', p3Tx: 'bQ7s1M', s1: <score>, t1: <threshold> }
}
Il s'agit d'une gêne à l'identification, pas d'un secret — la correspondance peut toujours être déduite par tâtonnements répétés — de sorte que son seul bénéfice est de ne pas exposer des noms stables et explicites. Les entrées non renseignées conservent leur nom par défaut.
Une chaîne simple (vmDefenseHook: '__vmDetection') est acceptée comme raccourci de { name: '__vmDetection' } mais est dépréciée — préférez la forme objet.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Configure la façon dont chaque catégorie de détection réagit. Elle n'active rien — les défenses elles-mêmes sont activées par vmSelfDefending, vmDebugProtection et vmDomainLock ; cette option ne fait que choisir comment réagit une défense déjà activée. La catégorie est l'unité de contrôle — chaque détecteur d'une catégorie applique la réaction de cette catégorie.
Chaque catégorie regroupe les détecteurs qui surveillent un même type de condition hostile. Une catégorie ne réagit que lorsque l'option qui émet ses détecteurs est activée :
Chaque catégorie correspond à une ou plusieurs des options vmSelfDefending, vmDebugProtection et vmDomainLock ; il n'existe aucune catégorie en dehors de ces trois options, et une réaction définie pour une catégorie dont l'option est désactivée n'a tout simplement aucun effet.
Les clés sont ces six noms de catégories, ou default (valeur de repli pour les catégories non spécifiées). Les valeurs sont :
break— rompre immédiatementdecoy— continuer à s'exécuter sur un état empoisonné, en produisant silencieusement des résultats erronésnone— ne rien faire localement (télémétrie uniquement)
Les valeurs par défaut par catégorie sont indiquées ci-dessus ; une catégorie que vous ne définissez pas (ou que vous laissez à sa valeur par défaut) utilise cette valeur par défaut. default atteint toutes les catégories, y compris celles qui sont correctes par construction (integrity, tamper) ; { default: 'none' } produit donc un build véritablement non intrusif, purement télémétrique :
vmDefenseReaction: { default: 'none' } // never break — pair with vmDefenseHook
vmDefenseReaction: { automation: 'none', domain: 'break' } // tolerate automation FPs, still break on a bad domain
vmStatefulOpcodes
Type: boolean Default: false
Fait dépendre la signification des opcodes de leur position dans le bytecode. Chaque position possède une correspondance opcode-vers-gestionnaire différente, dérivée d'une graine, de sorte qu'un même numéro d'opcode effectue des opérations différentes selon la position.
vmCallContextOpcodes
Type: boolean Default: false
Fait dépendre une fonction protégée de l'endroit d'où elle est appelée, de sorte qu'elle ne peut pas être extraite du code puis exécutée ou analysée isolément — elle ne se comporte correctement que lorsqu'elle est invoquée via ses véritables sites d'appel dans le programme. Cette option affecte les performances à l'exécution.
Actuellement, seules les constructions suivantes sont prises en charge :
- les déclarations de fonction (
function f() {}) ; - les expressions de fonction et les fonctions fléchées affectées à une variable (
const f = () => {}) ; - les méthodes privées d'instance (
this.#m()).
Dans tous les cas, la fonction doit toujours être atteinte par un appel direct (f(), this.#m()). Si elle est stockée dans une autre variable, passée en argument ou utilisée d'une autre manière comme valeur, elle reste non protégée. Les fonctions asynchrones sont prises en charge ; les générateurs ne le sont pas.
Cette option est expérimentale et peut casser votre code ; testez donc soigneusement la sortie avant de l'utiliser.
vmStackEncoding
Type: boolean Default: false
Chiffre les valeurs présentes sur la pile de la VM pendant l'exécution. Les valeurs sont encodées lorsqu'elles sont empilées et décodées lorsqu'elles sont dépilées, de sorte qu'une inspection de la mémoire montre des données chiffrées au lieu des valeurs réelles.
Cette option affecte fortement les performances.
vmCompactDispatcher
Type: boolean Default: false
Utilise un seul exécuteur VM au lieu de deux exécuteurs (synchrone + générateur). Réduit la taille du code obfusqué mais ajoute une surcharge d'environ 20 % sur un code fortement récursif.
false(par défaut) : deux exécuteurs — performances optimales, sortie plus volumineusetrue: un seul exécuteur — sortie plus petite, légèrement plus lente
vmStringArrayBytecodeOnly
Type: boolean Default: false
Lorsqu'elle est activée, le tableau de chaînes n'extrait que les chaînes issues des données de bytecode — aucune autre chaîne du code n'est transformée. Cela active de force stringArray même s'il n'est pas explicitement défini.
Pourquoi l'utiliser : extraire toutes les chaînes du runtime de la VM vers un tableau de chaînes est lent. Cette option ne cible que le contenu du bytecode pour l'extraction dans le tableau de chaînes, améliorant les performances tout en protégeant les constantes du bytecode.
- Lorsque
vmBytecodeArrayEncoding: false— les chaînes présentes dans les pools de constantes du bytecode (tableauxc) sont extraites - Lorsque
vmBytecodeArrayEncoding: true— les chaînes de bytecode encodées en base64 au niveau supérieur sont extraites stringArrayThresholdcontinue de contrôler le pourcentage de ces chaînes de bytecode qui sont extraites
vmDomainLock
Type: string[] Default: []
⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'
Restreint le code obfusqué à des domaines et/ou sous-domaines précis, et est bien plus difficile à localiser et à retirer que domainLock.
Si le code source n'est pas exécuté sur les domaines spécifiés par cette option, le navigateur est redirigé vers l'URL passée à vmDomainLockRedirectUrl, et les appels protégés ultérieurs renverront des résultats incorrects même si la redirection est supprimée.
Domaines et sous-domaines multiples
Il est possible de verrouiller votre code sur plusieurs domaines ou sous-domaines. Par exemple, pour le verrouiller de sorte qu'il ne s'exécute que sur www.example.com, ajoutez www.example.com. Pour qu'il fonctionne sur le domaine racine ainsi que sur tous ses sous-domaines (example.com, sub.example.com), utilisez .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Cette option ne fonctionne pas avec target: 'node', target: 'service-worker' ni target: 'bytenode'
Permet de rediriger le navigateur vers une URL fournie si le code source n'est pas exécuté sur les domaines spécifiés par vmDomainLock.
Options de préréglage
Obfuscation élevée, performances faibles
Les performances seront bien plus lentes que sans obfuscation
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
deadCodeInjection: true,
deadCodeInjectionThreshold: 1,
debugProtection: true,
debugProtectionInterval: 4000,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 5,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayEncoding: ['rc4'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersType: 'function',
stringArrayThreshold: 1,
transformObjectKeys: true
}
Obfuscation moyenne, performances optimales
Les performances seront plus lentes que sans obfuscation
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.75,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 10,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 0.75,
stringArrayEncoding: ['base64'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 2,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 4,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.75,
transformObjectKeys: true
}
Obfuscation faible, performances élevées
Les performances resteront à un niveau relativement normal
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: false,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: false,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75
}
Préréglage par défaut, performances élevées
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: 0,
disableConsoleOutput: false,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
selfDefending: false,
simplify: true,
splitStrings: false,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: false,
stringArrayCallsTransformThreshold: 0.5,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75
}
Obfuscation VM Ultra High (sécurité maximale)
Ce préréglage active l'obfuscation en bytecode basée sur une VM avec toutes les fonctionnalités de durcissement, y compris la répartition indirecte. Offre la protection la plus forte, mais avec une taille de sortie plus importante et une exécution bien plus lente.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: true,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: true,
vmCallContextOpcodes: false,
vmStackEncoding: true,
vmCompactDispatcher: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.5,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.5,
debugProtection: true,
debugProtectionInterval: 4000,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
selfDefending: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 5,
strictMode: null,
stringArray: true,
stringArrayCallsTransform: true,
stringArrayEncoding: ['rc4'],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.5,
transformObjectKeys: true
}
VM Anti-LLM (protection contre les agents IA)
Ce préréglage est spécifiquement conçu pour empêcher les agents IA et les LLM de rétro-concevoir du code en bytecode VM. Basé sur vm-default, avec l'auto-défense et la protection anti-débogage activées. Plus léger que vm-high-obfuscation, mais spécifiquement durci contre l'analyse automatisée.
{
optionsPreset: 'vm-anti-llm'
}
Inclut :
- l'obfuscation en bytecode VM avec tableau de chaînes (depuis
vm-default) vmSelfDefending— détection anti-hook, hash d'intégrité, empreinte de source, vérification d'un realm propre via iframe, dérivation de clé par chiffrement ARXvmDebugProtection— contrôles anti-débogage dans la boucle de répartition de la VMdebugProtection: false— pas de protection anti-débogage héritée (la protection anti-débogage de la VM est supérieure)
Obfuscation VM High (sécurité la plus élevée)
Ce préréglage active l'obfuscation en bytecode basée sur une VM avec la plupart des fonctionnalités de durcissement. Offre une protection forte avec de meilleures performances que le préréglage ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: true,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: true,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: true,
vmCallContextOpcodes: false,
vmStackEncoding: true,
vmCompactDispatcher: false
}
Obfuscation VM Medium (sécurité équilibrée)
Ce préréglage active l'obfuscation en bytecode basée sur une VM avec un ensemble équilibré de fonctionnalités de durcissement. Bon compromis entre sécurité et performances.
{
optionsPreset: 'vm-medium-obfuscation'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: true,
vmBytecodeArrayEncoding: false,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: true,
vmMacroOps: true,
vmDebugProtection: true,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false
}
Obfuscation VM Low (sécurité de base, meilleures performances)
Ce préréglage active une obfuscation en bytecode VM de base, sans fonctionnalités de durcissement supplémentaires. Bon équilibre entre sécurité et taille de sortie.
{
optionsPreset: 'vm-low-obfuscation'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: false,
vmBytecodeEncoding: false,
vmBytecodeArrayEncoding: false,
vmBytecodeArrayEncodingKey: '',
vmBytecodeArrayEncodingKeyGetter: '',
vmAsyncExecutor: false,
vmJumpsEncoding: false,
vmMacroOps: false,
vmDebugProtection: false,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false
}
VM Default (VM + protection du tableau de chaînes)
Ce préréglage combine une obfuscation en bytecode VM de base avec la protection par tableau de chaînes. Bon point de départ pour l'obfuscation VM avec protection des chaînes.
{
optionsPreset: 'vm-default'
}
Ou configurez individuellement :
{
compact: true,
simplify: true,
identifierNamesGenerator: 'mangled-shuffled',
vmObfuscation: true,
vmForceCompileDynamicCode: false,
vmWrapTopLevelInitializers: true,
vmDynamicOpcodes: true,
vmBytecodeEncoding: false,
vmBytecodeArrayEncoding: true,
vmStringArrayBytecodeOnly: true,
vmAsyncExecutor: false,
vmJumpsEncoding: false,
vmMacroOps: false,
vmDebugProtection: false,
vmSelfDefending: false,
vmDefenseHook: '',
vmDefenseReaction: {
automation: 'break',
debugger: 'decoy',
sandbox: 'decoy',
domain: 'break',
tamper: 'break',
integrity: 'break'
},
vmStatefulOpcodes: false,
vmCallContextOpcodes: false,
vmStackEncoding: false,
vmCompactDispatcher: false,
stringArray: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayThreshold: 1,
stringArrayIndexShift: true,
stringArrayIndexesType: ['hexadecimal-number'],
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 1,
stringArrayWrappersCount: 3,
stringArrayWrappersType: 'function',
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayEncoding: ['base64'],
splitStrings: true,
splitStringsChunkLength: 6
}
