Riferimento delle opzioni
Indice
compact
config
controlFlowFlattening
controlFlowFlatteningThreshold
deadCodeInjection
deadCodeInjectionThreshold
debugProtection
debugProtectionInterval
disableConsoleOutput
domainLock
Domini e sottodomini multipli
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
Domini e sottodomini multipli
vmDomainLockRedirectUrl
Preset Options
Offuscamento elevato, prestazioni basse
Offuscamento medio, prestazioni ottimali
Offuscamento basso, prestazioni elevate
Preset predefinito, prestazioni elevate
Offuscamento VM Ultra High (sicurezza massima)
VM Anti-LLM (protezione dagli agenti IA)
Offuscamento VM High (sicurezza più elevata)
Offuscamento VM Medium (sicurezza bilanciata)
Offuscamento VM Low (sicurezza di base, prestazioni migliori)
VM Default (VM + protezione con array di stringhe)
compact
Type: boolean Default: true
Comprime il codice di output su un'unica riga.
config
Type: string Default: ``
Nome del file di configurazione JS/JSON che contiene le opzioni dell'offuscatore. Queste vengono sovrascritte dalle opzioni passate direttamente alla CLI
controlFlowFlattening
Type: boolean Default: false
⚠️ Questa opzione incide notevolmente sulle prestazioni, con una velocità di esecuzione fino a 1,5 volte più lenta. Usa controlFlowFlatteningThreshold per impostare la percentuale di nodi interessati dall'appiattimento del flusso di controllo.
Attiva l'appiattimento del flusso di controllo del codice. L'appiattimento del flusso di controllo è una trasformazione della struttura del codice sorgente che ostacola la comprensione del programma.
Esempio:
// 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
La probabilità che la trasformazione controlFlowFlattening venga applicata a un determinato nodo.
Questa impostazione è particolarmente utile per basi di codice di grandi dimensioni, poiché un elevato numero di trasformazioni del flusso di controllo può rallentare il codice e aumentarne le dimensioni.
controlFlowFlatteningThreshold: 0 equivale a controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Aumenta drasticamente le dimensioni del codice offuscato (fino al 200%); usala solo se le dimensioni del codice offuscato non sono un problema. Usa deadCodeInjectionThreshold per impostare la percentuale di nodi interessati dall'iniezione di dead code.
⚠️ Questa opzione attiva forzatamente l'opzione stringArray.
⚠️ Questa opzione viene disabilitata silenziosamente quando vmObfuscation è attivata.
Con questa opzione, al codice offuscato vengono aggiunti blocchi casuali di dead code.
Esempio:
// 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
Consente di impostare la percentuale di nodi interessati da deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Può bloccare il browser se apri gli strumenti per sviluppatori.
⚠️ Questa opzione viene disabilitata silenziosamente quando vmObfuscation è attivata. Usa invece vmDebugProtection.
Questa opzione rende quasi impossibile utilizzare la funzione debugger degli strumenti per sviluppatori (sia sui browser basati su WebKit sia su Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Può bloccare il browser! Usala a tuo rischio.
⚠️ Questa opzione viene disabilitata silenziosamente quando vmObfuscation è attivata. Usa invece vmDebugProtection.
Se impostata, viene utilizzato un intervallo in millisecondi per forzare la modalità di debug nella scheda Console, rendendo più difficile l'uso di altre funzionalità degli strumenti per sviluppatori. Funziona se debugProtection è attivata. Il valore consigliato è compreso tra 2000 e 4000 millisecondi.
disableConsoleOutput
Type: boolean Default: false
⚠️ Questa opzione disabilita le chiamate console a livello globale per tutti gli script
Disabilita l'uso di console.log, console.info, console.error, console.warn, console.debug, console.exception e console.trace sostituendoli con funzioni vuote. Ciò rende più difficile l'uso del debugger.
domainLock
Type: string[] Default: []
⚠️ Questa opzione non funziona con target: 'node', target: 'service-worker' o target: 'bytenode'
Consente di eseguire il codice sorgente offuscato solo su domini e/o sottodomini specifici. In questo modo diventa davvero difficile per qualcuno copiare e incollare il codice sorgente ed eseguirlo altrove.
Se il codice sorgente non viene eseguito sui domini specificati da questa opzione, il browser verrà reindirizzato all'URL passato all'opzione domainLockRedirectUrl.
Domini e sottodomini multipli
È possibile vincolare il codice a più di un dominio o sottodominio. Ad esempio, per vincolarlo in modo che venga eseguito solo su www.example.com, aggiungi www.example.com. Per farlo funzionare sul dominio radice, inclusi tutti i sottodomini (example.com, sub.example.com), usa .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Questa opzione non funziona con target: 'node', target: 'service-worker' o target: 'bytenode'
Consente di reindirizzare il browser a un URL specificato se il codice sorgente non viene eseguito sui domini indicati da domainLock
exclude
Type: string[] Default: []
Nomi di file o glob che indicano i file da escludere dall'offuscamento.
forceTransformStrings
Type: string[] Default: []
Attiva la trasformazione forzata dei letterali stringa che corrispondono ai pattern RegExp passati.
⚠️ Questa opzione riguarda solo le stringhe che non dovrebbero essere trasformate da stringArrayThreshold (o da eventuali altre soglie in futuro)
L'opzione ha la priorità sull'opzione reservedStrings, ma non sui conditional comments.
Esempio:
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
L'obiettivo principale di questa opzione è la possibilità di usare gli stessi nomi di identificatori durante l'offuscamento di più sorgenti/file.
Attualmente sono supportati due tipi di identificatori:
- Identificatori globali:
- Tutti gli identificatori globali vengono scritti nella cache;
- Tutti gli identificatori globali non dichiarati corrispondenti vengono sostituiti con i valori presenti nella cache.
- Identificatori di proprietà, solo quando l'opzione
renamePropertiesè attivata:- Tutti gli identificatori di proprietà vengono scritti nella cache;
- Tutti gli identificatori di proprietà corrispondenti vengono sostituiti con i valori presenti nella cache.
API Node.js
Se viene passato un valore null, la cache viene disabilitata completamente.
Se viene passato un oggetto vuoto ({}), viene attivata la scrittura dei nomi degli identificatori nell'oggetto cache (tipo TIdentifierNamesCache). A questo oggetto cache si accede tramite la chiamata al metodo getIdentifierNamesCache dell'oggetto ObfuscationResult.
L'oggetto cache risultante può poi essere usato come valore dell'opzione identifierNamesGenerator per utilizzare questi nomi durante l'offuscamento di tutti i nomi di identificatori corrispondenti delle sorgenti successive.
Esempio:
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 dispone di un'opzione diversa --identifier-names-cache-path che consente di definire un percorso al file .json esistente che verrà usato per leggere e scrivere la cache dei nomi degli identificatori.
Se viene passato un percorso a un file vuoto, la cache dei nomi degli identificatori verrà scritta in quel file.
Questo file con la cache esistente può essere riutilizzato come valore dell'opzione --identifier-names-cache-path per utilizzare questi nomi durante l'offuscamento di tutti i nomi di identificatori corrispondenti dei file successivi.
identifierNamesGenerator
Type: string Default: hexadecimal
Imposta il generatore dei nomi degli identificatori.
Valori disponibili:
dictionary: nomi degli identificatori dall'elencoidentifiersDictionaryhexadecimal: nomi degli identificatori come_0xabc123mangled: nomi brevi degli identificatori comea,b,cmangled-shuffled: comemangledma con alfabeto mescolato
identifiersDictionary
Type: string[] Default: []
Imposta il dizionario degli identificatori per l'opzione identifierNamesGenerator: dictionary. Ogni identificatore del dizionario verrà usato in alcune varianti con una diversa combinazione di maiuscole e minuscole per ciascun carattere. Pertanto, il numero di identificatori nel dizionario dovrebbe dipendere dalla quantità di identificatori nel codice sorgente originale.
identifiersPrefix
Type: string Default: ''
Imposta un prefisso per tutti gli identificatori globali.
Usa questa opzione quando vuoi offuscare più file. Questa opzione aiuta a evitare conflitti tra gli identificatori globali di questi file. Il prefisso dovrebbe essere diverso per ogni file.
randomIdentifiersPrefix
Type: boolean Default: false
Aggiunge un prefisso casuale basato su seed (6 caratteri alfanumerici) a tutti gli identificatori globali. Usa questa opzione per evitare collisioni tra bundle offuscati separatamente e caricati nello stesso scope globale: elimina la necessità di scegliere manualmente un identifiersPrefix univoco per ciascun bundle.
- Il valore casuale è derivato dall'opzione
seede dall'hash del codice sorgente, quindi build riproducibili con lo stesso seed producono lo stesso prefisso. - Se combinato con
identifiersPrefix, i caratteri casuali vengono aggiunti al prefisso fornito dall'utente (ad esempiomyApp+ il casualeaBc123→myAppaBc123). - Se combinato con
vmObfuscation, il valore casuale sostituisce il prefissovmpredefinito: la casualità garantisce già l'univocità.
ignoreImports
Type: boolean Default: false
Impedisce l'offuscamento degli import require. Può essere utile in alcuni casi in cui, per qualche motivo, l'ambiente di runtime richiede questi import solo con stringhe statiche.
inputFileName
Type: string Default: ''
Consente di impostare il nome del file di input con il codice sorgente. Questo nome verrà usato internamente per la generazione della source map.
Obbligatorio quando si usa l'API NodeJS e l'opzione sourceMapSourcesMode ha il valore sources.
log
Type: boolean Default: false
Attiva la registrazione delle informazioni nella console.
numbersToExpressions
Type: boolean Default: false
Attiva la conversione dei numeri in espressioni
Esempio:
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Consente di impostare un preset di opzioni.
Valori disponibili:
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.
Tutte le opzioni aggiuntive verranno unite al preset di opzioni selezionato.
parseHtml
Type: boolean Default: false
Attiva l'offuscamento del JavaScript all'interno dei tag HTML <script>.
Quando è attivata, l'offuscatore:
- Rileva automaticamente se l'input è HTML (controllando la presenza di tag
<!DOCTYPE,<html>,<head>,<body>o<script>) - Estrae il JavaScript dai tag
<script>contrassegnati con l'attributodata-javascript-obfuscator - Offusca singolarmente ogni script contrassegnato preservando la struttura HTML
- Reinserisce il codice offuscato nelle posizioni originali
Importante: vengono offuscati solo gli script con l'attributo data-javascript-obfuscator. Ogni script contrassegnato viene offuscato singolarmente e in modo indipendente. Ciò significa che:
- Il codice all'interno dei tag script contrassegnati deve essere isolato: NON deve fare riferimento a variabili, funzioni o classi definite in altri tag script contrassegnati
- Gli script non contrassegnati possono comunque accedere alle variabili globali definite dagli script contrassegnati (tramite dichiarazioni
varo assegnazioni esplicite aglobalThis) - Questo ti dà il controllo esplicito su quali script proteggere
Offuscati (devono avere l'attributo data-javascript-obfuscator):
<script data-javascript-obfuscator>- script normali<script type="text/javascript" data-javascript-obfuscator>- script con tipo esplicito- Script con qualsiasi attributo aggiuntivo (
id,class, altridata-*, ecc.)
Ignorati (lasciati invariati):
- Script senza l'attributo
data-javascript-obfuscator <script type="module">- moduli ES (anche con l'attributo)<script src="...">- script esterni (anche con l'attributo)- Tag script vuoti
Nota: le source map non vengono generate quando parseHtml è attivata, perché non corrisponderebbero correttamente all'output HTML.
Esempio:
// 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
⚠️ questa opzione può compromettere il codice. Attivala solo se sai cosa fa!
Attiva l'offuscamento dei nomi di variabili e funzioni globali con dichiarazione.
Quando questa opzione è disabilitata e il codice di input dichiara funzioni o classi nello scope globale (ovvero il codice non è racchiuso in una IIFE), i loro nomi vengono mantenuti così come sono nell'output offuscato: altri script potrebbero farvi riferimento per nome. Con vmObfuscation viene segnalato un avviso VMGlobalFunctionNamesNotRenamed che elenca questi nomi, poiché il corpo della funzione è nascosto come bytecode ma il nome di primo livello leggibile rivela comunque cosa fa il codice (ad esempio a un LLM). Per evitare questa esposizione, racchiudi il codice in una IIFE oppure attiva questa opzione.
renameProperties
Type: boolean Default: false
⚠️ questa opzione POTREBBE compromettere il codice. Attivala solo se sai cosa fa!
Attiva la rinomina dei nomi delle proprietà. Tutte le proprietà DOM integrate e le proprietà delle classi core di JavaScript verranno ignorate.
Per passare dalla modalità safe a quella unsafe di questa opzione usa l'opzione renamePropertiesMode.
Per impostare il formato dei nomi delle proprietà rinominate usa l'opzione identifierNamesGenerator.
Per controllare quali proprietà verranno rinominate usa l'opzione reservedNames.
Esempio:
// 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
⚠️ Anche in modalità safe, l'opzione renameProperties POTREBBE compromettere il codice.
Specifica la modalità dell'opzione renameProperties:
safe- comportamento predefinito dopo la versione2.11.0. Tenta di rinominare le proprietà in modo più sicuro per prevenire errori di runtime. Con questa modalità alcune proprietà verranno escluse dalla rinomina.unsafe- comportamento predefinito prima della versione2.11.0. Rinomina le proprietà in modo non sicuro senza alcuna restrizione.
Se un file utilizza proprietà provenienti da un altro file, usa l'opzione identifierNamesCache per mantenere gli stessi nomi di proprietà tra questi file.
reservedNames
Type: string[] Default: []
Disabilita l'offuscamento e la generazione degli identificatori che corrispondono ai pattern RegExp passati.
Esempio:
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Disabilita la trasformazione dei letterali stringa che corrispondono ai pattern RegExp passati. Le stringhe corrispondenti rimarranno visibili nell'output offuscato.
Quando si usa l'offuscamento VM, le stringhe riservate vengono memorizzate in un array separato non crittografato per mantenerle visibili. Questo è utile per le stringhe che devono rimanere leggibili, come gli endpoint API per il monitoraggio o gli identificatori di librerie.
Esempio:
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Questa opzione imposta il seed per il generatore casuale. È utile per creare risultati ripetibili.
Se il seed è 0, il generatore casuale funzionerà senza seed.
selfDefending
Type: boolean Default: false
⚠️ Non modificare in alcun modo il codice offuscato dopo l'offuscamento con questa opzione, perché qualsiasi modifica, come la minificazione del codice, può attivare l'autodifesa e il codice smetterà di funzionare!
⚠️ Questa opzione imposta forzatamente il valore di compact su true
⚠️ Questa opzione viene disabilitata silenziosamente quando vmObfuscation è attivata. Usa invece vmSelfDefending.
Questa opzione rende il codice di output resistente alla formattazione e alla rinomina delle variabili. Se si prova a usare un beautifier JavaScript sul codice offuscato, il codice smetterà di funzionare, rendendone più difficile la comprensione e la modifica.
simplify
Type: boolean Default: true
Attiva un ulteriore offuscamento del codice tramite semplificazione.
⚠️ nelle versioni future l'offuscamento dei letterali boolean (true => !![]) verrà spostato sotto questa opzione.
Esempio:
// 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
Attiva la generazione della source map per il codice offuscato.
Le source map possono essere utili per eseguire il debug del codice sorgente JavaScript offuscato. Se vuoi o hai bisogno di eseguire il debug in produzione, puoi caricare il file della source map separato in una posizione segreta e poi puntare il browser a quella posizione.
sourceMapBaseUrl
Type: string Default: ``
Imposta l'URL di base per l'URL di importazione della source map quando sourceMapMode: 'separate'.
Esempio CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Risultato:
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Imposta il nome del file per la source map di output quando sourceMapMode: 'separate'.
Esempio CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Risultato:
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Specifica la modalità di generazione della source map:
inline- aggiunge la source map alla fine di ogni file .js;separate- genera il corrispondente file '.map' con la source map. Nel caso in cui l'offuscatore venga eseguito tramite CLI, aggiunge un collegamento al file della source map alla fine del file con il codice offuscato//# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Consente di controllare i campi sources e sourcesContent della source map:
sources-content- aggiunge un camposourcesfittizio, aggiunge il camposourcesContentcon il codice sorgente originale;sources- aggiunge il camposourcescon una descrizione della sorgente valida, non aggiunge il camposourcesContent. Quando si usa l'API NodeJS è necessario definire l'opzioneinputFileNameche verrà usata come valore del camposources.
splitStrings
Type: boolean Default: false
Suddivide i letterali stringa in blocchi con lunghezza pari al valore dell'opzione splitStringsChunkLength.
Esempio:
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Imposta la lunghezza dei blocchi dell'opzione splitStrings.
stringArray
Type: boolean Default: true
Rimuove i letterali stringa e li colloca in un array speciale. Ad esempio, la stringa "Hello World" in var m = "Hello World"; verrà sostituita con qualcosa come var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ l'opzione stringArray deve essere attivata
Attiva la trasformazione delle chiamate a stringArray. Tutti gli argomenti di queste chiamate possono essere estratti in un oggetto diverso a seconda del valore di stringArrayCallsTransformThreshold.
In questo modo diventa ancora più difficile individuare automaticamente le chiamate all'array di stringhe.
Esempio:
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
⚠️ le opzioni stringArray e stringArrayCallsTransformThreshold devono essere attivate
Puoi usare questa impostazione per regolare la probabilità (da 0 a 1) che le chiamate all'array di stringhe vengano trasformate.
stringArrayEncoding
Type: string[] Default: []
⚠️ l'opzione stringArray deve essere attivata
Questa opzione può rallentare lo script.
Codifica tutti i letterali stringa di stringArray usando base64 o rc4 e inserisce un codice speciale che serve a decodificarli nuovamente a runtime.
Ogni valore di stringArray verrà codificato con la codifica scelta casualmente dall'elenco passato. Ciò rende possibile l'uso di più codifiche.
Valori disponibili:
'none'(boolean): non codifica il valore distringArray'base64'(string): codifica il valore distringArrayusandobase64'rc4'(string): codifica il valore distringArrayusandorc4. Circa il 30-50% più lento dibase64, ma rende più difficile ottenere i valori iniziali.
Ad esempio, con i seguenti valori delle opzioni alcuni valori di stringArray non verranno codificati, mentre altri verranno codificati con le codifiche base64 e rc4:
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ l'opzione stringArray deve essere attivata
Consente di controllare il tipo degli indici delle chiamate all'array di stringhe.
Ogni indice di chiamata di stringArray verrà trasformato con il tipo scelto casualmente dall'elenco passato. Ciò rende possibile l'uso di più tipi.
Valori disponibili:
'hexadecimal-number'(default): trasforma gli indici delle chiamate all'array di stringhe come numeri esadecimali'hexadecimal-numeric-string': trasforma gli indici delle chiamate all'array di stringhe come stringa numerica esadecimale
Prima della versione 2.9.0, javascript-obfuscator trasformava tutti gli indici delle chiamate all'array di stringhe con il tipo hexadecimal-numeric-string. Ciò rende leggermente più difficile una parte della deoffuscazione manuale, ma consente ai deoffuscatori automatici di individuare facilmente queste chiamate.
Il nuovo tipo hexadecimal-number mira a rendere più difficile il rilevamento automatico dei pattern delle chiamate all'array di stringhe nel codice.
In futuro verranno aggiunti altri tipi.
stringArrayIndexShift
Type: boolean Default: true
⚠️ l'opzione stringArray deve essere attivata
Attiva uno spostamento aggiuntivo dell'indice per tutte le chiamate all'array di stringhe
stringArrayRotate
Type: boolean Default: true
⚠️ stringArray deve essere attivata
Sposta l'array stringArray di un numero fisso e casuale (generato durante l'offuscamento del codice) di posizioni. In questo modo diventa più difficile far corrispondere l'ordine delle stringhe rimosse alla loro posizione originale.
stringArrayShuffle
Type: boolean Default: true
⚠️ stringArray deve essere attivata
Mescola casualmente gli elementi dell'array stringArray.
stringArrayWrappersCount
Type: number Default: 1
⚠️ l'opzione stringArray deve essere attivata
Imposta il numero di wrapper per lo string array all'interno di ciascuno scope radice o di funzione.
Il numero effettivo di wrapper all'interno di ciascuno scope è limitato dal numero di nodi literal presenti in quello scope.
Esempio:
// 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
⚠️ le opzioni stringArray e stringArrayWrappersCount devono essere attivate
Attiva le chiamate concatenate tra i wrapper dello string array.
Esempio:
// 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'opzione stringArray deve essere attivata
⚠️ Attualmente questa opzione riguarda solo i wrapper aggiunti dal valore function dell'opzione stringArrayWrappersType
Consente di controllare il numero massimo di parametri dei wrapper dell'array di stringhe.
Il valore predefinito e minimo è 2. Valore consigliato tra 2 e 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ le opzioni stringArray e stringArrayWrappersCount devono essere attivate
Consente di selezionare il tipo di wrapper aggiunti dall'opzione stringArrayWrappersCount.
Valori disponibili:
'variable': aggiunge wrapper di variabili all'inizio di ciascuno scope. Prestazioni veloci.'function': aggiunge wrapper di funzioni in posizioni casuali all'interno di ciascuno scope. Prestazioni più lente rispetto avariable, ma fornisce un offuscamento più rigoroso.
È altamente consigliato usare i wrapper function per un offuscamento più elevato quando una perdita di prestazioni non ha un forte impatto sull'applicazione offuscata.
Esempio del valore dell'opzione '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'opzione stringArray deve essere attivata
Puoi usare questa impostazione per regolare la probabilità (da 0 a 1) che un letterale stringa venga inserito nello stringArray.
Questa impostazione è particolarmente utile per basi di codice di grandi dimensioni, perché richiama ripetutamente lo string array e può rallentare il codice.
stringArrayThreshold: 0 equivale a stringArray: false.
strictMode
Type: boolean | null Default: null
Consente di specificare come l'offuscatore deve trattare il codice rispetto alla modalità strict di JavaScript.
Valori disponibili:
null(default) - rileva automaticamente la modalità strict dal codice. Se il codice contiene una direttiva'use strict'esplicita, sintassi di modulo ES o metodi di classe, viene trattato come modalità strict. Altrimenti si assume la modalità sloppy.true- forza il trattamento in modalità strict per tutto il codice, anche senza una direttiva'use strict'esplicita. Usalo quando il codice verrà eseguito in un contesto in modalità strict (ad esempio in moduli ES, bundler o framework moderni).false- solo gli indicatori espliciti della modalità strict ('use strict', moduli ES, metodi di classe) vengono trattati come strict. L'ereditarietà dallo scope padre si applica comunque secondo la specifica JS.
target
Type: string Default: browser
Consente di impostare l'ambiente di destinazione per il codice offuscato.
Valori disponibili:
browser(default) — ambiente standard di una pagina web. Il codice di output è identico anode, ma alcune opzioni specifiche del browser non possono essere usate con il targetnodebrowser-no-eval— comebrowser, ma l'output non usaeval(). Usalo quando la pagina di destinazione ha una Content Security Policy che vietaeval/unsafe-eval.node— ambiente Node.js. Le opzioni specifiche del browser sono disabilitate (richiedonowindow/documente in Node non avrebbero effetto o genererebbero un errore). Alcune difesevmSelfDefendingche si basano su API disponibili solo nel browser — rilevamento dei browser headless, ripristino tramite realm pulito basato su iframe, controlli anti-inspector/DOM — non vengono emesse per questo target.service-worker— contesto Service Worker. Nessunwindow, nessundocument, un diverso globaleself.userscript— sandbox di un gestore di userscript (ad esempio Tampermonkey). Le difesevmSelfDefendingvengono adattate di conseguenza.bytenode— codice Node.js che verrà compilato con il loader bytenode (bytecode V8 memorizzato nella cache.jsc) dopo l'offuscamento. L'offuscatore stesso non richiamabytenode; emette JavaScript offuscato tramite VM il cui runtime è strutturato per resistere alla fase di compilazione di bytenode, e le difesevmSelfDefendingvengono adattate di conseguenza. Esegui tu stessobytenodesull'output offuscato per produrre il file.jscfinale.
transformObjectKeys
Type: boolean Default: false
Attiva la trasformazione delle chiavi degli oggetti.
Esempio:
// 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
Controlla quali avvisi di offuscamento non fatali vengono emessi tramite il metodo ObfuscationResult.getWarnings().
Valori disponibili:
'all'(default) — viene emesso ogni avviso.'none'— tutti gli avvisi vengono soppressi.- un oggetto che associa i tipi di avviso a valori booleani — un tipo associato a
falseviene soppresso; ogni tipo non presente (o associato atrue) rimane attivo. Ad esempio,{ "VMGlobalFunctionNamesNotRenamed": false }mantiene ogni avviso tranne quello.
Tipi di avviso:
VMGlobalFunctionNamesNotRenamed— convmObfuscation, i nomi delle dichiarazioni di funzione di primo livello, delle dichiarazioni di classe e delle variabili a cui è assegnata un'espressione di funzione/arrow/classe sono stati mantenuti così come sono (l'opzionerenameGlobalsè disabilitata e il codice non è racchiuso in una IIFE), quindi rimangono leggibili nell'output anche se i corpi sono nascosti come bytecode. I nomi esportati non vengono segnalati.VMTopLevelInitializerNotVirtualized— gli inizializzatori delle variabili di primo livello sono rimasti in JavaScript in chiaro con l'offuscamento VM perchévmWrapTopLevelInitializersè disabilitata o non è riuscita a virtualizzarli.DynamicCodeRenameRisk— il codice costruisce una funzione da una stringa a runtime (evaldiretto, il costruttoreFunctionofn.toString()iniettato in uno<script>/Worker), che potrebbe fare riferimento a identificatori rinominati dall'offuscatore.VMDynamicCodeSkipped— una funzione è stata esclusa dalla conversione in bytecode VM perché contieneevaldiretto /new Functiondinamico /Function(vedivmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— convmAsyncExecutorattivata, una funzione che hai contrassegnato esplicitamente in modalitàcommentè risultata sincrona ed è stata saltata (in quella modalità vengono virtualizzate solo le funzioni async).VMAsyncGeneratorSkippedInAsyncMode— convmAsyncExecutore un getter di chiave async attivo, un generatore async contrassegnato non è stato virtualizzato (deve restituire il suo iteratore in modo sincrono).BrowserTargetWithNodeStyleCode— il codice sembra destinato a Node.js (ad esempiorequire('fs'),__dirname,process.argv) mentre l'opzionetargetè impostata su un ambiente di tipo browser.
vmObfuscation
Type: boolean Default: false
Attiva l'offuscamento basato su bytecode VM. Quando è attivata, le funzioni JavaScript vengono compilate in bytecode personalizzato eseguito da una macchina virtuale integrata. Questo fornisce il massimo livello di protezione, poiché la logica del codice originale viene completamente trasformata.
Esempio:
Il tuo codice leggibile come return qty * price diventa un elenco di numeri come [0x15,0x03,0x17,...] che solo l'interprete VM integrato può eseguire. La logica originale non è più visibile come JavaScript.
vmTargetFunctions
Type: string[] Default: []
Specifica esattamente quali funzioni di primo livello devono ricevere la protezione VM, per nome.
Esempio:
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Risultato: solo queste tre funzioni ricevono la protezione VM. Tutto il resto rimane come JavaScript normale (ma comunque offuscato). Perfetto per proteggere controlli di licenza sensibili o logiche di autenticazione mantenendo snello il resto del codice.
vmExcludeFunctions
Type: string[] Default: []
Specifica le funzioni di primo livello che non devono mai ricevere la protezione VM. Ha la precedenza sulle altre impostazioni.
Esempio:
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Quando usarla: le funzioni di primo livello critiche per le prestazioni (loop di animazione, elaborazione di dati in tempo reale) possono essere escluse per evitare l'overhead della VM proteggendo comunque tutto il resto.
vmTargetFunctionsMode
Type: string Default: root
Controlla come le funzioni/i metodi vengono selezionati per l'offuscamento VM.
Esempio - Modalità 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'
}
Quando usarla: quando hai bisogno di un controllo chirurgico su esattamente quali funzioni ricevono la protezione VM, in particolare per funzioni annidate che contengono logica sensibile. A differenza di vmTargetFunctions, che funziona solo con funzioni denominate di primo livello, la modalità comment ti consente di proteggere qualsiasi funzione in qualsiasi punto del codice.
vmForceCompileDynamicCode
Type: boolean Default: false
Controlla cosa fa l'offuscamento VM con una funzione che contiene una chiamata eval diretta, new Function(...) o Function(...).
Per impostazione predefinita, tale funzione (e ogni funzione definita al suo interno) viene esclusa dalla conversione in bytecode VM e viene segnalato un avviso VMDynamicCodeSkipped in result.getWarnings(). Questo perché il codice sorgente costruito a runtime potrebbe fare riferimento a identificatori della catena di scope circostante — identificatori che l'offuscatore ha rinominato.
Se impostata su true, la funzione viene comunque convertita in bytecode e l'avviso VMDynamicCodeSkipped non viene più emesso.
L'avviso separato DynamicCodeRenameRisk continua a essere emesso indipendentemente da questa opzione, perché il rischio di rinomina che descrive è indipendente dall'esclusione dalla VM: attivare questa opzione non rende più sicuro il pattern sottostante.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
Con l'opzione disattivata (impostazione predefinita), loadConfig viene lasciata come JavaScript in chiaro. Con l'opzione attivata, loadConfig viene compilata in bytecode VM come qualsiasi altra funzione. Usala quando hai verificato il punto di chiamata e sai che il codice costruito a runtime non dipende da identificatori rinominati nella closure.
vmWrapTopLevelInitializers
Type: boolean Default: false
Racchiude alcuni inizializzatori di variabili di primo livello in IIFE (Immediately Invoked Function Expressions) affinché possano essere offuscati tramite VM.
Cosa fa: Senza questa opzione, le costanti e le variabili di primo livello rimangono visibili nell'output:
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
Con questa opzione attivata, l'inizializzatore viene racchiuso in una IIFE che viene offuscata tramite VM:
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Nota: questa opzione funziona solo quando vmTargetFunctionsMode è 'root' (impostazione predefinita).
Avvisi: ogni volta che un inizializzatore di primo livello rimane in JavaScript in chiaro con l'offuscamento VM, viene segnalato un avviso VMTopLevelInitializerNotVirtualized che elenca i nomi delle variabili interessate. Ciò comprende: questa opzione disabilitata, gli inizializzatori che questa opzione ha dovuto saltare (ciascuno con il motivo — ad esempio l'inizializzatore fa riferimento a un declaratore di pari livello o contiene await di primo livello) e la modalità vmAsyncExecutor, in cui i wrapper sincroni non possono essere virtualizzati affatto.
vmDynamicOpcodes
Type: boolean Default: false
Rende l'interprete VM più piccolo e unico per ogni build.
Cosa fa:
- Filtra le istruzioni inutilizzate - Se il codice non usa le classi, le istruzioni relative alle classi vengono rimosse completamente
- Randomizza la struttura - L'ordine dei gestori delle istruzioni viene mescolato a ogni build
Il risultato è un output più piccolo e ogni build ha un aspetto diverso.
vmBytecodeEncoding
Type: boolean Default: false
Codifica ogni istruzione del bytecode. Le istruzioni vengono decodificate una alla volta durante l'esecuzione.
vmBytecodeArrayEncoding
Type: boolean Default: false
Codifica l'intero array di bytecode come un unico blocco. L'array viene decodificato una sola volta all'avvio, prima che inizi l'esecuzione. Usala insieme a vmBytecodeEncoding per due livelli di protezione.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Chiave di crittografia personalizzata per la codifica dell'array di bytecode. Quando è impostata, viene usata questa chiave al posto di quella predefinita derivata dall'ambiente. La chiave deve essere fornita a runtime tramite vmBytecodeArrayEncodingKeyGetter.
Questa opzione esternalizza la chiave di crittografia: non viene incorporata nel codice offuscato stesso. Sebbene la chiave sia comunque accessibile a runtime (e quindi non sia veramente segreta), questa separazione impedisce agli strumenti di analisi statica di individuare la chiave esaminando il solo codice.
Importante: la chiave deve essere disponibile in modo sincrono quando il codice offuscato viene caricato. Usa un archivio sincrono come cookie, localStorage, sessionStorage, variabili globali o elementi DOM (ad esempio meta tag iniettati dal server). Metodi asincroni come fetch() non possono essere usati direttamente nell'espressione del key getter.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Espressione JavaScript sincrona che restituisce la chiave di crittografia a runtime. Questa espressione viene valutata quando il codice offuscato viene caricato e deve restituire la stessa chiave fornita in vmBytecodeArrayEncodingKey. Per risolvere la chiave in modo asincrono (una Promise), attiva vmAsyncExecutor.
Nota: un getter che restituisce una Promise richiede vmAsyncExecutor. Questo non può essere verificato in fase di build, quindi un getter con Promise e vmAsyncExecutor disattivato fallisce a runtime: il decodificatore riceve la Promise invece della chiave.
Il codice offuscato funzionerà solo quando il key getter restituisce esattamente la stessa chiave usata durante l'offuscamento. Se le chiavi non corrispondono, la decrittazione fallirà e il codice produrrà risultati privi di senso o errori. Se il key getter restituisce undefined, null o una stringa vuota, il codice genererà un errore: "VM decryption key not available".
Importante: tieni la chiave fuori dallo stesso file/script del codice offuscato: incorporarla lì consente di recuperarla anche con una scansione puramente statica del bundle. Memorizzala invece in una sorgente separata: cookie impostati dal server, localStorage popolato da un altro script, un meta tag HTML iniettato dal server, una variabile globale impostata da uno script diverso oppure (con vmAsyncExecutor) recuperata dal tuo backend a runtime.
Quando la chiave viene recuperata dal tuo backend (tramite vmAsyncExecutor), aggiungi a quell'endpoint controlli basati sulla sessione o sull'origine: restituisci la chiave corretta agli utenti reali (sessione valida, Origin/Referer previsti) e una chiave priva di senso alle richieste sospette (ad esempio un'origine localhost/inattesa, nessuna sessione). Gli utenti reali eseguono il codice normalmente; una copia eseguita al di fuori del tuo ambiente ottiene una chiave che non decritta nulla. La logica esatta dipende dal tuo sito.
Esempi:
// 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())'
Esempio di utilizzo:
// 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
Attiva l'executor VM asincrono, che consente a vmBytecodeArrayEncodingKeyGetter di restituire una Promise (un key getter asincrono): in questo modo la chiave di decrittazione può essere recuperata a runtime (richiesta di rete, IndexedDB, ecc.) invece di dover essere disponibile in modo sincrono quando il codice viene caricato.
Fortemente consigliato per basi di codice completamente async. In questa modalità vengono virtualizzate solo le funzioni async — una funzione sincrona non può essere resa async senza trasformare il suo valore di ritorno in una Promise e compromettere i suoi chiamanti — quindi il codice interamente async ottiene la massima copertura. Funziona comunque quando la radice è sincrona (ad esempio una IIFE sincrona / wrapper UMD): le funzioni async più esterne al suo interno sono protette e le parti sincrone vengono lasciate invariate.
Cosa viene trasformato: ogni funzione async più esterna, ovunque compaia (anche annidata all'interno di wrapper sincroni). L'async più esterna di ogni catena è l'unità protetta: tutto ciò che si trova al suo interno, sincrono e async, viene compilato. Le funzioni sincrone e i generatori semplici vengono lasciati non offuscati.
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
}
}
Esclusioni e avvisi. Anche i generatori async vengono lasciati non offuscati quando è attivo un key getter asincrono (un generatore async deve restituire il suo iteratore in modo sincrono e non può attendere la chiave). Nella modalità predefinita vmTargetFunctionsMode: 'root' le esclusioni sono silenziose (la selezione è automatica); nella modalità comment viene emesso un avviso tramite ObfuscationResult.getWarnings() ogni volta che una funzione che hai contrassegnato esplicitamente non può essere virtualizzata — è risultata sincrona oppure è un generatore async sotto un key getter asincrono.
Il key getter asincrono richiede inoltre vmBytecodeArrayEncoding con un vmBytecodeArrayEncodingKeyGetter.
Esempio di utilizzo:
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
Codifica le destinazioni dei salti nel bytecode. Gli offset dei salti vengono calcolati a runtime, nascondendo la struttura del flusso di controllo (if/else, cicli, ecc.) all'analisi statica.
vmMacroOps
Type: boolean Default: false
Combina sequenze di istruzioni comuni in singoli opcode "macro". Ad esempio, LOAD + ADD + STORE potrebbe diventare un'unica istruzione MACRO_ADD_TO_VAR. Questo interrompe il riconoscimento dei pattern e può migliorare le prestazioni.
vmDebugProtection
Type: boolean Default: false
Aggiunge al runtime VM difese multilivello anti-debug, anti-analisi e anti-LLM. Funziona al meglio con i target browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Aggiunge al runtime VM una protezione multilivello di rilevamento delle manomissioni, anti-hooking e anti-reverse-engineering.
⚠️ Questa opzione attiva forzatamente vmBytecodeArrayEncoding.
⚠️ Rilevamento di ambienti sensibili. Questa opzione vincola il codice offuscato al suo ambiente di runtime di destinazione e usa un fingerprinting avanzato del browser per rilevare gli strumenti di automazione. Il codice protetto con questa opzione si interromperà intenzionalmente quando viene eseguito in:
- Browser headless (Chrome/Chromium headless, PhantomJS)
- Strumenti di automazione del browser (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (quando
targetè impostato subrowser) - jsdom o emulazioni DOM lato server simili
- Ambienti in cui le funzioni native integrate del browser sono state intercettate o sostituite
Il codice funzionerà correttamente nei browser normali (Chrome, Firefox, Safari, Edge), anche quando viene caricato all'interno di iframe, estensioni del browser (content script) e Web Worker. Se hai bisogno di eseguire test automatizzati sul codice protetto, disabilita vmSelfDefending per le build di test: questa opzione è progettata per impedire l'analisi automatizzata e non può essere usata in sicurezza con alcun framework di automazione.
Fortemente consigliato l'uso insieme a vmDebugProtection, vmBytecodeArrayEncodingKey e vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook accetta un oggetto con due chiavi: name (obbligatoria) e aliases (facoltativa).
name è una funzione globale definita dalla tua pagina host che una difesa VM (vmDebugProtection / vmSelfDefending) chiama con un oggetto segnale quando rileva un segnale ostile — un debugger o un inspector, un browser headless / di automazione, un processo di AI-coding-agent, un dominio non consentito e così via. Usala per segnalare l'evento al tuo backend (ad esempio navigator.sendBeacon). L'hook è un puro raccoglitore di telemetria: il suo valore di ritorno viene ignorato e un hook mancante o che genera un'eccezione è un no-op silenzioso che non può mai disabilitare una difesa. Per modificare ciò che una difesa fa al momento del rilevamento, usa vmDefenseReaction.
aliases rinomina facoltativamente i campi di quell'oggetto segnale — descritto più avanti in Rinominare i campi del segnale.
L'oggetto segnale. L'hook riceve un unico signal:
source— il rilevatore specifico che si è attivato (vedi la tabella).category— il gruppo sotto cui viene segnalato:automation(browser non umani),debugger(è attivo un debugger/inspector),sandbox(host strumentato/fittizio),domain(violazione del domain-lock),tamper(funzioni integrate modificate a runtime) ointegrity(il codice della VM stessa è stato alterato).score/threshold— con quanta forza si è attivato il rilevatore e il valore che doveva raggiungere; l'hook si attiva solo quandoscore >= threshold. La maggior parte dei controlli è tutto-o-niente (un singolo segnale decisivo);headlesssomma diversi segnali relativi alla conformazione del browser, quindi il suoscoreè tipicamente più alto del suothreshold.
Registrare l'hook. Definiscilo come una semplice variabile globale prima che il bundle offuscato venga caricato — il runtime VM e le sue difese vengono eseguiti prima del tuo programma (protetto), quindi molti rilevamenti si attivano durante l'avvio:
// 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 definito all'interno del codice sorgente offuscato viene registrato troppo tardi per intercettare i rilevamenti al momento dell'avvio e, se viene compilato dalla VM, non è raggiungibile finché il tuo programma non viene eseguito. In ogni caso rimane sicuro (un hook mancante è un no-op e una protezione contro la rientranza impedisce qualsiasi loop incontrollato), ma per una copertura completa registralo in anticipo. Per proteggere comunque la tua logica di segnalazione, mantieni l'hook registrato come un buffer di una sola riga ((window.__vmDet = window.__vmDet || []).push(signal)) e leggi/invia quel buffer dal tuo codice offuscato.
Rinominare i campi del segnale (aliases). I valori predefiniti source/category sono nomi descrittivi, quindi chiunque strumenti il callback (o legga l'output) può riconoscere la protezione e quale rilevatore si è attivato. aliases rinomina i campi del segnale con token opachi a tua scelta, applicati all'interno della VM prima che il segnale venga emesso, così quei nomi non compaiono mai nell'output né raggiungono il callback. La tua applicazione conosce la propria mappatura e inoltra i token al tuo backend.
Gli alias sono per campo e mantengono separate le rinomine di chiavi e valori: ogni campo accetta una key (il nome della proprietà che riceve il callback); i campi-nome di tipo stringa source e category accettano anche una mappa values, mentre score/threshold sono numeri e accettano solo una key. I nomi che puoi mappare (qualsiasi altro viene rifiutato in fase di build):
- chiavi dei campi —
source,category,score,threshold - valori di
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - valori di
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> }
}
Questa è elusione del fingerprint, non segretezza — la mappatura può comunque essere dedotta con test ripetuti — quindi il suo unico vantaggio è non esporre nomi stabili e autoesplicativi. Le voci non impostate mantengono i loro nomi predefiniti.
Una semplice stringa (vmDefenseHook: '__vmDetection') è accettata come forma abbreviata di { name: '__vmDetection' } ma è deprecata — preferisci la forma a oggetto.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Configura come reagisce ciascuna categoria di rilevamento. Non attiva nulla: le difese stesse vengono attivate da vmSelfDefending, vmDebugProtection e vmDomainLock; questa opzione seleziona soltanto come reagisce una difesa attivata. La categoria è l'unità di controllo: ogni rilevatore di una categoria mette in atto la reazione di quella categoria.
Ogni categoria raggruppa i rilevatori che sorvegliano un tipo di condizione ostile. Una categoria reagisce solo quando l'opzione che emette i suoi rilevatori è attivata:
Ogni categoria è associata a una o più di vmSelfDefending, vmDebugProtection e vmDomainLock; non esiste alcuna categoria al di fuori di queste tre opzioni e una reazione impostata per una categoria la cui opzione è disattivata semplicemente non ha effetto.
Le chiavi sono questi sei nomi di categoria, oppure default (un fallback per le categorie non specificate). I valori sono:
break— interrompi immediatamentedecoy— continua l'esecuzione su uno stato avvelenato, producendo silenziosamente risultati erratinone— non fare nulla localmente (solo telemetria)
I valori predefiniti per categoria sono mostrati sopra; una categoria che non imposti (o che imposti sul suo valore predefinito) usa quel valore predefinito. default raggiunge ogni categoria, incluse quelle corrette per costruzione (integrity, tamper), quindi { default: 'none' } è una build davvero non interruttiva, di sola telemetria:
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
Fa dipendere il significato degli opcode dalla posizione nel bytecode. Ogni posizione ha una diversa mappatura opcode-gestore derivata da un seed, quindi lo stesso numero di opcode esegue operazioni diverse in posizioni diverse.
vmCallContextOpcodes
Type: boolean Default: false
Fa dipendere una funzione protetta dal punto in cui viene chiamata, così da non poter essere estratta dal codice ed eseguita o analizzata autonomamente: si comporta correttamente solo quando viene invocata tramite i suoi reali punti di chiamata nel programma. Questa opzione incide sulle prestazioni a runtime.
Attualmente sono supportate solo le seguenti costruzioni:
- dichiarazioni di funzione (
function f() {}); - espressioni di funzione e arrow function assegnate a una variabile (
const f = () => {}); - metodi privati di istanza (
this.#m()).
In ogni caso la funzione deve sempre essere raggiunta tramite una chiamata diretta (f(), this.#m()). Se viene memorizzata in un'altra variabile, passata come argomento o comunque usata come valore, viene lasciata non protetta. Le funzioni async sono supportate; i generatori no.
Questa opzione è sperimentale e potrebbe compromettere il codice, quindi testa a fondo l'output prima di usarla.
vmStackEncoding
Type: boolean Default: false
Crittografa i valori nello stack della VM durante l'esecuzione. I valori vengono codificati quando vengono inseriti (push) e decodificati quando vengono estratti (pop), così l'ispezione della memoria mostra dati crittografati invece dei valori effettivi.
Questa opzione incide pesantemente sulle prestazioni.
vmCompactDispatcher
Type: boolean Default: false
Usa un unico executor VM invece di due executor (sync + generator). Riduce le dimensioni del codice offuscato ma aggiunge un overhead sulle prestazioni di circa il 20% sul codice con molta ricorsione.
false(default): due executor — prestazioni ottimali, output più grandetrue: executor singolo — output più piccolo, leggermente più lento
vmStringArrayBytecodeOnly
Type: boolean Default: false
Quando è attivata, l'array di stringhe estrarrà solo le stringhe dai dati del bytecode — nessun'altra stringa nel codice viene trasformata. Questo attiva forzatamente stringArray anche se non è impostata esplicitamente.
Perché usarla: estrarre tutte le stringhe di runtime della VM in un array di stringhe è lento. Questa opzione mira solo al contenuto del bytecode per l'estrazione nell'array di stringhe, migliorando le prestazioni pur proteggendo comunque le costanti del bytecode.
- Quando
vmBytecodeArrayEncoding: false— vengono estratte le stringhe all'interno dei constant pool del bytecode (arrayc) - Quando
vmBytecodeArrayEncoding: true— vengono estratte le stringhe di bytecode codificate in base64 di primo livello stringArrayThresholdcontrolla comunque quale percentuale di quelle stringhe di bytecode viene estratta
vmDomainLock
Type: string[] Default: []
⚠️ Questa opzione non funziona con target: 'node', target: 'service-worker' o target: 'bytenode'
Limita il codice offuscato a domini e/o sottodomini specifici ed è molto più difficile da individuare e rimuovere rispetto a domainLock.
Se il codice sorgente non viene eseguito sui domini specificati da questa opzione, il browser verrà reindirizzato all'URL passato a vmDomainLockRedirectUrl e le successive chiamate protette restituiranno risultati errati anche se il reindirizzamento viene soppresso.
Domini e sottodomini multipli
È possibile vincolare il codice a più di un dominio o sottodominio. Ad esempio, per vincolarlo in modo che venga eseguito solo su www.example.com, aggiungi www.example.com. Per farlo funzionare sul dominio radice, inclusi tutti i sottodomini (example.com, sub.example.com), usa .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Questa opzione non funziona con target: 'node', target: 'service-worker' o target: 'bytenode'
Consente di reindirizzare il browser a un URL specificato se il codice sorgente non viene eseguito sui domini indicati da vmDomainLock.
Preset Options
Offuscamento elevato, prestazioni basse
Le prestazioni saranno molto più lente rispetto al codice non offuscato
{
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
}
Offuscamento medio, prestazioni ottimali
Le prestazioni saranno più lente rispetto al codice non offuscato
{
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
}
Offuscamento basso, prestazioni elevate
Le prestazioni si manterranno a un livello relativamente normale
{
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
}
Preset predefinito, prestazioni elevate
{
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
}
Offuscamento VM Ultra High (sicurezza massima)
Questo preset attiva l'offuscamento basato su bytecode VM con tutte le funzionalità di hardening, incluso il dispatch indiretto. Fornisce la protezione più forte ma con dimensioni di output maggiori ed esecuzione molto più lenta.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Oppure configuralo singolarmente:
{
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 (protezione dagli agenti IA)
Questo preset è progettato specificamente per impedire agli agenti IA e agli LLM di applicare il reverse engineering al codice trasformato in bytecode VM. Basato su vm-default con autodifesa e protezione del debug attivate. Più leggero di vm-high-obfuscation ma specificamente rafforzato contro l'analisi automatizzata.
{
optionsPreset: 'vm-anti-llm'
}
Include:
- Offuscamento con bytecode VM con array di stringhe (da
vm-default) vmSelfDefending— rilevamento anti-hook, hash di integrità, fingerprint del sorgente, verifica del realm pulito tramite iframe, derivazione della chiave con cifrario ARXvmDebugProtection— controlli anti-debug nel ciclo di dispatch della VMdebugProtection: false— nessuna protezione del debug legacy (la protezione del debug della VM è superiore)
Offuscamento VM High (sicurezza più elevata)
Questo preset attiva l'offuscamento basato su bytecode VM con la maggior parte delle funzionalità di hardening. Fornisce una protezione forte con prestazioni migliori rispetto al preset ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Oppure configuralo singolarmente:
{
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
}
Offuscamento VM Medium (sicurezza bilanciata)
Questo preset attiva l'offuscamento basato su bytecode VM con un insieme bilanciato di funzionalità di hardening. Buon compromesso tra sicurezza e prestazioni.
{
optionsPreset: 'vm-medium-obfuscation'
}
Oppure configuralo singolarmente:
{
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
}
Offuscamento VM Low (sicurezza di base, prestazioni migliori)
Questo preset attiva un offuscamento di base basato su bytecode VM senza funzionalità di hardening aggiuntive. Buon equilibrio tra sicurezza e dimensioni dell'output.
{
optionsPreset: 'vm-low-obfuscation'
}
Oppure configuralo singolarmente:
{
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 + protezione con array di stringhe)
Questo preset combina un offuscamento di base basato su bytecode VM con la protezione dell'array di stringhe. Buon punto di partenza per l'offuscamento VM con protezione delle stringhe.
{
optionsPreset: 'vm-default'
}
Oppure configuralo singolarmente:
{
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
Comprime il codice di output su un'unica riga.
config
Type: string Default: ``
Nome del file di configurazione JS/JSON che contiene le opzioni dell'offuscatore. Queste vengono sovrascritte dalle opzioni passate direttamente alla CLI
controlFlowFlattening
Type: boolean Default: false
⚠️ Questa opzione incide notevolmente sulle prestazioni, con una velocità di esecuzione fino a 1,5 volte più lenta. Usa controlFlowFlatteningThreshold per impostare la percentuale di nodi interessati dall'appiattimento del flusso di controllo.
Attiva l'appiattimento del flusso di controllo del codice. L'appiattimento del flusso di controllo è una trasformazione della struttura del codice sorgente che ostacola la comprensione del programma.
Esempio:
// 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
La probabilità che la trasformazione controlFlowFlattening venga applicata a un determinato nodo.
Questa impostazione è particolarmente utile per basi di codice di grandi dimensioni, poiché un elevato numero di trasformazioni del flusso di controllo può rallentare il codice e aumentarne le dimensioni.
controlFlowFlatteningThreshold: 0 equivale a controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Aumenta drasticamente le dimensioni del codice offuscato (fino al 200%); usala solo se le dimensioni del codice offuscato non sono un problema. Usa deadCodeInjectionThreshold per impostare la percentuale di nodi interessati dall'iniezione di dead code.
⚠️ Questa opzione attiva forzatamente l'opzione stringArray.
⚠️ Questa opzione viene disabilitata silenziosamente quando vmObfuscation è attivata.
Con questa opzione, al codice offuscato vengono aggiunti blocchi casuali di dead code.
Esempio:
// 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
Consente di impostare la percentuale di nodi interessati da deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Può bloccare il browser se apri gli strumenti per sviluppatori.
⚠️ Questa opzione viene disabilitata silenziosamente quando vmObfuscation è attivata. Usa invece vmDebugProtection.
Questa opzione rende quasi impossibile utilizzare la funzione debugger degli strumenti per sviluppatori (sia sui browser basati su WebKit sia su Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Può bloccare il browser! Usala a tuo rischio.
⚠️ Questa opzione viene disabilitata silenziosamente quando vmObfuscation è attivata. Usa invece vmDebugProtection.
Se impostata, viene utilizzato un intervallo in millisecondi per forzare la modalità di debug nella scheda Console, rendendo più difficile l'uso di altre funzionalità degli strumenti per sviluppatori. Funziona se debugProtection è attivata. Il valore consigliato è compreso tra 2000 e 4000 millisecondi.
disableConsoleOutput
Type: boolean Default: false
⚠️ Questa opzione disabilita le chiamate console a livello globale per tutti gli script
Disabilita l'uso di console.log, console.info, console.error, console.warn, console.debug, console.exception e console.trace sostituendoli con funzioni vuote. Ciò rende più difficile l'uso del debugger.
domainLock
Type: string[] Default: []
⚠️ Questa opzione non funziona con target: 'node', target: 'service-worker' o target: 'bytenode'
Consente di eseguire il codice sorgente offuscato solo su domini e/o sottodomini specifici. In questo modo diventa davvero difficile per qualcuno copiare e incollare il codice sorgente ed eseguirlo altrove.
Se il codice sorgente non viene eseguito sui domini specificati da questa opzione, il browser verrà reindirizzato all'URL passato all'opzione domainLockRedirectUrl.
Domini e sottodomini multipli
È possibile vincolare il codice a più di un dominio o sottodominio. Ad esempio, per vincolarlo in modo che venga eseguito solo su www.example.com, aggiungi www.example.com. Per farlo funzionare sul dominio radice, inclusi tutti i sottodomini (example.com, sub.example.com), usa .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Questa opzione non funziona con target: 'node', target: 'service-worker' o target: 'bytenode'
Consente di reindirizzare il browser a un URL specificato se il codice sorgente non viene eseguito sui domini indicati da domainLock
exclude
Type: string[] Default: []
Nomi di file o glob che indicano i file da escludere dall'offuscamento.
forceTransformStrings
Type: string[] Default: []
Attiva la trasformazione forzata dei letterali stringa che corrispondono ai pattern RegExp passati.
⚠️ Questa opzione riguarda solo le stringhe che non dovrebbero essere trasformate da stringArrayThreshold (o da eventuali altre soglie in futuro)
L'opzione ha la priorità sull'opzione reservedStrings, ma non sui conditional comments.
Esempio:
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
L'obiettivo principale di questa opzione è la possibilità di usare gli stessi nomi di identificatori durante l'offuscamento di più sorgenti/file.
Attualmente sono supportati due tipi di identificatori:
- Identificatori globali:
- Tutti gli identificatori globali vengono scritti nella cache;
- Tutti gli identificatori globali non dichiarati corrispondenti vengono sostituiti con i valori presenti nella cache.
- Identificatori di proprietà, solo quando l'opzione
renamePropertiesè attivata:- Tutti gli identificatori di proprietà vengono scritti nella cache;
- Tutti gli identificatori di proprietà corrispondenti vengono sostituiti con i valori presenti nella cache.
API Node.js
Se viene passato un valore null, la cache viene disabilitata completamente.
Se viene passato un oggetto vuoto ({}), viene attivata la scrittura dei nomi degli identificatori nell'oggetto cache (tipo TIdentifierNamesCache). A questo oggetto cache si accede tramite la chiamata al metodo getIdentifierNamesCache dell'oggetto ObfuscationResult.
L'oggetto cache risultante può poi essere usato come valore dell'opzione identifierNamesGenerator per utilizzare questi nomi durante l'offuscamento di tutti i nomi di identificatori corrispondenti delle sorgenti successive.
Esempio:
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 dispone di un'opzione diversa --identifier-names-cache-path che consente di definire un percorso al file .json esistente che verrà usato per leggere e scrivere la cache dei nomi degli identificatori.
Se viene passato un percorso a un file vuoto, la cache dei nomi degli identificatori verrà scritta in quel file.
Questo file con la cache esistente può essere riutilizzato come valore dell'opzione --identifier-names-cache-path per utilizzare questi nomi durante l'offuscamento di tutti i nomi di identificatori corrispondenti dei file successivi.
identifierNamesGenerator
Type: string Default: hexadecimal
Imposta il generatore dei nomi degli identificatori.
Valori disponibili:
dictionary: nomi degli identificatori dall'elencoidentifiersDictionaryhexadecimal: nomi degli identificatori come_0xabc123mangled: nomi brevi degli identificatori comea,b,cmangled-shuffled: comemangledma con alfabeto mescolato
identifiersDictionary
Type: string[] Default: []
Imposta il dizionario degli identificatori per l'opzione identifierNamesGenerator: dictionary. Ogni identificatore del dizionario verrà usato in alcune varianti con una diversa combinazione di maiuscole e minuscole per ciascun carattere. Pertanto, il numero di identificatori nel dizionario dovrebbe dipendere dalla quantità di identificatori nel codice sorgente originale.
identifiersPrefix
Type: string Default: ''
Imposta un prefisso per tutti gli identificatori globali.
Usa questa opzione quando vuoi offuscare più file. Questa opzione aiuta a evitare conflitti tra gli identificatori globali di questi file. Il prefisso dovrebbe essere diverso per ogni file.
randomIdentifiersPrefix
Type: boolean Default: false
Aggiunge un prefisso casuale basato su seed (6 caratteri alfanumerici) a tutti gli identificatori globali. Usa questa opzione per evitare collisioni tra bundle offuscati separatamente e caricati nello stesso scope globale: elimina la necessità di scegliere manualmente un identifiersPrefix univoco per ciascun bundle.
- Il valore casuale è derivato dall'opzione
seede dall'hash del codice sorgente, quindi build riproducibili con lo stesso seed producono lo stesso prefisso. - Se combinato con
identifiersPrefix, i caratteri casuali vengono aggiunti al prefisso fornito dall'utente (ad esempiomyApp+ il casualeaBc123→myAppaBc123). - Se combinato con
vmObfuscation, il valore casuale sostituisce il prefissovmpredefinito: la casualità garantisce già l'univocità.
ignoreImports
Type: boolean Default: false
Impedisce l'offuscamento degli import require. Può essere utile in alcuni casi in cui, per qualche motivo, l'ambiente di runtime richiede questi import solo con stringhe statiche.
inputFileName
Type: string Default: ''
Consente di impostare il nome del file di input con il codice sorgente. Questo nome verrà usato internamente per la generazione della source map.
Obbligatorio quando si usa l'API NodeJS e l'opzione sourceMapSourcesMode ha il valore sources.
log
Type: boolean Default: false
Attiva la registrazione delle informazioni nella console.
numbersToExpressions
Type: boolean Default: false
Attiva la conversione dei numeri in espressioni
Esempio:
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Consente di impostare un preset di opzioni.
Valori disponibili:
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.
Tutte le opzioni aggiuntive verranno unite al preset di opzioni selezionato.
parseHtml
Type: boolean Default: false
Attiva l'offuscamento del JavaScript all'interno dei tag HTML <script>.
Quando è attivata, l'offuscatore:
- Rileva automaticamente se l'input è HTML (controllando la presenza di tag
<!DOCTYPE,<html>,<head>,<body>o<script>) - Estrae il JavaScript dai tag
<script>contrassegnati con l'attributodata-javascript-obfuscator - Offusca singolarmente ogni script contrassegnato preservando la struttura HTML
- Reinserisce il codice offuscato nelle posizioni originali
Importante: vengono offuscati solo gli script con l'attributo data-javascript-obfuscator. Ogni script contrassegnato viene offuscato singolarmente e in modo indipendente. Ciò significa che:
- Il codice all'interno dei tag script contrassegnati deve essere isolato: NON deve fare riferimento a variabili, funzioni o classi definite in altri tag script contrassegnati
- Gli script non contrassegnati possono comunque accedere alle variabili globali definite dagli script contrassegnati (tramite dichiarazioni
varo assegnazioni esplicite aglobalThis) - Questo ti dà il controllo esplicito su quali script proteggere
Offuscati (devono avere l'attributo data-javascript-obfuscator):
<script data-javascript-obfuscator>- script normali<script type="text/javascript" data-javascript-obfuscator>- script con tipo esplicito- Script con qualsiasi attributo aggiuntivo (
id,class, altridata-*, ecc.)
Ignorati (lasciati invariati):
- Script senza l'attributo
data-javascript-obfuscator <script type="module">- moduli ES (anche con l'attributo)<script src="...">- script esterni (anche con l'attributo)- Tag script vuoti
Nota: le source map non vengono generate quando parseHtml è attivata, perché non corrisponderebbero correttamente all'output HTML.
Esempio:
// 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
⚠️ questa opzione può compromettere il codice. Attivala solo se sai cosa fa!
Attiva l'offuscamento dei nomi di variabili e funzioni globali con dichiarazione.
Quando questa opzione è disabilitata e il codice di input dichiara funzioni o classi nello scope globale (ovvero il codice non è racchiuso in una IIFE), i loro nomi vengono mantenuti così come sono nell'output offuscato: altri script potrebbero farvi riferimento per nome. Con vmObfuscation viene segnalato un avviso VMGlobalFunctionNamesNotRenamed che elenca questi nomi, poiché il corpo della funzione è nascosto come bytecode ma il nome di primo livello leggibile rivela comunque cosa fa il codice (ad esempio a un LLM). Per evitare questa esposizione, racchiudi il codice in una IIFE oppure attiva questa opzione.
renameProperties
Type: boolean Default: false
⚠️ questa opzione POTREBBE compromettere il codice. Attivala solo se sai cosa fa!
Attiva la rinomina dei nomi delle proprietà. Tutte le proprietà DOM integrate e le proprietà delle classi core di JavaScript verranno ignorate.
Per passare dalla modalità safe a quella unsafe di questa opzione usa l'opzione renamePropertiesMode.
Per impostare il formato dei nomi delle proprietà rinominate usa l'opzione identifierNamesGenerator.
Per controllare quali proprietà verranno rinominate usa l'opzione reservedNames.
Esempio:
// 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
⚠️ Anche in modalità safe, l'opzione renameProperties POTREBBE compromettere il codice.
Specifica la modalità dell'opzione renameProperties:
safe- comportamento predefinito dopo la versione2.11.0. Tenta di rinominare le proprietà in modo più sicuro per prevenire errori di runtime. Con questa modalità alcune proprietà verranno escluse dalla rinomina.unsafe- comportamento predefinito prima della versione2.11.0. Rinomina le proprietà in modo non sicuro senza alcuna restrizione.
Se un file utilizza proprietà provenienti da un altro file, usa l'opzione identifierNamesCache per mantenere gli stessi nomi di proprietà tra questi file.
reservedNames
Type: string[] Default: []
Disabilita l'offuscamento e la generazione degli identificatori che corrispondono ai pattern RegExp passati.
Esempio:
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Disabilita la trasformazione dei letterali stringa che corrispondono ai pattern RegExp passati. Le stringhe corrispondenti rimarranno visibili nell'output offuscato.
Quando si usa l'offuscamento VM, le stringhe riservate vengono memorizzate in un array separato non crittografato per mantenerle visibili. Questo è utile per le stringhe che devono rimanere leggibili, come gli endpoint API per il monitoraggio o gli identificatori di librerie.
Esempio:
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Questa opzione imposta il seed per il generatore casuale. È utile per creare risultati ripetibili.
Se il seed è 0, il generatore casuale funzionerà senza seed.
selfDefending
Type: boolean Default: false
⚠️ Non modificare in alcun modo il codice offuscato dopo l'offuscamento con questa opzione, perché qualsiasi modifica, come la minificazione del codice, può attivare l'autodifesa e il codice smetterà di funzionare!
⚠️ Questa opzione imposta forzatamente il valore di compact su true
⚠️ Questa opzione viene disabilitata silenziosamente quando vmObfuscation è attivata. Usa invece vmSelfDefending.
Questa opzione rende il codice di output resistente alla formattazione e alla rinomina delle variabili. Se si prova a usare un beautifier JavaScript sul codice offuscato, il codice smetterà di funzionare, rendendone più difficile la comprensione e la modifica.
simplify
Type: boolean Default: true
Attiva un ulteriore offuscamento del codice tramite semplificazione.
⚠️ nelle versioni future l'offuscamento dei letterali boolean (true => !![]) verrà spostato sotto questa opzione.
Esempio:
// 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
Attiva la generazione della source map per il codice offuscato.
Le source map possono essere utili per eseguire il debug del codice sorgente JavaScript offuscato. Se vuoi o hai bisogno di eseguire il debug in produzione, puoi caricare il file della source map separato in una posizione segreta e poi puntare il browser a quella posizione.
sourceMapBaseUrl
Type: string Default: ``
Imposta l'URL di base per l'URL di importazione della source map quando sourceMapMode: 'separate'.
Esempio CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Risultato:
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Imposta il nome del file per la source map di output quando sourceMapMode: 'separate'.
Esempio CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Risultato:
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Specifica la modalità di generazione della source map:
inline- aggiunge la source map alla fine di ogni file .js;separate- genera il corrispondente file '.map' con la source map. Nel caso in cui l'offuscatore venga eseguito tramite CLI, aggiunge un collegamento al file della source map alla fine del file con il codice offuscato//# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Consente di controllare i campi sources e sourcesContent della source map:
sources-content- aggiunge un camposourcesfittizio, aggiunge il camposourcesContentcon il codice sorgente originale;sources- aggiunge il camposourcescon una descrizione della sorgente valida, non aggiunge il camposourcesContent. Quando si usa l'API NodeJS è necessario definire l'opzioneinputFileNameche verrà usata come valore del camposources.
splitStrings
Type: boolean Default: false
Suddivide i letterali stringa in blocchi con lunghezza pari al valore dell'opzione splitStringsChunkLength.
Esempio:
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Imposta la lunghezza dei blocchi dell'opzione splitStrings.
stringArray
Type: boolean Default: true
Rimuove i letterali stringa e li colloca in un array speciale. Ad esempio, la stringa "Hello World" in var m = "Hello World"; verrà sostituita con qualcosa come var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ l'opzione stringArray deve essere attivata
Attiva la trasformazione delle chiamate a stringArray. Tutti gli argomenti di queste chiamate possono essere estratti in un oggetto diverso a seconda del valore di stringArrayCallsTransformThreshold.
In questo modo diventa ancora più difficile individuare automaticamente le chiamate all'array di stringhe.
Esempio:
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
⚠️ le opzioni stringArray e stringArrayCallsTransformThreshold devono essere attivate
Puoi usare questa impostazione per regolare la probabilità (da 0 a 1) che le chiamate all'array di stringhe vengano trasformate.
stringArrayEncoding
Type: string[] Default: []
⚠️ l'opzione stringArray deve essere attivata
Questa opzione può rallentare lo script.
Codifica tutti i letterali stringa di stringArray usando base64 o rc4 e inserisce un codice speciale che serve a decodificarli nuovamente a runtime.
Ogni valore di stringArray verrà codificato con la codifica scelta casualmente dall'elenco passato. Ciò rende possibile l'uso di più codifiche.
Valori disponibili:
'none'(boolean): non codifica il valore distringArray'base64'(string): codifica il valore distringArrayusandobase64'rc4'(string): codifica il valore distringArrayusandorc4. Circa il 30-50% più lento dibase64, ma rende più difficile ottenere i valori iniziali.
Ad esempio, con i seguenti valori delle opzioni alcuni valori di stringArray non verranno codificati, mentre altri verranno codificati con le codifiche base64 e rc4:
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ l'opzione stringArray deve essere attivata
Consente di controllare il tipo degli indici delle chiamate all'array di stringhe.
Ogni indice di chiamata di stringArray verrà trasformato con il tipo scelto casualmente dall'elenco passato. Ciò rende possibile l'uso di più tipi.
Valori disponibili:
'hexadecimal-number'(default): trasforma gli indici delle chiamate all'array di stringhe come numeri esadecimali'hexadecimal-numeric-string': trasforma gli indici delle chiamate all'array di stringhe come stringa numerica esadecimale
Prima della versione 2.9.0, javascript-obfuscator trasformava tutti gli indici delle chiamate all'array di stringhe con il tipo hexadecimal-numeric-string. Ciò rende leggermente più difficile una parte della deoffuscazione manuale, ma consente ai deoffuscatori automatici di individuare facilmente queste chiamate.
Il nuovo tipo hexadecimal-number mira a rendere più difficile il rilevamento automatico dei pattern delle chiamate all'array di stringhe nel codice.
In futuro verranno aggiunti altri tipi.
stringArrayIndexShift
Type: boolean Default: true
⚠️ l'opzione stringArray deve essere attivata
Attiva uno spostamento aggiuntivo dell'indice per tutte le chiamate all'array di stringhe
stringArrayRotate
Type: boolean Default: true
⚠️ stringArray deve essere attivata
Sposta l'array stringArray di un numero fisso e casuale (generato durante l'offuscamento del codice) di posizioni. In questo modo diventa più difficile far corrispondere l'ordine delle stringhe rimosse alla loro posizione originale.
stringArrayShuffle
Type: boolean Default: true
⚠️ stringArray deve essere attivata
Mescola casualmente gli elementi dell'array stringArray.
stringArrayWrappersCount
Type: number Default: 1
⚠️ l'opzione stringArray deve essere attivata
Imposta il numero di wrapper per lo string array all'interno di ciascuno scope radice o di funzione.
Il numero effettivo di wrapper all'interno di ciascuno scope è limitato dal numero di nodi literal presenti in quello scope.
Esempio:
// 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
⚠️ le opzioni stringArray e stringArrayWrappersCount devono essere attivate
Attiva le chiamate concatenate tra i wrapper dello string array.
Esempio:
// 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'opzione stringArray deve essere attivata
⚠️ Attualmente questa opzione riguarda solo i wrapper aggiunti dal valore function dell'opzione stringArrayWrappersType
Consente di controllare il numero massimo di parametri dei wrapper dell'array di stringhe.
Il valore predefinito e minimo è 2. Valore consigliato tra 2 e 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ le opzioni stringArray e stringArrayWrappersCount devono essere attivate
Consente di selezionare il tipo di wrapper aggiunti dall'opzione stringArrayWrappersCount.
Valori disponibili:
'variable': aggiunge wrapper di variabili all'inizio di ciascuno scope. Prestazioni veloci.'function': aggiunge wrapper di funzioni in posizioni casuali all'interno di ciascuno scope. Prestazioni più lente rispetto avariable, ma fornisce un offuscamento più rigoroso.
È altamente consigliato usare i wrapper function per un offuscamento più elevato quando una perdita di prestazioni non ha un forte impatto sull'applicazione offuscata.
Esempio del valore dell'opzione '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'opzione stringArray deve essere attivata
Puoi usare questa impostazione per regolare la probabilità (da 0 a 1) che un letterale stringa venga inserito nello stringArray.
Questa impostazione è particolarmente utile per basi di codice di grandi dimensioni, perché richiama ripetutamente lo string array e può rallentare il codice.
stringArrayThreshold: 0 equivale a stringArray: false.
strictMode
Type: boolean | null Default: null
Consente di specificare come l'offuscatore deve trattare il codice rispetto alla modalità strict di JavaScript.
Valori disponibili:
null(default) - rileva automaticamente la modalità strict dal codice. Se il codice contiene una direttiva'use strict'esplicita, sintassi di modulo ES o metodi di classe, viene trattato come modalità strict. Altrimenti si assume la modalità sloppy.true- forza il trattamento in modalità strict per tutto il codice, anche senza una direttiva'use strict'esplicita. Usalo quando il codice verrà eseguito in un contesto in modalità strict (ad esempio in moduli ES, bundler o framework moderni).false- solo gli indicatori espliciti della modalità strict ('use strict', moduli ES, metodi di classe) vengono trattati come strict. L'ereditarietà dallo scope padre si applica comunque secondo la specifica JS.
target
Type: string Default: browser
Consente di impostare l'ambiente di destinazione per il codice offuscato.
Valori disponibili:
browser(default) — ambiente standard di una pagina web. Il codice di output è identico anode, ma alcune opzioni specifiche del browser non possono essere usate con il targetnodebrowser-no-eval— comebrowser, ma l'output non usaeval(). Usalo quando la pagina di destinazione ha una Content Security Policy che vietaeval/unsafe-eval.node— ambiente Node.js. Le opzioni specifiche del browser sono disabilitate (richiedonowindow/documente in Node non avrebbero effetto o genererebbero un errore). Alcune difesevmSelfDefendingche si basano su API disponibili solo nel browser — rilevamento dei browser headless, ripristino tramite realm pulito basato su iframe, controlli anti-inspector/DOM — non vengono emesse per questo target.service-worker— contesto Service Worker. Nessunwindow, nessundocument, un diverso globaleself.userscript— sandbox di un gestore di userscript (ad esempio Tampermonkey). Le difesevmSelfDefendingvengono adattate di conseguenza.bytenode— codice Node.js che verrà compilato con il loader bytenode (bytecode V8 memorizzato nella cache.jsc) dopo l'offuscamento. L'offuscatore stesso non richiamabytenode; emette JavaScript offuscato tramite VM il cui runtime è strutturato per resistere alla fase di compilazione di bytenode, e le difesevmSelfDefendingvengono adattate di conseguenza. Esegui tu stessobytenodesull'output offuscato per produrre il file.jscfinale.
transformObjectKeys
Type: boolean Default: false
Attiva la trasformazione delle chiavi degli oggetti.
Esempio:
// 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
Controlla quali avvisi di offuscamento non fatali vengono emessi tramite il metodo ObfuscationResult.getWarnings().
Valori disponibili:
'all'(default) — viene emesso ogni avviso.'none'— tutti gli avvisi vengono soppressi.- un oggetto che associa i tipi di avviso a valori booleani — un tipo associato a
falseviene soppresso; ogni tipo non presente (o associato atrue) rimane attivo. Ad esempio,{ "VMGlobalFunctionNamesNotRenamed": false }mantiene ogni avviso tranne quello.
Tipi di avviso:
VMGlobalFunctionNamesNotRenamed— convmObfuscation, i nomi delle dichiarazioni di funzione di primo livello, delle dichiarazioni di classe e delle variabili a cui è assegnata un'espressione di funzione/arrow/classe sono stati mantenuti così come sono (l'opzionerenameGlobalsè disabilitata e il codice non è racchiuso in una IIFE), quindi rimangono leggibili nell'output anche se i corpi sono nascosti come bytecode. I nomi esportati non vengono segnalati.VMTopLevelInitializerNotVirtualized— gli inizializzatori delle variabili di primo livello sono rimasti in JavaScript in chiaro con l'offuscamento VM perchévmWrapTopLevelInitializersè disabilitata o non è riuscita a virtualizzarli.DynamicCodeRenameRisk— il codice costruisce una funzione da una stringa a runtime (evaldiretto, il costruttoreFunctionofn.toString()iniettato in uno<script>/Worker), che potrebbe fare riferimento a identificatori rinominati dall'offuscatore.VMDynamicCodeSkipped— una funzione è stata esclusa dalla conversione in bytecode VM perché contieneevaldiretto /new Functiondinamico /Function(vedivmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— convmAsyncExecutorattivata, una funzione che hai contrassegnato esplicitamente in modalitàcommentè risultata sincrona ed è stata saltata (in quella modalità vengono virtualizzate solo le funzioni async).VMAsyncGeneratorSkippedInAsyncMode— convmAsyncExecutore un getter di chiave async attivo, un generatore async contrassegnato non è stato virtualizzato (deve restituire il suo iteratore in modo sincrono).BrowserTargetWithNodeStyleCode— il codice sembra destinato a Node.js (ad esempiorequire('fs'),__dirname,process.argv) mentre l'opzionetargetè impostata su un ambiente di tipo browser.
vmObfuscation
Type: boolean Default: false
Attiva l'offuscamento basato su bytecode VM. Quando è attivata, le funzioni JavaScript vengono compilate in bytecode personalizzato eseguito da una macchina virtuale integrata. Questo fornisce il massimo livello di protezione, poiché la logica del codice originale viene completamente trasformata.
Esempio:
Il tuo codice leggibile come return qty * price diventa un elenco di numeri come [0x15,0x03,0x17,...] che solo l'interprete VM integrato può eseguire. La logica originale non è più visibile come JavaScript.
vmTargetFunctions
Type: string[] Default: []
Specifica esattamente quali funzioni di primo livello devono ricevere la protezione VM, per nome.
Esempio:
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Risultato: solo queste tre funzioni ricevono la protezione VM. Tutto il resto rimane come JavaScript normale (ma comunque offuscato). Perfetto per proteggere controlli di licenza sensibili o logiche di autenticazione mantenendo snello il resto del codice.
vmExcludeFunctions
Type: string[] Default: []
Specifica le funzioni di primo livello che non devono mai ricevere la protezione VM. Ha la precedenza sulle altre impostazioni.
Esempio:
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Quando usarla: le funzioni di primo livello critiche per le prestazioni (loop di animazione, elaborazione di dati in tempo reale) possono essere escluse per evitare l'overhead della VM proteggendo comunque tutto il resto.
vmTargetFunctionsMode
Type: string Default: root
Controlla come le funzioni/i metodi vengono selezionati per l'offuscamento VM.
Esempio - Modalità 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'
}
Quando usarla: quando hai bisogno di un controllo chirurgico su esattamente quali funzioni ricevono la protezione VM, in particolare per funzioni annidate che contengono logica sensibile. A differenza di vmTargetFunctions, che funziona solo con funzioni denominate di primo livello, la modalità comment ti consente di proteggere qualsiasi funzione in qualsiasi punto del codice.
vmForceCompileDynamicCode
Type: boolean Default: false
Controlla cosa fa l'offuscamento VM con una funzione che contiene una chiamata eval diretta, new Function(...) o Function(...).
Per impostazione predefinita, tale funzione (e ogni funzione definita al suo interno) viene esclusa dalla conversione in bytecode VM e viene segnalato un avviso VMDynamicCodeSkipped in result.getWarnings(). Questo perché il codice sorgente costruito a runtime potrebbe fare riferimento a identificatori della catena di scope circostante — identificatori che l'offuscatore ha rinominato.
Se impostata su true, la funzione viene comunque convertita in bytecode e l'avviso VMDynamicCodeSkipped non viene più emesso.
L'avviso separato DynamicCodeRenameRisk continua a essere emesso indipendentemente da questa opzione, perché il rischio di rinomina che descrive è indipendente dall'esclusione dalla VM: attivare questa opzione non rende più sicuro il pattern sottostante.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
Con l'opzione disattivata (impostazione predefinita), loadConfig viene lasciata come JavaScript in chiaro. Con l'opzione attivata, loadConfig viene compilata in bytecode VM come qualsiasi altra funzione. Usala quando hai verificato il punto di chiamata e sai che il codice costruito a runtime non dipende da identificatori rinominati nella closure.
vmWrapTopLevelInitializers
Type: boolean Default: false
Racchiude alcuni inizializzatori di variabili di primo livello in IIFE (Immediately Invoked Function Expressions) affinché possano essere offuscati tramite VM.
Cosa fa: Senza questa opzione, le costanti e le variabili di primo livello rimangono visibili nell'output:
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
Con questa opzione attivata, l'inizializzatore viene racchiuso in una IIFE che viene offuscata tramite VM:
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Nota: questa opzione funziona solo quando vmTargetFunctionsMode è 'root' (impostazione predefinita).
Avvisi: ogni volta che un inizializzatore di primo livello rimane in JavaScript in chiaro con l'offuscamento VM, viene segnalato un avviso VMTopLevelInitializerNotVirtualized che elenca i nomi delle variabili interessate. Ciò comprende: questa opzione disabilitata, gli inizializzatori che questa opzione ha dovuto saltare (ciascuno con il motivo — ad esempio l'inizializzatore fa riferimento a un declaratore di pari livello o contiene await di primo livello) e la modalità vmAsyncExecutor, in cui i wrapper sincroni non possono essere virtualizzati affatto.
vmDynamicOpcodes
Type: boolean Default: false
Rende l'interprete VM più piccolo e unico per ogni build.
Cosa fa:
- Filtra le istruzioni inutilizzate - Se il codice non usa le classi, le istruzioni relative alle classi vengono rimosse completamente
- Randomizza la struttura - L'ordine dei gestori delle istruzioni viene mescolato a ogni build
Il risultato è un output più piccolo e ogni build ha un aspetto diverso.
vmBytecodeEncoding
Type: boolean Default: false
Codifica ogni istruzione del bytecode. Le istruzioni vengono decodificate una alla volta durante l'esecuzione.
vmBytecodeArrayEncoding
Type: boolean Default: false
Codifica l'intero array di bytecode come un unico blocco. L'array viene decodificato una sola volta all'avvio, prima che inizi l'esecuzione. Usala insieme a vmBytecodeEncoding per due livelli di protezione.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Chiave di crittografia personalizzata per la codifica dell'array di bytecode. Quando è impostata, viene usata questa chiave al posto di quella predefinita derivata dall'ambiente. La chiave deve essere fornita a runtime tramite vmBytecodeArrayEncodingKeyGetter.
Questa opzione esternalizza la chiave di crittografia: non viene incorporata nel codice offuscato stesso. Sebbene la chiave sia comunque accessibile a runtime (e quindi non sia veramente segreta), questa separazione impedisce agli strumenti di analisi statica di individuare la chiave esaminando il solo codice.
Importante: la chiave deve essere disponibile in modo sincrono quando il codice offuscato viene caricato. Usa un archivio sincrono come cookie, localStorage, sessionStorage, variabili globali o elementi DOM (ad esempio meta tag iniettati dal server). Metodi asincroni come fetch() non possono essere usati direttamente nell'espressione del key getter.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Espressione JavaScript sincrona che restituisce la chiave di crittografia a runtime. Questa espressione viene valutata quando il codice offuscato viene caricato e deve restituire la stessa chiave fornita in vmBytecodeArrayEncodingKey. Per risolvere la chiave in modo asincrono (una Promise), attiva vmAsyncExecutor.
Nota: un getter che restituisce una Promise richiede vmAsyncExecutor. Questo non può essere verificato in fase di build, quindi un getter con Promise e vmAsyncExecutor disattivato fallisce a runtime: il decodificatore riceve la Promise invece della chiave.
Il codice offuscato funzionerà solo quando il key getter restituisce esattamente la stessa chiave usata durante l'offuscamento. Se le chiavi non corrispondono, la decrittazione fallirà e il codice produrrà risultati privi di senso o errori. Se il key getter restituisce undefined, null o una stringa vuota, il codice genererà un errore: "VM decryption key not available".
Importante: tieni la chiave fuori dallo stesso file/script del codice offuscato: incorporarla lì consente di recuperarla anche con una scansione puramente statica del bundle. Memorizzala invece in una sorgente separata: cookie impostati dal server, localStorage popolato da un altro script, un meta tag HTML iniettato dal server, una variabile globale impostata da uno script diverso oppure (con vmAsyncExecutor) recuperata dal tuo backend a runtime.
Quando la chiave viene recuperata dal tuo backend (tramite vmAsyncExecutor), aggiungi a quell'endpoint controlli basati sulla sessione o sull'origine: restituisci la chiave corretta agli utenti reali (sessione valida, Origin/Referer previsti) e una chiave priva di senso alle richieste sospette (ad esempio un'origine localhost/inattesa, nessuna sessione). Gli utenti reali eseguono il codice normalmente; una copia eseguita al di fuori del tuo ambiente ottiene una chiave che non decritta nulla. La logica esatta dipende dal tuo sito.
Esempi:
// 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())'
Esempio di utilizzo:
// 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
Attiva l'executor VM asincrono, che consente a vmBytecodeArrayEncodingKeyGetter di restituire una Promise (un key getter asincrono): in questo modo la chiave di decrittazione può essere recuperata a runtime (richiesta di rete, IndexedDB, ecc.) invece di dover essere disponibile in modo sincrono quando il codice viene caricato.
Fortemente consigliato per basi di codice completamente async. In questa modalità vengono virtualizzate solo le funzioni async — una funzione sincrona non può essere resa async senza trasformare il suo valore di ritorno in una Promise e compromettere i suoi chiamanti — quindi il codice interamente async ottiene la massima copertura. Funziona comunque quando la radice è sincrona (ad esempio una IIFE sincrona / wrapper UMD): le funzioni async più esterne al suo interno sono protette e le parti sincrone vengono lasciate invariate.
Cosa viene trasformato: ogni funzione async più esterna, ovunque compaia (anche annidata all'interno di wrapper sincroni). L'async più esterna di ogni catena è l'unità protetta: tutto ciò che si trova al suo interno, sincrono e async, viene compilato. Le funzioni sincrone e i generatori semplici vengono lasciati non offuscati.
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
}
}
Esclusioni e avvisi. Anche i generatori async vengono lasciati non offuscati quando è attivo un key getter asincrono (un generatore async deve restituire il suo iteratore in modo sincrono e non può attendere la chiave). Nella modalità predefinita vmTargetFunctionsMode: 'root' le esclusioni sono silenziose (la selezione è automatica); nella modalità comment viene emesso un avviso tramite ObfuscationResult.getWarnings() ogni volta che una funzione che hai contrassegnato esplicitamente non può essere virtualizzata — è risultata sincrona oppure è un generatore async sotto un key getter asincrono.
Il key getter asincrono richiede inoltre vmBytecodeArrayEncoding con un vmBytecodeArrayEncodingKeyGetter.
Esempio di utilizzo:
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
Codifica le destinazioni dei salti nel bytecode. Gli offset dei salti vengono calcolati a runtime, nascondendo la struttura del flusso di controllo (if/else, cicli, ecc.) all'analisi statica.
vmMacroOps
Type: boolean Default: false
Combina sequenze di istruzioni comuni in singoli opcode "macro". Ad esempio, LOAD + ADD + STORE potrebbe diventare un'unica istruzione MACRO_ADD_TO_VAR. Questo interrompe il riconoscimento dei pattern e può migliorare le prestazioni.
vmDebugProtection
Type: boolean Default: false
Aggiunge al runtime VM difese multilivello anti-debug, anti-analisi e anti-LLM. Funziona al meglio con i target browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Aggiunge al runtime VM una protezione multilivello di rilevamento delle manomissioni, anti-hooking e anti-reverse-engineering.
⚠️ Questa opzione attiva forzatamente vmBytecodeArrayEncoding.
⚠️ Rilevamento di ambienti sensibili. Questa opzione vincola il codice offuscato al suo ambiente di runtime di destinazione e usa un fingerprinting avanzato del browser per rilevare gli strumenti di automazione. Il codice protetto con questa opzione si interromperà intenzionalmente quando viene eseguito in:
- Browser headless (Chrome/Chromium headless, PhantomJS)
- Strumenti di automazione del browser (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (quando
targetè impostato subrowser) - jsdom o emulazioni DOM lato server simili
- Ambienti in cui le funzioni native integrate del browser sono state intercettate o sostituite
Il codice funzionerà correttamente nei browser normali (Chrome, Firefox, Safari, Edge), anche quando viene caricato all'interno di iframe, estensioni del browser (content script) e Web Worker. Se hai bisogno di eseguire test automatizzati sul codice protetto, disabilita vmSelfDefending per le build di test: questa opzione è progettata per impedire l'analisi automatizzata e non può essere usata in sicurezza con alcun framework di automazione.
Fortemente consigliato l'uso insieme a vmDebugProtection, vmBytecodeArrayEncodingKey e vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook accetta un oggetto con due chiavi: name (obbligatoria) e aliases (facoltativa).
name è una funzione globale definita dalla tua pagina host che una difesa VM (vmDebugProtection / vmSelfDefending) chiama con un oggetto segnale quando rileva un segnale ostile — un debugger o un inspector, un browser headless / di automazione, un processo di AI-coding-agent, un dominio non consentito e così via. Usala per segnalare l'evento al tuo backend (ad esempio navigator.sendBeacon). L'hook è un puro raccoglitore di telemetria: il suo valore di ritorno viene ignorato e un hook mancante o che genera un'eccezione è un no-op silenzioso che non può mai disabilitare una difesa. Per modificare ciò che una difesa fa al momento del rilevamento, usa vmDefenseReaction.
aliases rinomina facoltativamente i campi di quell'oggetto segnale — descritto più avanti in Rinominare i campi del segnale.
L'oggetto segnale. L'hook riceve un unico signal:
source— il rilevatore specifico che si è attivato (vedi la tabella).category— il gruppo sotto cui viene segnalato:automation(browser non umani),debugger(è attivo un debugger/inspector),sandbox(host strumentato/fittizio),domain(violazione del domain-lock),tamper(funzioni integrate modificate a runtime) ointegrity(il codice della VM stessa è stato alterato).score/threshold— con quanta forza si è attivato il rilevatore e il valore che doveva raggiungere; l'hook si attiva solo quandoscore >= threshold. La maggior parte dei controlli è tutto-o-niente (un singolo segnale decisivo);headlesssomma diversi segnali relativi alla conformazione del browser, quindi il suoscoreè tipicamente più alto del suothreshold.
Registrare l'hook. Definiscilo come una semplice variabile globale prima che il bundle offuscato venga caricato — il runtime VM e le sue difese vengono eseguiti prima del tuo programma (protetto), quindi molti rilevamenti si attivano durante l'avvio:
// 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 definito all'interno del codice sorgente offuscato viene registrato troppo tardi per intercettare i rilevamenti al momento dell'avvio e, se viene compilato dalla VM, non è raggiungibile finché il tuo programma non viene eseguito. In ogni caso rimane sicuro (un hook mancante è un no-op e una protezione contro la rientranza impedisce qualsiasi loop incontrollato), ma per una copertura completa registralo in anticipo. Per proteggere comunque la tua logica di segnalazione, mantieni l'hook registrato come un buffer di una sola riga ((window.__vmDet = window.__vmDet || []).push(signal)) e leggi/invia quel buffer dal tuo codice offuscato.
Rinominare i campi del segnale (aliases). I valori predefiniti source/category sono nomi descrittivi, quindi chiunque strumenti il callback (o legga l'output) può riconoscere la protezione e quale rilevatore si è attivato. aliases rinomina i campi del segnale con token opachi a tua scelta, applicati all'interno della VM prima che il segnale venga emesso, così quei nomi non compaiono mai nell'output né raggiungono il callback. La tua applicazione conosce la propria mappatura e inoltra i token al tuo backend.
Gli alias sono per campo e mantengono separate le rinomine di chiavi e valori: ogni campo accetta una key (il nome della proprietà che riceve il callback); i campi-nome di tipo stringa source e category accettano anche una mappa values, mentre score/threshold sono numeri e accettano solo una key. I nomi che puoi mappare (qualsiasi altro viene rifiutato in fase di build):
- chiavi dei campi —
source,category,score,threshold - valori di
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - valori di
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> }
}
Questa è elusione del fingerprint, non segretezza — la mappatura può comunque essere dedotta con test ripetuti — quindi il suo unico vantaggio è non esporre nomi stabili e autoesplicativi. Le voci non impostate mantengono i loro nomi predefiniti.
Una semplice stringa (vmDefenseHook: '__vmDetection') è accettata come forma abbreviata di { name: '__vmDetection' } ma è deprecata — preferisci la forma a oggetto.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Configura come reagisce ciascuna categoria di rilevamento. Non attiva nulla: le difese stesse vengono attivate da vmSelfDefending, vmDebugProtection e vmDomainLock; questa opzione seleziona soltanto come reagisce una difesa attivata. La categoria è l'unità di controllo: ogni rilevatore di una categoria mette in atto la reazione di quella categoria.
Ogni categoria raggruppa i rilevatori che sorvegliano un tipo di condizione ostile. Una categoria reagisce solo quando l'opzione che emette i suoi rilevatori è attivata:
Ogni categoria è associata a una o più di vmSelfDefending, vmDebugProtection e vmDomainLock; non esiste alcuna categoria al di fuori di queste tre opzioni e una reazione impostata per una categoria la cui opzione è disattivata semplicemente non ha effetto.
Le chiavi sono questi sei nomi di categoria, oppure default (un fallback per le categorie non specificate). I valori sono:
break— interrompi immediatamentedecoy— continua l'esecuzione su uno stato avvelenato, producendo silenziosamente risultati erratinone— non fare nulla localmente (solo telemetria)
I valori predefiniti per categoria sono mostrati sopra; una categoria che non imposti (o che imposti sul suo valore predefinito) usa quel valore predefinito. default raggiunge ogni categoria, incluse quelle corrette per costruzione (integrity, tamper), quindi { default: 'none' } è una build davvero non interruttiva, di sola telemetria:
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
Fa dipendere il significato degli opcode dalla posizione nel bytecode. Ogni posizione ha una diversa mappatura opcode-gestore derivata da un seed, quindi lo stesso numero di opcode esegue operazioni diverse in posizioni diverse.
vmCallContextOpcodes
Type: boolean Default: false
Fa dipendere una funzione protetta dal punto in cui viene chiamata, così da non poter essere estratta dal codice ed eseguita o analizzata autonomamente: si comporta correttamente solo quando viene invocata tramite i suoi reali punti di chiamata nel programma. Questa opzione incide sulle prestazioni a runtime.
Attualmente sono supportate solo le seguenti costruzioni:
- dichiarazioni di funzione (
function f() {}); - espressioni di funzione e arrow function assegnate a una variabile (
const f = () => {}); - metodi privati di istanza (
this.#m()).
In ogni caso la funzione deve sempre essere raggiunta tramite una chiamata diretta (f(), this.#m()). Se viene memorizzata in un'altra variabile, passata come argomento o comunque usata come valore, viene lasciata non protetta. Le funzioni async sono supportate; i generatori no.
Questa opzione è sperimentale e potrebbe compromettere il codice, quindi testa a fondo l'output prima di usarla.
vmStackEncoding
Type: boolean Default: false
Crittografa i valori nello stack della VM durante l'esecuzione. I valori vengono codificati quando vengono inseriti (push) e decodificati quando vengono estratti (pop), così l'ispezione della memoria mostra dati crittografati invece dei valori effettivi.
Questa opzione incide pesantemente sulle prestazioni.
vmCompactDispatcher
Type: boolean Default: false
Usa un unico executor VM invece di due executor (sync + generator). Riduce le dimensioni del codice offuscato ma aggiunge un overhead sulle prestazioni di circa il 20% sul codice con molta ricorsione.
false(default): due executor — prestazioni ottimali, output più grandetrue: executor singolo — output più piccolo, leggermente più lento
vmStringArrayBytecodeOnly
Type: boolean Default: false
Quando è attivata, l'array di stringhe estrarrà solo le stringhe dai dati del bytecode — nessun'altra stringa nel codice viene trasformata. Questo attiva forzatamente stringArray anche se non è impostata esplicitamente.
Perché usarla: estrarre tutte le stringhe di runtime della VM in un array di stringhe è lento. Questa opzione mira solo al contenuto del bytecode per l'estrazione nell'array di stringhe, migliorando le prestazioni pur proteggendo comunque le costanti del bytecode.
- Quando
vmBytecodeArrayEncoding: false— vengono estratte le stringhe all'interno dei constant pool del bytecode (arrayc) - Quando
vmBytecodeArrayEncoding: true— vengono estratte le stringhe di bytecode codificate in base64 di primo livello stringArrayThresholdcontrolla comunque quale percentuale di quelle stringhe di bytecode viene estratta
vmDomainLock
Type: string[] Default: []
⚠️ Questa opzione non funziona con target: 'node', target: 'service-worker' o target: 'bytenode'
Limita il codice offuscato a domini e/o sottodomini specifici ed è molto più difficile da individuare e rimuovere rispetto a domainLock.
Se il codice sorgente non viene eseguito sui domini specificati da questa opzione, il browser verrà reindirizzato all'URL passato a vmDomainLockRedirectUrl e le successive chiamate protette restituiranno risultati errati anche se il reindirizzamento viene soppresso.
Domini e sottodomini multipli
È possibile vincolare il codice a più di un dominio o sottodominio. Ad esempio, per vincolarlo in modo che venga eseguito solo su www.example.com, aggiungi www.example.com. Per farlo funzionare sul dominio radice, inclusi tutti i sottodomini (example.com, sub.example.com), usa .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Questa opzione non funziona con target: 'node', target: 'service-worker' o target: 'bytenode'
Consente di reindirizzare il browser a un URL specificato se il codice sorgente non viene eseguito sui domini indicati da vmDomainLock.
Preset Options
Offuscamento elevato, prestazioni basse
Le prestazioni saranno molto più lente rispetto al codice non offuscato
{
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
}
Offuscamento medio, prestazioni ottimali
Le prestazioni saranno più lente rispetto al codice non offuscato
{
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
}
Offuscamento basso, prestazioni elevate
Le prestazioni si manterranno a un livello relativamente normale
{
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
}
Preset predefinito, prestazioni elevate
{
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
}
Offuscamento VM Ultra High (sicurezza massima)
Questo preset attiva l'offuscamento basato su bytecode VM con tutte le funzionalità di hardening, incluso il dispatch indiretto. Fornisce la protezione più forte ma con dimensioni di output maggiori ed esecuzione molto più lenta.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Oppure configuralo singolarmente:
{
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 (protezione dagli agenti IA)
Questo preset è progettato specificamente per impedire agli agenti IA e agli LLM di applicare il reverse engineering al codice trasformato in bytecode VM. Basato su vm-default con autodifesa e protezione del debug attivate. Più leggero di vm-high-obfuscation ma specificamente rafforzato contro l'analisi automatizzata.
{
optionsPreset: 'vm-anti-llm'
}
Include:
- Offuscamento con bytecode VM con array di stringhe (da
vm-default) vmSelfDefending— rilevamento anti-hook, hash di integrità, fingerprint del sorgente, verifica del realm pulito tramite iframe, derivazione della chiave con cifrario ARXvmDebugProtection— controlli anti-debug nel ciclo di dispatch della VMdebugProtection: false— nessuna protezione del debug legacy (la protezione del debug della VM è superiore)
Offuscamento VM High (sicurezza più elevata)
Questo preset attiva l'offuscamento basato su bytecode VM con la maggior parte delle funzionalità di hardening. Fornisce una protezione forte con prestazioni migliori rispetto al preset ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Oppure configuralo singolarmente:
{
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
}
Offuscamento VM Medium (sicurezza bilanciata)
Questo preset attiva l'offuscamento basato su bytecode VM con un insieme bilanciato di funzionalità di hardening. Buon compromesso tra sicurezza e prestazioni.
{
optionsPreset: 'vm-medium-obfuscation'
}
Oppure configuralo singolarmente:
{
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
}
Offuscamento VM Low (sicurezza di base, prestazioni migliori)
Questo preset attiva un offuscamento di base basato su bytecode VM senza funzionalità di hardening aggiuntive. Buon equilibrio tra sicurezza e dimensioni dell'output.
{
optionsPreset: 'vm-low-obfuscation'
}
Oppure configuralo singolarmente:
{
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 + protezione con array di stringhe)
Questo preset combina un offuscamento di base basato su bytecode VM con la protezione dell'array di stringhe. Buon punto di partenza per l'offuscamento VM con protezione delle stringhe.
{
optionsPreset: 'vm-default'
}
Oppure configuralo singolarmente:
{
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
}
