Optionsreferenz

Inhalt

compact

config

controlFlowFlattening

controlFlowFlatteningThreshold

deadCodeInjection

deadCodeInjectionThreshold

debugProtection

debugProtectionInterval

disableConsoleOutput

domainLock

Mehrere Domains und Subdomains

domainLockRedirectUrl

exclude

forceTransformStrings

identifierNamesCache

Node.js-API

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

Mehrere Domains und Subdomains

vmDomainLockRedirectUrl

Preset Options

Hohe Obfuskierung, geringe Performance

Mittlere Obfuskierung, optimale Performance

Geringe Obfuskierung, hohe Performance

Standardvoreinstellung, hohe Performance

VM Ultra High – Obfuskierung (maximale Sicherheit)

VM Anti-LLM (Schutz vor KI-Agenten)

VM High – Obfuskierung (höchste Sicherheit)

VM Medium – Obfuskierung (ausgewogene Sicherheit)

VM Low – Obfuskierung (Basissicherheit, bessere Performance)

VM Default (VM- + String-Array-Schutz)

compact

Type: boolean Default: true

Kompakte Codeausgabe in einer einzigen Zeile.

config

Type: string Default: ``

Name der JS-/JSON-Konfigurationsdatei, die die Obfuscator-Optionen enthält. Diese Werte werden von Optionen überschrieben, die direkt an die CLI übergeben werden

controlFlowFlattening

Type: boolean Default: false

⚠️ Diese Option beeinträchtigt die Performance erheblich – bis zu 1,5-mal langsamere Laufzeitgeschwindigkeit. Mit controlFlowFlatteningThreshold legen Sie fest, welcher Prozentsatz der Knoten vom Control Flow Flattening betroffen ist.

Aktiviert das Einebnen des Kontrollflusses (Control Flow Flattening). Control Flow Flattening ist eine Strukturtransformation des Quellcodes, die das Verständnis des Programms erschwert.

Beispiel:

// 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

Die Wahrscheinlichkeit, mit der die Transformation controlFlowFlattening auf einen einzelnen Knoten angewendet wird.

Diese Einstellung ist besonders bei großem Codeumfang nützlich, denn eine große Zahl von Kontrollfluss-Transformationen kann Ihren Code verlangsamen und seine Größe erhöhen.

controlFlowFlatteningThreshold: 0 entspricht controlFlowFlattening: false.

deadCodeInjection

Type: boolean Default: false

⚠️ Vergrößert den obfuskierten Code drastisch (um bis zu 200 %). Verwenden Sie diese Option nur, wenn die Größe des obfuskierten Codes keine Rolle spielt. Mit deadCodeInjectionThreshold legen Sie fest, welcher Prozentsatz der Knoten von der Injektion toten Codes betroffen ist.
⚠️ Diese Option aktiviert zwangsweise die Option stringArray.
⚠️ Diese Option wird stillschweigend deaktiviert, wenn vmObfuscation aktiviert ist.

Mit dieser Option werden dem obfuskierten Code zufällige Blöcke aus totem Code hinzugefügt.

Beispiel:

// 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

Legt fest, welcher Prozentsatz der Knoten von deadCodeInjection betroffen ist.

debugProtection

Type: boolean Default: false

⚠️ Kann Ihren Browser einfrieren, wenn Sie die Entwicklertools öffnen.
⚠️ Diese Option wird stillschweigend deaktiviert, wenn vmObfuscation aktiviert ist. Verwenden Sie stattdessen vmDebugProtection.

Diese Option macht es nahezu unmöglich, die debugger-Funktion der Entwicklertools zu verwenden (sowohl in WebKit-basierten Browsern als auch in Mozilla Firefox).

debugProtectionInterval

Type: number Default: 0

⚠️ Kann Ihren Browser einfrieren! Verwendung auf eigene Gefahr.
⚠️ Diese Option wird stillschweigend deaktiviert, wenn vmObfuscation aktiviert ist. Verwenden Sie stattdessen vmDebugProtection.

Ist die Option gesetzt, wird über ein Intervall in Millisekunden der Debug-Modus im Konsolen-Tab erzwungen, was die Nutzung der übrigen Funktionen der Entwicklertools erschwert. Funktioniert, wenn debugProtection aktiviert ist. Empfohlen wird ein Wert zwischen 2000 und 4000 Millisekunden.

disableConsoleOutput

Type: boolean Default: false

⚠️ Diese Option deaktiviert console-Aufrufe global für alle Skripte

Deaktiviert die Verwendung von console.log, console.info, console.error, console.warn, console.debug, console.exception und console.trace, indem sie durch leere Funktionen ersetzt werden. Das erschwert den Einsatz des Debuggers.

domainLock

Type: string[] Default: []

⚠️ Diese Option funktioniert nicht mit target: 'node', target: 'service-worker' oder target: 'bytenode'

Erlaubt es, den obfuskierten Quellcode nur auf bestimmten Domains und/oder Subdomains auszuführen. Dadurch wird es sehr schwer, Ihren Quellcode einfach zu kopieren und anderswo auszuführen.

Wird der Quellcode nicht auf den mit dieser Option angegebenen Domains ausgeführt, leitet der Browser auf die URL um, die an die Option domainLockRedirectUrl übergeben wurde.

Mehrere Domains und Subdomains

Sie können Ihren Code an mehr als eine Domain oder Subdomain binden. Um ihn zum Beispiel so zu sperren, dass er nur auf www.example.com läuft, fügen Sie www.example.com hinzu. Damit er auf der Root-Domain einschließlich aller Subdomains läuft (example.com, sub.example.com), verwenden Sie .example.com.

domainLockRedirectUrl

Type: string Default: about:blank

⚠️ Diese Option funktioniert nicht mit target: 'node', target: 'service-worker' oder target: 'bytenode'

Leitet den Browser auf eine übergebene URL um, wenn der Quellcode nicht auf den unter domainLock angegebenen Domains ausgeführt wird

exclude

Type: string[] Default: []

Dateinamen oder Globs, die angeben, welche Dateien von der Obfuskierung ausgeschlossen werden.

forceTransformStrings

Type: string[] Default: []

Erzwingt die Transformation von String-Literalen, die auf die übergebenen RegExp-Muster passen.

⚠️ Diese Option betrifft nur Strings, die aufgrund von stringArrayThreshold (oder künftig möglicherweise weiterer Schwellenwerte) nicht transformiert werden sollten

Die Option hat Vorrang vor der Option reservedStrings, nicht aber vor conditional comments.

Beispiel:

	{
		forceTransformStrings: [
			'some-important-value',
			'some-string_\d'
		]
	}

identifierNamesCache

Type: Object | null Default: null

Hauptziel dieser Option ist die Möglichkeit, bei der Obfuskierung mehrerer Quellen bzw. Dateien dieselben Bezeichnernamen zu verwenden.

Derzeit werden zwei Arten von Bezeichnern unterstützt:

  • Globale Bezeichner:
    • Alle globalen Bezeichner werden in den Cache geschrieben;
    • Alle passenden nicht deklarierten globalen Bezeichner werden durch die Werte aus dem Cache ersetzt.
  • Eigenschaftsbezeichner, nur wenn die Option renameProperties aktiviert ist:
    • Alle Eigenschaftsbezeichner werden in den Cache geschrieben;
    • Alle passenden Eigenschaftsbezeichner werden durch die Werte aus dem Cache ersetzt.

Node.js-API

Wird der Wert null übergeben, wird der Cache vollständig deaktiviert.

Wird ein leeres Objekt ({}) übergeben, wird das Schreiben der Bezeichnernamen in ein Cache-Objekt (Typ TIdentifierNamesCache) aktiviert. Auf dieses Cache-Objekt wird über den Methodenaufruf getIdentifierNamesCache des ObfuscationResult-Objekts zugegriffen.

Das so entstandene Cache-Objekt kann anschließend als Wert der Option identifierNamesGenerator dienen, um diese Namen bei der Obfuskierung aller passenden Bezeichnernamen weiterer Quellen zu verwenden.

Beispiel:

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

Die CLI besitzt eine abweichende Option --identifier-names-cache-path, mit der sich der Pfad zu einer vorhandenen .json-Datei angeben lässt, aus der der Bezeichnernamen-Cache gelesen und in die er geschrieben wird.

Wird der Pfad zu einer leeren Datei übergeben, wird der Bezeichnernamen-Cache in diese Datei geschrieben.

Diese Datei mit dem vorhandenen Cache kann erneut als Wert der Option --identifier-names-cache-path verwendet werden, um diese Namen bei der Obfuskierung aller passenden Bezeichnernamen der nächsten Dateien zu nutzen.

identifierNamesGenerator

Type: string Default: hexadecimal

Legt den Generator für Bezeichnernamen fest.

Verfügbare Werte:

  • dictionary: Bezeichnernamen aus der Liste identifiersDictionary
  • hexadecimal: Bezeichnernamen wie _0xabc123
  • mangled: kurze Bezeichnernamen wie a, b, c
  • mangled-shuffled: wie mangled, jedoch mit gemischtem Alphabet

identifiersDictionary

Type: string[] Default: []

Legt das Bezeichner-Wörterbuch für identifierNamesGenerator mit dem Wert dictionary fest. Jeder Bezeichner aus dem Wörterbuch wird in mehreren Varianten mit unterschiedlicher Groß- und Kleinschreibung der einzelnen Zeichen verwendet. Die Anzahl der Bezeichner im Wörterbuch sollte sich daher an der Anzahl der Bezeichner im ursprünglichen Quellcode orientieren.

identifiersPrefix

Type: string Default: ''

Legt ein Präfix für alle globalen Bezeichner fest.

Verwenden Sie diese Option, wenn Sie mehrere Dateien obfuskieren möchten. Sie hilft, Konflikte zwischen den globalen Bezeichnern dieser Dateien zu vermeiden. Das Präfix sollte für jede Datei unterschiedlich sein.

randomIdentifiersPrefix

Type: boolean Default: false

Stellt allen globalen Bezeichnern ein zufälliges, aus dem Seed abgeleitetes Präfix (6 alphanumerische Zeichen) voran. Verwenden Sie diese Option, um Kollisionen zwischen getrennt obfuskierten Bundles zu vermeiden, die in denselben globalen Gültigkeitsbereich geladen werden – Sie müssen dann nicht mehr für jedes Bundle von Hand ein eindeutiges identifiersPrefix wählen.

  • Der Zufallswert wird aus der Option seed und dem Hash des Quellcodes abgeleitet; reproduzierbare Builds mit demselben Seed erzeugen daher dasselbe Präfix.
  • In Kombination mit identifiersPrefix werden die zufälligen Zeichen an das von Ihnen angegebene Präfix angehängt (z. B. myApp + zufälliges aBc123myAppaBc123).
  • In Kombination mit vmObfuscation ersetzt der Zufallswert das Standardpräfix vm – die Zufälligkeit garantiert die Eindeutigkeit bereits.

ignoreImports

Type: boolean Default: false

Verhindert die Obfuskierung von require-Importen. Das kann in Fällen hilfreich sein, in denen die Laufzeitumgebung diese Importe aus irgendeinem Grund nur mit statischen Strings akzeptiert.

inputFileName

Type: string Default: ''

Legt den Namen der Eingabedatei mit dem Quellcode fest. Dieser Name wird intern für die Generierung der Source Map verwendet. Erforderlich, wenn die NodeJS-API verwendet wird und die Option sourceMapSourcesMode den Wert sources hat.

log

Type: boolean Default: false

Aktiviert die Ausgabe von Informationen in der Konsole.

numbersToExpressions

Type: boolean Default: false

Aktiviert die Umwandlung von Zahlen in Ausdrücke

Beispiel:

// input
const foo = 1234;

// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;

optionsPreset

Type: string Default: default

Ermöglicht das Festlegen einer Optionsvoreinstellung.

Verfügbare Werte:

  • 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.

Alle zusätzlich angegebenen Optionen werden mit der ausgewählten Optionsvoreinstellung zusammengeführt.

parseHtml

Type: boolean Default: false

Aktiviert die Obfuskierung von JavaScript innerhalb von HTML-<script>-Tags.

Ist die Option aktiviert, wird der Obfuscator:

  • automatisch erkennen, ob die Eingabe HTML ist (anhand von <!DOCTYPE, <html>, <head>, <body> oder <script>-Tags)
  • JavaScript aus <script>-Tags extrahieren, die mit dem Attribut data-javascript-obfuscator markiert sind
  • jedes markierte Skript einzeln obfuskieren und dabei die HTML-Struktur beibehalten
  • den obfuskierten Code wieder an seiner ursprünglichen Position einfügen

Wichtig: Es werden ausschließlich Skripte mit dem Attribut data-javascript-obfuscator obfuskiert. Jedes markierte Skript wird einzeln und unabhängig obfuskiert. Das bedeutet:

  • Code innerhalb markierter Skript-Tags muss isoliert sein – er darf KEINE Variablen, Funktionen oder Klassen referenzieren, die in anderen markierten Skript-Tags definiert sind
  • Nicht markierte Skripte können weiterhin auf globale Werte zugreifen, die von markierten Skripten definiert werden (über var-Deklarationen oder ausdrückliche Zuweisungen an globalThis)
  • So behalten Sie die ausdrückliche Kontrolle darüber, welche Skripte geschützt werden

Wird obfuskiert (Attribut data-javascript-obfuscator erforderlich):

  • <script data-javascript-obfuscator> – normale Skripte
  • <script type="text/javascript" data-javascript-obfuscator> – Skripte mit ausdrücklich angegebenem Typ
  • Skripte mit beliebigen zusätzlichen Attributen (id, class, weitere data-* usw.)

Wird übersprungen (bleibt unverändert):

  • Skripte ohne das Attribut data-javascript-obfuscator
  • <script type="module"> – ES-Module (auch mit dem Attribut)
  • <script src="..."> – externe Skripte (auch mit dem Attribut)
  • Leere Skript-Tags

Hinweis: Bei aktiviertem parseHtml werden keine Source Maps erzeugt, da sie sich nicht korrekt auf die HTML-Ausgabe abbilden ließen.

Beispiel:

// 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

⚠️ Diese Option kann Ihren Code beschädigen. Aktivieren Sie sie nur, wenn Sie wissen, was sie bewirkt!

Aktiviert die Obfuskierung von globalen Variablen- und Funktionsnamen mit Deklaration.

Ist diese Option deaktiviert und deklariert der Eingabecode Funktionen oder Klassen im globalen Gültigkeitsbereich (ist der Code also nicht in eine IIFE eingeschlossen), bleiben deren Namen in der obfuskierten Ausgabe unverändert – andere Skripte können sie weiterhin über ihren Namen ansprechen. Unter vmObfuscation wird in diesem Fall eine Warnung VMGlobalFunctionNamesNotRenamed mit diesen Namen gemeldet: Der Funktionsrumpf ist zwar als Bytecode verborgen, der lesbare Name auf oberster Ebene verrät aber nach wie vor, was der Code tut (etwa gegenüber einem LLM). Um das zu vermeiden, schließen Sie den Code in eine IIFE ein oder aktivieren Sie diese Option.

renameProperties

Type: boolean Default: false

⚠️ Diese Option KANN Ihren Code beschädigen. Aktivieren Sie sie nur, wenn Sie wissen, was sie bewirkt!

Aktiviert die Umbenennung von Eigenschaftsnamen. Alle integrierten DOM-Eigenschaften sowie Eigenschaften der JavaScript-Kernklassen werden dabei ignoriert.

Um zwischen dem safe- und dem unsafe-Modus dieser Option zu wechseln, verwenden Sie die Option renamePropertiesMode.

Um das Format der umbenannten Eigenschaftsnamen festzulegen, verwenden Sie die Option identifierNamesGenerator.

Um zu steuern, welche Eigenschaften umbenannt werden, verwenden Sie die Option reservedNames.

Beispiel:

// 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

⚠️ Selbst im Modus safe KANN die Option renameProperties Ihren Code beschädigen.

Legt den Modus der Option renameProperties fest:

  • safe – Standardverhalten seit Version 2.11.0. Versucht, Eigenschaften auf sicherere Weise umzubenennen, um Laufzeitfehler zu vermeiden. In diesem Modus werden einige Eigenschaften von der Umbenennung ausgenommen.
  • unsafe – Standardverhalten vor Version 2.11.0. Benennt Eigenschaften ohne jede Einschränkung auf unsichere Weise um.

Wenn eine Datei Eigenschaften aus einer anderen Datei verwendet, nutzen Sie die Option identifierNamesCache, um zwischen diesen Dateien dieselben Eigenschaftsnamen beizubehalten.

reservedNames

Type: string[] Default: []

Deaktiviert die Obfuskierung und die Generierung von Bezeichnern, die auf die übergebenen RegExp-Muster passen.

Beispiel:

	{
		reservedNames: [
			'^someVariable',
			'functionParameter_\d'
		]
	}

reservedStrings

Type: string[] Default: []

Deaktiviert die Transformation von String-Literalen, die auf die übergebenen RegExp-Muster passen. Passende Strings bleiben in der obfuskierten Ausgabe sichtbar.

Bei der VM-Obfuskierung werden reservierte Strings in einem separaten, unverschlüsselten Array abgelegt, damit sie sichtbar bleiben. Das ist für Strings nützlich, die lesbar bleiben müssen, etwa API-Endpunkte für das Monitoring oder Kennungen von Bibliotheken.

Beispiel:

	{
		reservedStrings: [
			'react-native',
			'\.\/src\/test',
			'some-string_\d'
		]
	}

seed

Type: string|number Default: 0

Diese Option legt den Startwert (Seed) für den Zufallsgenerator fest. Das ist nützlich, um reproduzierbare Ergebnisse zu erhalten.

Ist der Seed 0, arbeitet der Zufallsgenerator ohne Startwert.

selfDefending

Type: boolean Default: false

⚠️ Verändern Sie den obfuskierten Code nach einer Obfuskierung mit dieser Option in keiner Weise, denn jede Änderung – etwa das Uglifying des Codes – kann die Selbstverteidigung auslösen, sodass der Code nicht mehr funktioniert!
⚠️ Diese Option setzt compact zwangsweise auf true
⚠️ Diese Option wird stillschweigend deaktiviert, wenn vmObfuscation aktiviert ist. Verwenden Sie stattdessen vmSelfDefending.

Diese Option macht den Ausgabecode widerstandsfähig gegen Neuformatierung und das Umbenennen von Variablen. Wendet jemand einen JavaScript-Beautifier auf den obfuskierten Code an, funktioniert der Code nicht mehr, was sein Verständnis und seine Veränderung erschwert.

simplify

Type: boolean Default: true

Aktiviert zusätzliche Code-Obfuskierung durch Vereinfachung.

⚠️ In künftigen Releases wird die Obfuskierung von boolean-Literalen (true => !![]) unter diese Option verschoben.

Beispiel:

// 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

Aktiviert die Generierung einer Source Map für den obfuskierten Code.

Source Maps können hilfreich sein, um obfuskierten JavaScript-Quellcode zu debuggen. Wenn Sie in der Produktion debuggen möchten oder müssen, können Sie die separate Source-Map-Datei an einem geheimen Ort ablegen und Ihren Browser dorthin verweisen.

sourceMapBaseUrl

Type: string Default: ``

Legt die Basis-URL für die Import-URL der Source Map fest, wenn sourceMapMode: 'separate' gesetzt ist.

CLI-Beispiel:

javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'

Ergebnis:

//# sourceMappingURL=http://localhost:9000/out.js.map

sourceMapFileName

Type: string Default: ``

Legt den Dateinamen der ausgegebenen Source Map fest, wenn sourceMapMode: 'separate' gesetzt ist.

CLI-Beispiel:

javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example

Ergebnis:

//# sourceMappingURL=http://localhost:9000/example.js.map

sourceMapMode

Type: string Default: separate

Legt den Modus der Source-Map-Generierung fest:

  • inline – hängt die Source Map an das Ende jeder .js-Datei an;
  • separate – erzeugt eine zugehörige '.map'-Datei mit der Source Map. Führen Sie den Obfuscator über die CLI aus, wird am Ende der Datei mit dem obfuskierten Code ein Verweis auf die Source-Map-Datei eingefügt: //# sourceMappingUrl=file.js.map.

sourceMapSourcesMode

Type: string Default: sources-content

Ermöglicht die Steuerung der Felder sources und sourcesContent der Source Map:

  • sources-content – fügt ein Platzhalter-Feld sources sowie ein Feld sourcesContent mit dem ursprünglichen Quellcode hinzu;
  • sources – fügt ein Feld sources mit einer gültigen Quellenbeschreibung hinzu, jedoch kein Feld sourcesContent. Bei Verwendung der NodeJS-API muss die Option inputFileName definiert werden, deren Wert als Inhalt des Feldes sources verwendet wird.

splitStrings

Type: boolean Default: false

Teilt String-Literale in Blöcke der Länge auf, die mit der Option splitStringsChunkLength festgelegt wird.

Beispiel:

// input
(function(){
    var test = 'abcdefg';
})();

// output
(function(){
    var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();

splitStringsChunkLength

Type: number Default: 10

Legt die Blocklänge für die Option splitStrings fest.

stringArray

Type: boolean Default: true

Entfernt String-Literale und legt sie in einem speziellen Array ab. So wird zum Beispiel der String "Hello World" in var m = "Hello World"; durch etwas wie var m = _0x12c456[0x1]; ersetzt

stringArrayCallsTransform

Type: boolean Default: false

⚠️ Die Option stringArray muss aktiviert sein

Aktiviert die Transformation der Aufrufe des stringArray. Alle Argumente dieser Aufrufe können – abhängig vom Wert von stringArrayCallsTransformThreshold – in ein separates Objekt ausgelagert werden. Dadurch wird es noch schwerer, Aufrufe des String-Arrays automatisch aufzuspüren.

Beispiel:

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

⚠️ Die Optionen stringArray und stringArrayCallsTransformThreshold müssen aktiviert sein

Mit dieser Einstellung passen Sie die Wahrscheinlichkeit (von 0 bis 1) an, mit der Aufrufe des String-Arrays transformiert werden.

stringArrayEncoding

Type: string[] Default: []

⚠️ Die Option stringArray muss aktiviert sein

Diese Option kann Ihr Skript verlangsamen.

Codiert alle String-Literale des stringArray mit base64 oder rc4 und fügt speziellen Code ein, der sie zur Laufzeit wieder decodiert.

Jeder stringArray-Wert wird mit einer zufällig aus der übergebenen Liste ausgewählten Codierung codiert. Dadurch lassen sich mehrere Codierungen gleichzeitig verwenden.

Verfügbare Werte:

  • 'none' (boolean): codiert den stringArray-Wert nicht
  • 'base64' (string): codiert den stringArray-Wert mit base64
  • 'rc4' (string): codiert den stringArray-Wert mit rc4. Etwa 30–50 % langsamer als base64, dafür sind die ursprünglichen Werte schwerer zu ermitteln.

Mit den folgenden Optionswerten bleibt zum Beispiel ein Teil der stringArray-Werte uncodiert, während andere Werte mit base64- und rc4-Codierung codiert werden:

stringArrayEncoding: [
    'none',
    'base64',
    'rc4'
]

stringArrayIndexesType

Type: string[] Default: ['hexadecimal-number']

⚠️ Die Option stringArray muss aktiviert sein

Ermöglicht die Steuerung des Typs der Indizes von String-Array-Aufrufen.

Jeder Index eines stringArray-Aufrufs wird mit einem zufällig aus der übergebenen Liste ausgewählten Typ transformiert. Dadurch lassen sich mehrere Typen gleichzeitig verwenden.

Verfügbare Werte:

  • 'hexadecimal-number' (default): transformiert die Indizes von String-Array-Aufrufen zu hexadezimalen Zahlen
  • 'hexadecimal-numeric-string': transformiert die Indizes von String-Array-Aufrufen zu hexadezimalen numerischen Strings

Vor Version 2.9.0 hat javascript-obfuscator alle Indizes von String-Array-Aufrufen mit dem Typ hexadecimal-numeric-string transformiert. Das erschwert die manuelle Deobfuskierung geringfügig, erlaubt aber automatischen Deobfuskatoren, diese Aufrufe leicht zu erkennen.

Der neue Typ hexadecimal-number erschwert das automatische Erkennen der Aufrufmuster des String-Arrays im Code.

Weitere Typen werden künftig hinzukommen.

stringArrayIndexShift

Type: boolean Default: true

⚠️ Die Option stringArray muss aktiviert sein

Aktiviert eine zusätzliche Indexverschiebung für alle String-Array-Aufrufe

stringArrayRotate

Type: boolean Default: true

⚠️ stringArray muss aktiviert sein

Verschiebt das stringArray-Array um eine feste, bei der Obfuskierung zufällig erzeugte Anzahl von Positionen. Dadurch wird es schwerer, die Reihenfolge der entfernten Strings ihren ursprünglichen Stellen zuzuordnen.

stringArrayShuffle

Type: boolean Default: true

⚠️ stringArray muss aktiviert sein

Mischt die Elemente des stringArray-Arrays zufällig.

stringArrayWrappersCount

Type: number Default: 1

⚠️ Die Option stringArray muss aktiviert sein

Legt die Anzahl der Wrapper für das string array innerhalb jedes Wurzel- oder Funktionsgültigkeitsbereichs fest. Die tatsächliche Anzahl der Wrapper in einem Gültigkeitsbereich ist durch die Anzahl der literal-Knoten in diesem Bereich begrenzt.

Beispiel:

// 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

⚠️ Die Optionen stringArray und stringArrayWrappersCount müssen aktiviert sein

Aktiviert verkettete Aufrufe zwischen den string array-Wrappern.

Beispiel:

// 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

⚠️ Die Option stringArray muss aktiviert sein
⚠️ Derzeit betrifft diese Option nur Wrapper, die durch den Optionswert function von stringArrayWrappersType hinzugefügt werden

Ermöglicht die Steuerung der maximalen Anzahl von Parametern der String-Array-Wrapper. Standard- und Mindestwert ist 2. Empfohlen wird ein Wert zwischen 2 und 5.

stringArrayWrappersType

Type: string Default: variable

⚠️ Die Optionen stringArray und stringArrayWrappersCount müssen aktiviert sein

Ermöglicht die Auswahl des Typs der Wrapper, die durch die Option stringArrayWrappersCount hinzugefügt werden.

Verfügbare Werte:

  • 'variable': fügt Variablen-Wrapper am Anfang jedes Gültigkeitsbereichs ein. Schnelle Ausführung.
  • 'function': fügt Funktions-Wrapper an zufälligen Positionen innerhalb jedes Gültigkeitsbereichs ein. Langsamer als variable, bietet dafür aber eine strengere Obfuskierung.

Es wird dringend empfohlen, für eine stärkere Obfuskierung function-Wrapper zu verwenden, sofern sich ein Performanceverlust auf die obfuskierte Anwendung nicht stark auswirkt.

Beispiel für den Optionswert '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

⚠️ Die Option stringArray muss aktiviert sein

Mit dieser Einstellung passen Sie die Wahrscheinlichkeit (von 0 bis 1) an, mit der ein String-Literal in das stringArray aufgenommen wird.

Diese Einstellung ist besonders bei großem Codeumfang nützlich, denn das string array wird immer wieder aufgerufen, was Ihren Code verlangsamen kann.

stringArrayThreshold: 0 entspricht stringArray: false.

strictMode

Type: boolean | null Default: null

Legt fest, wie der Obfuscator den Code im Hinblick auf den Strict Mode von JavaScript behandeln soll.

Verfügbare Werte:

  • null (Standard) – erkennt den Strict Mode automatisch anhand des Codes. Enthält der Code eine ausdrückliche 'use strict'-Direktive, ES-Modul-Syntax oder Klassenmethoden, wird er als Strict-Mode-Code behandelt. Andernfalls wird der Sloppy Mode angenommen.
  • true – behandelt sämtlichen Code als Strict-Mode-Code, auch ohne ausdrückliche 'use strict'-Direktive. Verwenden Sie diesen Wert, wenn Ihr Code in einem Strict-Mode-Kontext ausgeführt wird (z. B. in ES-Modulen, Bundlern oder modernen Frameworks).
  • false – nur ausdrückliche Strict-Mode-Merkmale ('use strict', ES-Module, Klassenmethoden) gelten als Strict Mode. Die Vererbung aus dem übergeordneten Gültigkeitsbereich greift weiterhin gemäß JS-Spezifikation.

target

Type: string Default: browser

Legt die Zielumgebung für den obfuskierten Code fest.

Verfügbare Werte:

  • browser (Standard) – gewöhnliche Webseiten-Umgebung. Der Ausgabecode ist mit dem für node identisch, einige browserspezifische Optionen dürfen jedoch nicht mit dem Ziel node verwendet werden
  • browser-no-eval – wie browser, die Ausgabe verwendet jedoch kein eval(). Verwenden Sie dieses Ziel, wenn die Zielseite eine Content Security Policy besitzt, die eval/unsafe-eval verbietet.
  • node – Node.js-Umgebung. Browserspezifische Optionen sind deaktiviert (sie benötigen window/document und wären in Node wirkungslos oder würden einen Fehler auslösen). Einige vmSelfDefending-Abwehrmechanismen, die auf reine Browser-APIs angewiesen sind – Erkennung von Headless-Browsern, Wiederherstellung eines sauberen Realms über ein iframe, Anti-Inspector- und DOM-Prüfungen –, werden für dieses Ziel nicht ausgegeben.
  • service-worker – Service-Worker-Kontext. Kein window, kein document, ein anderes globales self.
  • userscript – Sandbox eines Userscript-Managers (z. B. Tampermonkey). Die vmSelfDefending-Abwehrmechanismen werden entsprechend angepasst.
  • bytenode – Node.js-Code, der nach der Obfuskierung mit dem bytenode-Loader kompiliert wird (von V8 zwischengespeicherter Bytecode, .jsc). Der Obfuscator ruft bytenode nicht selbst auf; er gibt VM-obfuskiertes JavaScript aus, dessen Laufzeit so aufgebaut ist, dass sie den Kompilierschritt von bytenode übersteht, und passt die vmSelfDefending-Abwehrmechanismen entsprechend an. Führen Sie bytenode anschließend selbst auf der obfuskierten Ausgabe aus, um die endgültige .jsc-Datei zu erzeugen.

transformObjectKeys

Type: boolean Default: false

Aktiviert die Transformation von Objektschlüsseln.

Beispiel:

// 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

Steuert, welche nicht fatalen Obfuskierungswarnungen über die Methode ObfuscationResult.getWarnings() gemeldet werden.

Verfügbare Werte:

  • 'all' (Standard) – jede Warnung wird gemeldet.
  • 'none' – alle Warnungen werden unterdrückt.
  • ein Objekt, das Warnungstypen auf Wahrheitswerte abbildet – ein auf false gesetzter Typ wird unterdrückt; jeder nicht aufgeführte (oder auf true gesetzte) Typ bleibt aktiv. { "VMGlobalFunctionNamesNotRenamed": false } behält zum Beispiel alle Warnungen bis auf diese eine bei.

Warnungstypen:

  • VMGlobalFunctionNamesNotRenamed – unter vmObfuscation wurden die Namen von Funktionsdeklarationen, Klassendeklarationen und Variablen der obersten Ebene, denen ein Funktions-, Pfeilfunktions- oder Klassenausdruck zugewiesen wurde, unverändert übernommen (die Option renameGlobals ist deaktiviert und der Code ist nicht in eine IIFE eingeschlossen). Sie bleiben in der Ausgabe daher lesbar, obwohl die Rümpfe als Bytecode verborgen sind. Exportierte Namen werden nicht gemeldet.
  • VMTopLevelInitializerNotVirtualized – Initialisierer von Variablen der obersten Ebene sind trotz VM-Obfuskierung als reines JavaScript erhalten geblieben, weil vmWrapTopLevelInitializers deaktiviert ist oder sie nicht virtualisieren konnte.
  • DynamicCodeRenameRisk – der Code erzeugt zur Laufzeit eine Funktion aus einem String (direktes eval, der Function-Konstruktor oder ein über fn.toString() in ein <script>/einen Worker eingefügter Code), die Bezeichner referenzieren kann, die der Obfuscator umbenannt hat.
  • VMDynamicCodeSkipped – eine Funktion wurde vom Bytecoding der VM ausgenommen, weil sie direktes eval, dynamisches new Function oder Function enthält (siehe vmForceCompileDynamicCode).
  • VMSyncFunctionSkippedInAsyncMode – bei aktiviertem vmAsyncExecutor hat sich eine von Ihnen im comment-Modus ausdrücklich markierte Funktion als synchron erwiesen und wurde übersprungen (in diesem Modus werden nur asynchrone Funktionen virtualisiert).
  • VMAsyncGeneratorSkippedInAsyncMode – bei aktivem vmAsyncExecutor und asynchronem Schlüssel-Getter konnte ein markierter Async-Generator nicht virtualisiert werden (er muss seinen Iterator synchron zurückgeben).
  • BrowserTargetWithNodeStyleCode – der Code sieht danach aus, als ziele er auf Node.js (etwa require('fs'), __dirname, process.argv), während die Option target auf eine browserähnliche Umgebung gesetzt ist.

vmObfuscation

Type: boolean Default: false

Aktiviert die VM-basierte Bytecode-Obfuskierung. Ist sie aktiviert, werden JavaScript-Funktionen in eigenen Bytecode kompiliert, der auf einer eingebetteten virtuellen Maschine läuft. Das bietet das höchste Schutzniveau, da die ursprüngliche Codelogik vollständig umgewandelt wird.

Beispiel: Aus Ihrem lesbaren Code wie return qty * price wird eine Liste von Zahlen wie [0x15,0x03,0x17,...], die nur der eingebettete VM-Interpreter ausführen kann. Die ursprüngliche Logik ist nicht mehr als JavaScript sichtbar.

vmTargetFunctions

Type: string[] Default: []

Legt namentlich fest, welche Funktionen der obersten Ebene genau VM-Schutz erhalten sollen.

Beispiel:

{
    vmObfuscation: true,
    vmTargetFunctions: ['someFunctionName']
}

Ergebnis: Nur diese drei Funktionen erhalten VM-Schutz. Alles andere bleibt normales (aber weiterhin obfuskiertes) JavaScript. Ideal, um sensible Lizenzprüfungen oder Authentifizierungslogik zu schützen und den Rest Ihres Codes schlank zu halten.

vmExcludeFunctions

Type: string[] Default: []

Legt Funktionen der obersten Ebene fest, die niemals VM-Schutz erhalten sollen. Hat Vorrang vor anderen Einstellungen.

Beispiel:

{
    vmObfuscation: true,
    vmExcludeFunctions: ['someFunctionName']
}

Wann verwenden: Performancekritische Funktionen der obersten Ebene (Animationsschleifen, Echtzeit-Datenverarbeitung) lassen sich ausschließen, um den VM-Mehraufwand zu vermeiden, während alles andere geschützt bleibt.

vmTargetFunctionsMode

Type: string Default: root

Steuert, wie Funktionen/Methoden für die VM-Obfuskierung ausgewählt werden.

ModusBeschreibung
rootStandardverhalten. Für die VM-Obfuskierung kommen nur Funktionen der obersten Ebene infrage. Verwendet die Erlaubnisliste vmTargetFunctions und die Sperrliste vmExcludeFunctions zum Filtern.
commentNur Funktionen/Methoden, die mit dem Kommentar /* javascript-obfuscator:vm */ versehen sind, werden VM-obfuskiert. Funktioniert mit Funktionen/Methoden auf jeder Verschachtelungsebene.

Beispiel – Comment-Modus:

// 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'
}

Wann verwenden: Wenn Sie punktgenau steuern müssen, welche Funktionen VM-Schutz erhalten – insbesondere verschachtelte Funktionen mit sensibler Logik. Anders als vmTargetFunctions, das nur mit benannten Funktionen der obersten Ebene funktioniert, können Sie im Comment-Modus jede beliebige Funktion an jeder Stelle Ihres Codes schützen.

vmForceCompileDynamicCode

Type: boolean Default: false

Steuert, was die VM-Obfuskierung mit einer Funktion tut, die einen direkten eval-, new Function(...)- oder Function(...)-Aufruf enthält.

Standardmäßig wird eine solche Funktion (und jede darin definierte Funktion) vom Bytecoding der VM ausgenommen, und über result.getWarnings() wird eine Warnung VMDynamicCodeSkipped gemeldet. Der Grund: Der zur Laufzeit erzeugte Quellcode kann Bezeichner aus der umgebenden Gültigkeitsbereichskette referenzieren – Bezeichner, die der Obfuscator umbenannt hat.

Ist der Wert true, wird die Funktion trotzdem in Bytecode überführt und die Warnung VMDynamicCodeSkipped nicht mehr ausgegeben.

Die separate Warnung DynamicCodeRenameRisk wird unabhängig von dieser Option weiterhin ausgelöst, denn das darin beschriebene Umbenennungsrisiko ist unabhängig vom VM-Überspringen – das Aktivieren dieser Option macht das zugrunde liegende Muster nicht sicherer.

// Source code
function loadConfig(src) {
    return eval(src);
}
loadConfig('1 + 2');
// Options
{
    vmObfuscation: true,
    vmForceCompileDynamicCode: true
}

Bei ausgeschalteter Option (Standard) bleibt loadConfig reines JavaScript. Bei eingeschalteter Option wird loadConfig wie jede andere Funktion in VM-Bytecode kompiliert. Verwenden Sie diese Option, wenn Sie die Aufrufstelle geprüft haben und wissen, dass der zur Laufzeit erzeugte Code nicht von durch Closures umbenannten Bezeichnern abhängt.

vmWrapTopLevelInitializers

Type: boolean Default: false

Schließt einige Initialisierer von Variablen der obersten Ebene in IIFEs (Immediately Invoked Function Expressions) ein, damit sie VM-obfuskiert werden können.

Was sie tut: Ohne diese Option bleiben Konstanten und Variablen der obersten Ebene in der Ausgabe sichtbar:

// Input
const MY_STRING = "my-string";

// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string";  // String is visible!

Mit aktivierter Option wird der Initialisierer in eine IIFE eingeschlossen, die VM-obfuskiert wird:

// Input
const MY_STRING = "my-string";

// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })();  // String hidden in bytecode

Hinweis: Diese Option funktioniert nur, wenn vmTargetFunctionsMode den Wert 'root' (Standard) hat.

Warnungen: Sobald ein Initialisierer der obersten Ebene trotz VM-Obfuskierung als reines JavaScript erhalten bleibt, wird eine Warnung VMTopLevelInitializerNotVirtualized mit den betroffenen Variablennamen gemeldet. Das umfasst: eine deaktivierte Option, Initialisierer, die diese Option überspringen musste (jeweils mit Grund – etwa weil der Initialisierer einen benachbarten Deklarator referenziert oder ein Top-Level-await enthält), sowie den vmAsyncExecutor-Modus, in dem sich die synchronen Wrapper überhaupt nicht virtualisieren lassen.

vmDynamicOpcodes

Type: boolean Default: false

Macht den VM-Interpreter kleiner und für jeden Build einzigartig.

Was sie tut:

  1. Filtert ungenutzte Instruktionen – Verwendet Ihr Code keine Klassen, werden klassenbezogene Instruktionen vollständig entfernt
  2. Randomisiert die Struktur – Die Reihenfolge der Instruktions-Handler wird bei jedem Build neu gemischt

Das Ergebnis: eine kleinere Ausgabe, und jeder Build sieht anders aus.

vmBytecodeEncoding

Type: boolean Default: false

Codiert jede Bytecode-Instruktion. Die Instruktionen werden während der Ausführung einzeln decodiert.

vmBytecodeArrayEncoding

Type: boolean Default: false

Codiert das gesamte Bytecode-Array als einen einzigen Block. Das Array wird einmalig beim Start decodiert, bevor die Ausführung beginnt. Verwenden Sie diese Option zusammen mit vmBytecodeEncoding für zwei Schutzschichten.

vmBytecodeArrayEncodingKey

Type: string Default: ''

Eigener Verschlüsselungsschlüssel für die Codierung des Bytecode-Arrays. Ist er gesetzt, wird dieser Schlüssel anstelle des standardmäßig aus der Umgebung abgeleiteten Schlüssels verwendet. Der Schlüssel muss zur Laufzeit über vmBytecodeArrayEncodingKeyGetter bereitgestellt werden.

Diese Option externalisiert den Verschlüsselungsschlüssel – er ist nicht im obfuskierten Code selbst eingebettet. Der Schlüssel ist zur Laufzeit zwar weiterhin zugänglich (und damit nicht wirklich geheim), doch diese Trennung verhindert, dass Werkzeuge zur statischen Analyse den Schlüssel allein durch Untersuchung des Codes finden.

Wichtig: Der Schlüssel muss synchron verfügbar sein, wenn der obfuskierte Code geladen wird. Verwenden Sie einen synchronen Speicher wie Cookies, localStorage, sessionStorage, globale Variablen oder DOM-Elemente (z. B. servergesetzte Meta-Tags). Asynchrone Methoden wie fetch() können im Ausdruck des Schlüssel-Getters nicht direkt verwendet werden.

vmBytecodeArrayEncodingKeyGetter

Type: string Default: ''

Synchroner JavaScript-Ausdruck, der den Verschlüsselungsschlüssel zur Laufzeit zurückgibt. Dieser Ausdruck wird ausgewertet, wenn der obfuskierte Code geladen wird, und muss denselben Schlüssel zurückgeben, der in vmBytecodeArrayEncodingKey angegeben wurde. Um den Schlüssel asynchron aufzulösen (ein Promise), aktivieren Sie vmAsyncExecutor.

Hinweis: Ein Getter, der ein Promise zurückgibt, erfordert vmAsyncExecutor. Das lässt sich zur Build-Zeit nicht prüfen, daher schlägt ein Promise-Getter bei ausgeschaltetem vmAsyncExecutor zur Laufzeit fehl – der Decoder erhält das Promise statt des Schlüssels.

Der obfuskierte Code funktioniert nur, wenn der Schlüssel-Getter genau denselben Schlüssel zurückgibt, der bei der Obfuskierung verwendet wurde. Stimmen die Schlüssel nicht überein, schlägt die Entschlüsselung fehl und der Code erzeugt Datenmüll oder Fehler. Gibt der Schlüssel-Getter undefined, null oder einen leeren String zurück, löst der Code einen Fehler aus: „VM decryption key not available“.

Wichtig: Bewahren Sie den Schlüssel nicht in derselben Datei bzw. demselben Skript wie den obfuskierten Code auf – wird er dort eingebettet, kann selbst ein rein statischer Scan des Bundles ihn wiederherstellen. Legen Sie ihn stattdessen in einer separaten Quelle ab: servergesetzte Cookies, ein von einem anderen Skript befülltes localStorage, ein servereingefügtes HTML-Meta-Tag, eine von einem anderen Skript gesetzte globale Variable oder (mit vmAsyncExecutor) zur Laufzeit von Ihrem Backend abgerufen.

Wird der Schlüssel von Ihrem Backend abgerufen (über vmAsyncExecutor), fügen Sie diesem Endpunkt sitzungs- oder ursprungsbasierte Prüfungen hinzu: Geben Sie echten Nutzern (gültige Sitzung, erwarteter Origin/Referer) den richtigen Schlüssel zurück und verdächtigen Anfragen (etwa ein localhost/unerwarteter Ursprung, keine Sitzung) einen Datenmüll-Schlüssel. Echte Nutzer laufen normal; eine Kopie, die außerhalb Ihrer Umgebung läuft, erhält einen Schlüssel, der zu nichts entschlüsselt. Die genaue Logik hängt von Ihrer Website ab.

Beispiele:

// 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())'

Anwendungsbeispiel:

// 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

Aktiviert den asynchronen VM-Executor, der es vmBytecodeArrayEncodingKeyGetter erlaubt, ein Promise zurückzugeben (ein asynchroner Schlüssel-Getter) – so kann der Entschlüsselungsschlüssel zur Laufzeit abgerufen werden (Netzwerkanfrage, IndexedDB usw.), statt beim Laden des Codes synchron verfügbar sein zu müssen.

Dringend empfohlen für vollständig asynchrone Codebasen. In diesem Modus werden nur async-Funktionen virtualisiert – eine synchrone Funktion lässt sich nicht asynchron machen, ohne ihren Rückgabewert in ein Promise zu verwandeln und ihre Aufrufer zu beschädigen –, daher erzielt durchgängig asynchroner Code die höchste Abdeckung. Er funktioniert auch, wenn die Wurzel synchron ist (etwa eine synchrone IIFE / ein UMD-Wrapper): Die äußersten async-Funktionen darin werden geschützt, die synchronen Teile bleiben unverändert.

Was transformiert wird: jede äußerste async-Funktion, wo immer sie auftritt (auch verschachtelt innerhalb synchroner Wrapper). Die äußerste async-Funktion jeder Kette ist die geschützte Einheit – alles in ihr, synchron wie asynchron, wird mit einkompiliert. Synchrone Funktionen und einfache Generatoren bleiben unobfuskiert.

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
    }
}

Übersprungenes und Warnungen. Async-Generatoren bleiben bei aktivem asynchronem Schlüssel-Getter ebenfalls unobfuskiert (ein Async-Generator muss seinen Iterator synchron zurückgeben und kann nicht auf den Schlüssel warten). Im standardmäßigen vmTargetFunctionsMode: 'root' erfolgen Auslassungen still (die Auswahl ist automatisch); im comment-Modus wird über ObfuscationResult.getWarnings() eine Warnung ausgegeben, sobald sich eine von Ihnen ausdrücklich markierte Funktion nicht virtualisieren lässt – weil sie sich als synchron erwiesen hat oder ein Async-Generator unter einem asynchronen Schlüssel-Getter ist.

Der asynchrone Schlüssel-Getter erfordert zusätzlich vmBytecodeArrayEncoding mit einem vmBytecodeArrayEncodingKeyGetter.

Anwendungsbeispiel:

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

Codiert die Sprungziele im Bytecode. Die Sprungoffsets werden zur Laufzeit berechnet und verbergen so die Kontrollflussstruktur (if/else, Schleifen usw.) vor der statischen Analyse.

vmMacroOps

Type: boolean Default: false

Fasst häufige Instruktionsfolgen zu einzelnen „Makro“-Opcodes zusammen. Aus LOAD + ADD + STORE kann zum Beispiel eine einzelne Instruktion MACRO_ADD_TO_VAR werden. Das durchbricht die Mustererkennung und kann die Performance verbessern.

vmDebugProtection

Type: boolean Default: false

Fügt der VM-Laufzeit mehrschichtige Abwehrmechanismen gegen Debugging, Analyse und LLMs hinzu. Funktioniert am besten mit den Zielen browser/browser-no-eval.

vmSelfDefending

Type: boolean Default: false

Fügt der VM-Laufzeit mehrschichtigen Schutz vor Manipulation, Hooking und Reverse Engineering hinzu.

⚠️ Diese Option aktiviert zwangsweise vmBytecodeArrayEncoding.

⚠️ Erkennung sensibler Umgebungen. Diese Option bindet den obfuskierten Code an seine Ziel-Laufzeitumgebung und nutzt fortgeschrittenes Browser-Fingerprinting, um Automatisierungswerkzeuge zu erkennen. Mit dieser Option geschützter Code bricht absichtlich ab, wenn er ausgeführt wird in:

  • Headless-Browsern (Headless Chrome/Chromium, PhantomJS)
  • Browser-Automatisierungswerkzeugen (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
  • Node.js (wenn target auf browser gesetzt ist)
  • jsdom oder ähnlichen serverseitigen DOM-Emulationen
  • Umgebungen, in denen native Browser-Builtins gehookt oder ersetzt wurden

Der Code funktioniert korrekt in normalen Browsern (Chrome, Firefox, Safari, Edge), auch wenn er innerhalb von iframes, Browser-Erweiterungen (Content Scripts) und Web Workern geladen wird. Wenn Sie automatisierte Tests gegen geschützten Code ausführen müssen, deaktivieren Sie vmSelfDefending für Test-Builds – diese Option soll die automatisierte Analyse verhindern und kann mit keinem Automatisierungs-Framework sicher verwendet werden.

Es wird dringend empfohlen, diese Option zusammen mit vmDebugProtection, vmBytecodeArrayEncodingKey und vmBytecodeArrayEncodingKeyGetter zu verwenden.

vmDefenseHook

Type: { name: string, aliases?: object } Default: ''

vmDefenseHook nimmt ein Objekt mit zwei Schlüsseln entgegen: name (erforderlich) und aliases (optional).

name ist eine globale Funktion, die Ihre Host-Seite definiert und die eine VM-Abwehr (vmDebugProtection / vmSelfDefending) mit einem Signalobjekt aufruft, sobald sie ein feindliches Signal erkennt – einen Debugger oder Inspector, einen Headless-/Automatisierungsbrowser, einen Prozess eines KI-Coding-Agenten, eine unzulässige Domain und so weiter. Verwenden Sie sie, um das Ereignis an Ihr Backend zu melden (etwa navigator.sendBeacon). Der Hook ist ein reiner Telemetrie-Empfänger: Sein Rückgabewert wird ignoriert, und ein fehlender oder auslösender Hook ist ein stiller No-op, der niemals eine Abwehr deaktivieren kann. Um zu ändern, was eine Abwehr bei einer Erkennung tut, verwenden Sie vmDefenseReaction.

aliases benennt optional die Felder dieses Signalobjekts um – behandelt weiter unten unter Die Signalfelder umbenennen.

Das Signalobjekt. Der Hook erhält ein einzelnes signal:

  • source – der konkrete Detektor, der ausgelöst hat (siehe Tabelle).
  • category – die Gruppe, unter der er meldet: automation (nichtmenschliche Browser), debugger (ein Debugger/Inspector ist aktiv), sandbox (instrumentierter/vorgetäuschter Host), domain (Verstoß gegen die Domain-Sperre), tamper (Builtins zur Laufzeit gepatcht) oder integrity (der VM-eigene Code wurde verändert).
  • score / threshold – wie stark der Detektor ausgelöst hat und der Wert, den er erreichen musste; der Hook feuert erst, sobald score >= threshold. Die meisten Prüfungen sind Alles-oder-nichts (ein einzelnes eindeutiges Signal); headless summiert mehrere Signale der Browser-Form, sodass sein score in der Regel höher ist als sein threshold.
sourceerkenntcategory
integrityder obfuskierte VM-Code selbst wurde verändertintegrity
nodefür den Browser gedachter Code, der unter Node.js läuftdebugger
debuggereine angehängte oder aktive Debugger- bzw. Inspector-Sitzung oder eine Debug-Umgebungdebugger
headlessein Headless-Browser wird zum Ausführen des Codes verwendetautomation
agentein KI-Coding-Agent, der den Code ausführtautomation
timingeine Ausführungspause, die auf einen Breakpoint oder einen schrittweise arbeitenden Debugger hindeutetdebugger
sandboxder Code läuft in einer Sandbox oder einer vorgetäuschten Host-Umgebungsandbox
domainder Ursprung der Seite steht nicht in der Erlaubnisliste von vmDomainLockdomain
nativeHookeine native Builtin-Funktion wurde ersetzt oder gehookttamper

Den Hook registrieren. Definieren Sie ihn als einfache globale Funktion bevor das obfuskierte Bundle geladen wird – die VM-Laufzeit und ihre Abwehrmechanismen laufen vor Ihrem (geschützten) Programm, sodass viele Erkennungen bereits während des Starts feuern:

// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }

Ein innerhalb des obfuskierten Quellcodes definierter Hook wird zu spät registriert, um Erkennungen zur Startzeit abzufangen, und falls er VM-kompiliert wird, ist er erst erreichbar, wenn Ihr Programm läuft. Er ist ohnehin abgesichert (ein fehlender Hook ist ein No-op, und ein Re-entrancy-Schutz verhindert Ausuferungen), doch für vollständige Abdeckung registrieren Sie ihn vorab. Um dennoch Ihre Meldelogik zu schützen, halten Sie den registrierten Hook als einzeiligen Puffer ((window.__vmDet = window.__vmDet || []).push(signal)) und lesen bzw. senden Sie diesen Puffer aus Ihrem obfuskierten Code.

Die Signalfelder umbenennen (aliases). Die Standardwerte von source/category sind beschreibende Namen, sodass jeder, der den Callback instrumentiert (oder die Ausgabe liest), den Schutz erkennen kann und weiß, welcher Detektor ausgelöst hat. aliases benennt Signalfelder in undurchsichtige Tokens Ihrer Wahl um, angewendet innerhalb der VM bevor das Signal ausgegeben wird, sodass diese Namen nie in der Ausgabe auftauchen oder den Callback erreichen. Ihre App kennt ihre eigene Zuordnung und leitet die Tokens an Ihr Backend weiter.

Die Aliase gelten pro Feld und halten das Umbenennen von Schlüsseln und Werten getrennt: Jedes Feld nimmt einen key (den Eigenschaftsnamen, den der Callback erhält); die string-basierten Namensfelder source und category nehmen zusätzlich eine values-Zuordnung, während score/threshold Zahlen sind und nur einen key nehmen. Die Namen, die Sie zuordnen können (alles andere wird zur Build-Zeit abgelehnt):

  • Feldschlüsselsource, category, score, threshold
  • source-Werteheadless, agent, node, debugger, timing, sandbox, domain, nativeHook, integrity
  • category-Werteautomation, 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> }
}

Dies dient der Vermeidung von Fingerprints, nicht der Geheimhaltung – die Zuordnung lässt sich durch wiederholtes Testen weiterhin erschließen –, sodass ihr einziger Nutzen darin besteht, keine stabilen, selbsterklärenden Namen preiszugeben. Nicht gesetzte Einträge behalten ihre Standardnamen.

Ein einfacher String (vmDefenseHook: '__vmDetection') wird als Kurzform für { name: '__vmDetection' } akzeptiert, ist aber veraltet – bevorzugen Sie die Objektform.

vmDefenseReaction

Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }

Konfiguriert, wie jede Erkennungskategorie reagiert. Sie aktiviert nichts – die Abwehrmechanismen selbst werden durch vmSelfDefending, vmDebugProtection und vmDomainLock eingeschaltet; diese Option wählt nur aus, wie eine aktivierte Abwehr reagiert. Die Kategorie ist die Steuerungseinheit – jeder Detektor einer Kategorie setzt die Reaktion dieser Kategorie um.

Jede Kategorie fasst die Detektoren zusammen, die auf eine bestimmte Art feindlicher Bedingung achten. Eine Kategorie reagiert nur, wenn die Option aktiviert ist, die ihre Detektoren ausgibt:

KategorieAktiviert durchReagiert, wenn
automationvmSelfDefending oder vmDebugProtectionDer Code wird von Software statt von einer Person gesteuert: ein Headless- oder automatisierter Browser, ein Scraping-/Test-Framework oder ein KI-Coding-Agent, der die Seite schrittweise durchgeht.
debuggervmDebugProtection oder vmSelfDefendingJemand hat einen Debugger oder den Inspector der Browser-Entwicklertools geöffnet und geht den laufenden Code schrittweise durch, um ihn zu verstehen.
sandboxvmDebugProtectionDer Code läuft überhaupt nicht in einem echten Browser – er wurde in eine emulierte oder skriptgesteuerte JavaScript-Umgebung überführt, um dort ausgeführt und offline untersucht zu werden.
domainvmDomainLockDer Code läuft auf einer Website, die Sie nicht autorisiert haben: ein Host, der nicht in Ihrer Erlaubnisliste von vmDomainLock steht (etwa Ihr Bundle, das auf die Domain eines anderen kopiert wurde).
tampervmSelfDefendingDie JavaScript-Umgebung rund um die VM wurde verändert, um sie zu beobachten oder zu kapern, etwa durch native Browser-Builtins, die gegen instrumentierte Versionen ausgetauscht wurden.
integrityvmSelfDefendingDer eigene Code des geschützten Bundles wurde seit seiner Erzeugung bearbeitet oder gepatcht.

Jede Kategorie ist einer oder mehreren der Optionen vmSelfDefending, vmDebugProtection und vmDomainLock zugeordnet; es gibt keine Kategorie außerhalb dieser drei Optionen, und eine Reaktion, die für eine Kategorie gesetzt ist, deren Option ausgeschaltet ist, hat schlicht keine Wirkung.

Schlüssel sind diese sechs Kategorienamen oder default (ein Rückfall für nicht angegebene Kategorien). Werte sind:

  • break – sofort abbrechen
  • decoy – auf vergiftetem Zustand weiterlaufen und dabei stillschweigend falsche Ergebnisse erzeugen
  • none – lokal nichts tun (nur Telemetrie)

Die kategoriespezifischen Standardwerte sind oben angegeben; eine Kategorie, die Sie nicht setzen (oder auf ihren Standardwert setzen), verwendet diesen Standard. default erreicht jede Kategorie, auch die per Konstruktion korrekten (integrity, tamper), sodass { default: 'none' } ein tatsächlich nicht abbrechender, reiner Telemetrie-Build ist:

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

Lässt die Bedeutung der Opcodes von der Position im Bytecode abhängen. Jede Position hat eine andere, aus einem Seed abgeleitete Zuordnung von Opcode zu Handler, sodass dieselbe Opcode-Nummer an unterschiedlichen Positionen unterschiedliche Operationen ausführt.

vmCallContextOpcodes

Type: boolean Default: false

Lässt eine geschützte Funktion davon abhängen, von wo aus sie aufgerufen wird, sodass sie sich nicht aus dem Code herauslösen und für sich allein ausführen oder analysieren lässt – sie verhält sich nur korrekt, wenn sie über ihre echten Aufrufstellen im Programm aufgerufen wird. Diese Option beeinträchtigt die Laufzeit-Performance.

Derzeit werden nur die folgenden Konstruktionen unterstützt:

  • Funktionsdeklarationen (function f() {});
  • einer Variablen zugewiesene Funktionsausdrücke und Pfeilfunktionen (const f = () => {});
  • private Instanzmethoden (this.#m()).

In jedem Fall muss die Funktion stets über einen direkten Aufruf erreicht werden (f(), this.#m()). Wird sie in einer anderen Variablen gespeichert, als Argument übergeben oder anderweitig als Wert verwendet, bleibt sie ungeschützt. Async-Funktionen werden unterstützt, Generatoren nicht.

Diese Option ist experimentell und kann Ihren Code beschädigen; testen Sie die Ausgabe daher gründlich, bevor Sie sie einsetzen.

vmStackEncoding

Type: boolean Default: false

Verschlüsselt die Werte auf dem VM-Stack während der Ausführung. Werte werden beim Ablegen codiert und beim Entnehmen decodiert, sodass eine Speicheruntersuchung verschlüsselte Daten statt der tatsächlichen Werte zeigt.

Diese Option beeinträchtigt die Performance stark.

vmCompactDispatcher

Type: boolean Default: false

Verwendet einen einzigen VM-Executor statt zweier Executoren (synchron + Generator). Reduziert die Größe des obfuskierten Codes, fügt aber bei rekursionsintensivem Code etwa 20 % Performance-Mehraufwand hinzu.

  • false (Standard): zwei Executoren – optimale Performance, größere Ausgabe
  • true: ein Executor – kleinere Ausgabe, etwas langsamer

vmStringArrayBytecodeOnly

Type: boolean Default: false

Ist die Option aktiviert, extrahiert das String-Array ausschließlich Strings aus Bytecode-Daten – keine anderen Strings im Code werden transformiert. Dadurch wird stringArray zwangsweise aktiviert, selbst wenn es nicht ausdrücklich gesetzt ist.

Warum verwenden: Sämtliche VM-Laufzeit-Strings in ein String-Array zu extrahieren, ist langsam. Diese Option richtet die String-Array-Extraktion nur auf Bytecode-Inhalte aus und verbessert so die Performance, während die Bytecode-Konstanten weiterhin geschützt bleiben.

  • Bei vmBytecodeArrayEncoding: false werden Strings innerhalb der Bytecode-Konstantenpools (c-Arrays) extrahiert
  • Bei vmBytecodeArrayEncoding: true werden die base64-codierten Bytecode-Strings der obersten Ebene extrahiert
  • stringArrayThreshold steuert weiterhin, welcher Prozentsatz dieser Bytecode-Strings extrahiert wird

vmDomainLock

Type: string[] Default: []

⚠️ Diese Option funktioniert nicht mit target: 'node', target: 'service-worker' oder target: 'bytenode'

Beschränkt den obfuskierten Code auf bestimmte Domains und/oder Subdomains und ist deutlich schwerer aufzuspüren und zu entfernen als domainLock.

Wird der Quellcode nicht auf den mit dieser Option angegebenen Domains ausgeführt, leitet der Browser auf die an vmDomainLockRedirectUrl übergebene URL um, und weitere geschützte Aufrufe liefern selbst dann falsche Ergebnisse, wenn die Weiterleitung unterdrückt wird.

Mehrere Domains und Subdomains

Sie können Ihren Code an mehr als eine Domain oder Subdomain binden. Um ihn zum Beispiel so zu sperren, dass er nur auf www.example.com läuft, fügen Sie www.example.com hinzu. Damit er auf der Root-Domain einschließlich aller Subdomains läuft (example.com, sub.example.com), verwenden Sie .example.com.

vmDomainLockRedirectUrl

Type: string Default: about:blank

⚠️ Diese Option funktioniert nicht mit target: 'node', target: 'service-worker' oder target: 'bytenode'

Leitet den Browser auf eine übergebene URL um, wenn der Quellcode nicht auf den unter vmDomainLock angegebenen Domains ausgeführt wird.

Preset Options

Hohe Obfuskierung, geringe Performance

Die Performance ist deutlich schlechter als ohne Obfuskierung

{
    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
}

Mittlere Obfuskierung, optimale Performance

Die Performance ist schlechter als ohne Obfuskierung

{
    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
}

Geringe Obfuskierung, hohe Performance

Die Performance bleibt auf einem relativ normalen Niveau

{
    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
}

Standardvoreinstellung, hohe Performance

{
    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
}

VM Ultra High – Obfuskierung (maximale Sicherheit)

Diese Voreinstellung aktiviert die VM-basierte Bytecode-Obfuskierung mit allen Härtungsfunktionen einschließlich indirektem Dispatch. Bietet den stärksten Schutz, jedoch mit größerer Ausgabe und deutlich langsamerer Ausführung.

{
    optionsPreset: 'vm-ultra-high-obfuscation'
}

Oder einzeln konfigurieren:

{
    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 (Schutz vor KI-Agenten)

Diese Voreinstellung ist eigens dafür ausgelegt, KI-Agenten und LLMs am Reverse Engineering von VM-Bytecode-Code zu hindern. Basiert auf vm-default mit aktiviertem Self Defending und Debug Protection. Leichter als vm-high-obfuscation, aber gezielt gegen automatisierte Analyse gehärtet.

{
    optionsPreset: 'vm-anti-llm'
}

Enthält:

  • VM-Bytecode-Obfuskierung mit String-Array (aus vm-default)
  • vmSelfDefending – Anti-Hook-Erkennung, Integritäts-Hash, Quell-Fingerprint, iframe-basierte Verifikation eines sauberen Realms, ARX-Cipher-Schlüsselableitung
  • vmDebugProtection – Anti-Debugging-Prüfungen in der VM-Dispatch-Schleife
  • debugProtection: false – keine veraltete Debug Protection (der VM-Debug-Schutz ist überlegen)

VM High – Obfuskierung (höchste Sicherheit)

Diese Voreinstellung aktiviert die VM-basierte Bytecode-Obfuskierung mit den meisten Härtungsfunktionen. Bietet starken Schutz bei besserer Performance als die Ultra-High-Voreinstellung.

{
    optionsPreset: 'vm-high-obfuscation'
}

Oder einzeln konfigurieren:

{
    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
}

VM Medium – Obfuskierung (ausgewogene Sicherheit)

Diese Voreinstellung aktiviert die VM-basierte Bytecode-Obfuskierung mit einem ausgewogenen Satz an Härtungsfunktionen. Guter Kompromiss zwischen Sicherheit und Performance.

{
    optionsPreset: 'vm-medium-obfuscation'
}

Oder einzeln konfigurieren:

{
    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
}

VM Low – Obfuskierung (Basissicherheit, bessere Performance)

Diese Voreinstellung aktiviert eine grundlegende VM-basierte Bytecode-Obfuskierung ohne zusätzliche Härtungsfunktionen. Gute Balance zwischen Sicherheit und Ausgabegröße.

{
    optionsPreset: 'vm-low-obfuscation'
}

Oder einzeln konfigurieren:

{
    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- + String-Array-Schutz)

Diese Voreinstellung kombiniert eine grundlegende VM-basierte Bytecode-Obfuskierung mit String-Array-Schutz. Guter Ausgangspunkt für die VM-Obfuskierung mit String-Schutz.

{
    optionsPreset: 'vm-default'
}

Oder einzeln konfigurieren:

{
    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

Kompakte Codeausgabe in einer einzigen Zeile.

config

Type: string Default: ``

Name der JS-/JSON-Konfigurationsdatei, die die Obfuscator-Optionen enthält. Diese Werte werden von Optionen überschrieben, die direkt an die CLI übergeben werden

controlFlowFlattening

Type: boolean Default: false

⚠️ Diese Option beeinträchtigt die Performance erheblich – bis zu 1,5-mal langsamere Laufzeitgeschwindigkeit. Mit controlFlowFlatteningThreshold legen Sie fest, welcher Prozentsatz der Knoten vom Control Flow Flattening betroffen ist.

Aktiviert das Einebnen des Kontrollflusses (Control Flow Flattening). Control Flow Flattening ist eine Strukturtransformation des Quellcodes, die das Verständnis des Programms erschwert.

Beispiel:

// 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

Die Wahrscheinlichkeit, mit der die Transformation controlFlowFlattening auf einen einzelnen Knoten angewendet wird.

Diese Einstellung ist besonders bei großem Codeumfang nützlich, denn eine große Zahl von Kontrollfluss-Transformationen kann Ihren Code verlangsamen und seine Größe erhöhen.

controlFlowFlatteningThreshold: 0 entspricht controlFlowFlattening: false.

deadCodeInjection

Type: boolean Default: false

⚠️ Vergrößert den obfuskierten Code drastisch (um bis zu 200 %). Verwenden Sie diese Option nur, wenn die Größe des obfuskierten Codes keine Rolle spielt. Mit deadCodeInjectionThreshold legen Sie fest, welcher Prozentsatz der Knoten von der Injektion toten Codes betroffen ist.
⚠️ Diese Option aktiviert zwangsweise die Option stringArray.
⚠️ Diese Option wird stillschweigend deaktiviert, wenn vmObfuscation aktiviert ist.

Mit dieser Option werden dem obfuskierten Code zufällige Blöcke aus totem Code hinzugefügt.

Beispiel:

// 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

Legt fest, welcher Prozentsatz der Knoten von deadCodeInjection betroffen ist.

debugProtection

Type: boolean Default: false

⚠️ Kann Ihren Browser einfrieren, wenn Sie die Entwicklertools öffnen.
⚠️ Diese Option wird stillschweigend deaktiviert, wenn vmObfuscation aktiviert ist. Verwenden Sie stattdessen vmDebugProtection.

Diese Option macht es nahezu unmöglich, die debugger-Funktion der Entwicklertools zu verwenden (sowohl in WebKit-basierten Browsern als auch in Mozilla Firefox).

debugProtectionInterval

Type: number Default: 0

⚠️ Kann Ihren Browser einfrieren! Verwendung auf eigene Gefahr.
⚠️ Diese Option wird stillschweigend deaktiviert, wenn vmObfuscation aktiviert ist. Verwenden Sie stattdessen vmDebugProtection.

Ist die Option gesetzt, wird über ein Intervall in Millisekunden der Debug-Modus im Konsolen-Tab erzwungen, was die Nutzung der übrigen Funktionen der Entwicklertools erschwert. Funktioniert, wenn debugProtection aktiviert ist. Empfohlen wird ein Wert zwischen 2000 und 4000 Millisekunden.

disableConsoleOutput

Type: boolean Default: false

⚠️ Diese Option deaktiviert console-Aufrufe global für alle Skripte

Deaktiviert die Verwendung von console.log, console.info, console.error, console.warn, console.debug, console.exception und console.trace, indem sie durch leere Funktionen ersetzt werden. Das erschwert den Einsatz des Debuggers.

domainLock

Type: string[] Default: []

⚠️ Diese Option funktioniert nicht mit target: 'node', target: 'service-worker' oder target: 'bytenode'

Erlaubt es, den obfuskierten Quellcode nur auf bestimmten Domains und/oder Subdomains auszuführen. Dadurch wird es sehr schwer, Ihren Quellcode einfach zu kopieren und anderswo auszuführen.

Wird der Quellcode nicht auf den mit dieser Option angegebenen Domains ausgeführt, leitet der Browser auf die URL um, die an die Option domainLockRedirectUrl übergeben wurde.

Mehrere Domains und Subdomains

Sie können Ihren Code an mehr als eine Domain oder Subdomain binden. Um ihn zum Beispiel so zu sperren, dass er nur auf www.example.com läuft, fügen Sie www.example.com hinzu. Damit er auf der Root-Domain einschließlich aller Subdomains läuft (example.com, sub.example.com), verwenden Sie .example.com.

domainLockRedirectUrl

Type: string Default: about:blank

⚠️ Diese Option funktioniert nicht mit target: 'node', target: 'service-worker' oder target: 'bytenode'

Leitet den Browser auf eine übergebene URL um, wenn der Quellcode nicht auf den unter domainLock angegebenen Domains ausgeführt wird

exclude

Type: string[] Default: []

Dateinamen oder Globs, die angeben, welche Dateien von der Obfuskierung ausgeschlossen werden.

forceTransformStrings

Type: string[] Default: []

Erzwingt die Transformation von String-Literalen, die auf die übergebenen RegExp-Muster passen.

⚠️ Diese Option betrifft nur Strings, die aufgrund von stringArrayThreshold (oder künftig möglicherweise weiterer Schwellenwerte) nicht transformiert werden sollten

Die Option hat Vorrang vor der Option reservedStrings, nicht aber vor conditional comments.

Beispiel:

	{
		forceTransformStrings: [
			'some-important-value',
			'some-string_\d'
		]
	}

identifierNamesCache

Type: Object | null Default: null

Hauptziel dieser Option ist die Möglichkeit, bei der Obfuskierung mehrerer Quellen bzw. Dateien dieselben Bezeichnernamen zu verwenden.

Derzeit werden zwei Arten von Bezeichnern unterstützt:

  • Globale Bezeichner:
    • Alle globalen Bezeichner werden in den Cache geschrieben;
    • Alle passenden nicht deklarierten globalen Bezeichner werden durch die Werte aus dem Cache ersetzt.
  • Eigenschaftsbezeichner, nur wenn die Option renameProperties aktiviert ist:
    • Alle Eigenschaftsbezeichner werden in den Cache geschrieben;
    • Alle passenden Eigenschaftsbezeichner werden durch die Werte aus dem Cache ersetzt.

Node.js-API

Wird der Wert null übergeben, wird der Cache vollständig deaktiviert.

Wird ein leeres Objekt ({}) übergeben, wird das Schreiben der Bezeichnernamen in ein Cache-Objekt (Typ TIdentifierNamesCache) aktiviert. Auf dieses Cache-Objekt wird über den Methodenaufruf getIdentifierNamesCache des ObfuscationResult-Objekts zugegriffen.

Das so entstandene Cache-Objekt kann anschließend als Wert der Option identifierNamesGenerator dienen, um diese Namen bei der Obfuskierung aller passenden Bezeichnernamen weiterer Quellen zu verwenden.

Beispiel:

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

Die CLI besitzt eine abweichende Option --identifier-names-cache-path, mit der sich der Pfad zu einer vorhandenen .json-Datei angeben lässt, aus der der Bezeichnernamen-Cache gelesen und in die er geschrieben wird.

Wird der Pfad zu einer leeren Datei übergeben, wird der Bezeichnernamen-Cache in diese Datei geschrieben.

Diese Datei mit dem vorhandenen Cache kann erneut als Wert der Option --identifier-names-cache-path verwendet werden, um diese Namen bei der Obfuskierung aller passenden Bezeichnernamen der nächsten Dateien zu nutzen.

identifierNamesGenerator

Type: string Default: hexadecimal

Legt den Generator für Bezeichnernamen fest.

Verfügbare Werte:

  • dictionary: Bezeichnernamen aus der Liste identifiersDictionary
  • hexadecimal: Bezeichnernamen wie _0xabc123
  • mangled: kurze Bezeichnernamen wie a, b, c
  • mangled-shuffled: wie mangled, jedoch mit gemischtem Alphabet

identifiersDictionary

Type: string[] Default: []

Legt das Bezeichner-Wörterbuch für identifierNamesGenerator mit dem Wert dictionary fest. Jeder Bezeichner aus dem Wörterbuch wird in mehreren Varianten mit unterschiedlicher Groß- und Kleinschreibung der einzelnen Zeichen verwendet. Die Anzahl der Bezeichner im Wörterbuch sollte sich daher an der Anzahl der Bezeichner im ursprünglichen Quellcode orientieren.

identifiersPrefix

Type: string Default: ''

Legt ein Präfix für alle globalen Bezeichner fest.

Verwenden Sie diese Option, wenn Sie mehrere Dateien obfuskieren möchten. Sie hilft, Konflikte zwischen den globalen Bezeichnern dieser Dateien zu vermeiden. Das Präfix sollte für jede Datei unterschiedlich sein.

randomIdentifiersPrefix

Type: boolean Default: false

Stellt allen globalen Bezeichnern ein zufälliges, aus dem Seed abgeleitetes Präfix (6 alphanumerische Zeichen) voran. Verwenden Sie diese Option, um Kollisionen zwischen getrennt obfuskierten Bundles zu vermeiden, die in denselben globalen Gültigkeitsbereich geladen werden – Sie müssen dann nicht mehr für jedes Bundle von Hand ein eindeutiges identifiersPrefix wählen.

  • Der Zufallswert wird aus der Option seed und dem Hash des Quellcodes abgeleitet; reproduzierbare Builds mit demselben Seed erzeugen daher dasselbe Präfix.
  • In Kombination mit identifiersPrefix werden die zufälligen Zeichen an das von Ihnen angegebene Präfix angehängt (z. B. myApp + zufälliges aBc123myAppaBc123).
  • In Kombination mit vmObfuscation ersetzt der Zufallswert das Standardpräfix vm – die Zufälligkeit garantiert die Eindeutigkeit bereits.

ignoreImports

Type: boolean Default: false

Verhindert die Obfuskierung von require-Importen. Das kann in Fällen hilfreich sein, in denen die Laufzeitumgebung diese Importe aus irgendeinem Grund nur mit statischen Strings akzeptiert.

inputFileName

Type: string Default: ''

Legt den Namen der Eingabedatei mit dem Quellcode fest. Dieser Name wird intern für die Generierung der Source Map verwendet. Erforderlich, wenn die NodeJS-API verwendet wird und die Option sourceMapSourcesMode den Wert sources hat.

log

Type: boolean Default: false

Aktiviert die Ausgabe von Informationen in der Konsole.

numbersToExpressions

Type: boolean Default: false

Aktiviert die Umwandlung von Zahlen in Ausdrücke

Beispiel:

// input
const foo = 1234;

// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;

optionsPreset

Type: string Default: default

Ermöglicht das Festlegen einer Optionsvoreinstellung.

Verfügbare Werte:

  • 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.

Alle zusätzlich angegebenen Optionen werden mit der ausgewählten Optionsvoreinstellung zusammengeführt.

parseHtml

Type: boolean Default: false

Aktiviert die Obfuskierung von JavaScript innerhalb von HTML-<script>-Tags.

Ist die Option aktiviert, wird der Obfuscator:

  • automatisch erkennen, ob die Eingabe HTML ist (anhand von <!DOCTYPE, <html>, <head>, <body> oder <script>-Tags)
  • JavaScript aus <script>-Tags extrahieren, die mit dem Attribut data-javascript-obfuscator markiert sind
  • jedes markierte Skript einzeln obfuskieren und dabei die HTML-Struktur beibehalten
  • den obfuskierten Code wieder an seiner ursprünglichen Position einfügen

Wichtig: Es werden ausschließlich Skripte mit dem Attribut data-javascript-obfuscator obfuskiert. Jedes markierte Skript wird einzeln und unabhängig obfuskiert. Das bedeutet:

  • Code innerhalb markierter Skript-Tags muss isoliert sein – er darf KEINE Variablen, Funktionen oder Klassen referenzieren, die in anderen markierten Skript-Tags definiert sind
  • Nicht markierte Skripte können weiterhin auf globale Werte zugreifen, die von markierten Skripten definiert werden (über var-Deklarationen oder ausdrückliche Zuweisungen an globalThis)
  • So behalten Sie die ausdrückliche Kontrolle darüber, welche Skripte geschützt werden

Wird obfuskiert (Attribut data-javascript-obfuscator erforderlich):

  • <script data-javascript-obfuscator> – normale Skripte
  • <script type="text/javascript" data-javascript-obfuscator> – Skripte mit ausdrücklich angegebenem Typ
  • Skripte mit beliebigen zusätzlichen Attributen (id, class, weitere data-* usw.)

Wird übersprungen (bleibt unverändert):

  • Skripte ohne das Attribut data-javascript-obfuscator
  • <script type="module"> – ES-Module (auch mit dem Attribut)
  • <script src="..."> – externe Skripte (auch mit dem Attribut)
  • Leere Skript-Tags

Hinweis: Bei aktiviertem parseHtml werden keine Source Maps erzeugt, da sie sich nicht korrekt auf die HTML-Ausgabe abbilden ließen.

Beispiel:

// 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

⚠️ Diese Option kann Ihren Code beschädigen. Aktivieren Sie sie nur, wenn Sie wissen, was sie bewirkt!

Aktiviert die Obfuskierung von globalen Variablen- und Funktionsnamen mit Deklaration.

Ist diese Option deaktiviert und deklariert der Eingabecode Funktionen oder Klassen im globalen Gültigkeitsbereich (ist der Code also nicht in eine IIFE eingeschlossen), bleiben deren Namen in der obfuskierten Ausgabe unverändert – andere Skripte können sie weiterhin über ihren Namen ansprechen. Unter vmObfuscation wird in diesem Fall eine Warnung VMGlobalFunctionNamesNotRenamed mit diesen Namen gemeldet: Der Funktionsrumpf ist zwar als Bytecode verborgen, der lesbare Name auf oberster Ebene verrät aber nach wie vor, was der Code tut (etwa gegenüber einem LLM). Um das zu vermeiden, schließen Sie den Code in eine IIFE ein oder aktivieren Sie diese Option.

renameProperties

Type: boolean Default: false

⚠️ Diese Option KANN Ihren Code beschädigen. Aktivieren Sie sie nur, wenn Sie wissen, was sie bewirkt!

Aktiviert die Umbenennung von Eigenschaftsnamen. Alle integrierten DOM-Eigenschaften sowie Eigenschaften der JavaScript-Kernklassen werden dabei ignoriert.

Um zwischen dem safe- und dem unsafe-Modus dieser Option zu wechseln, verwenden Sie die Option renamePropertiesMode.

Um das Format der umbenannten Eigenschaftsnamen festzulegen, verwenden Sie die Option identifierNamesGenerator.

Um zu steuern, welche Eigenschaften umbenannt werden, verwenden Sie die Option reservedNames.

Beispiel:

// 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

⚠️ Selbst im Modus safe KANN die Option renameProperties Ihren Code beschädigen.

Legt den Modus der Option renameProperties fest:

  • safe – Standardverhalten seit Version 2.11.0. Versucht, Eigenschaften auf sicherere Weise umzubenennen, um Laufzeitfehler zu vermeiden. In diesem Modus werden einige Eigenschaften von der Umbenennung ausgenommen.
  • unsafe – Standardverhalten vor Version 2.11.0. Benennt Eigenschaften ohne jede Einschränkung auf unsichere Weise um.

Wenn eine Datei Eigenschaften aus einer anderen Datei verwendet, nutzen Sie die Option identifierNamesCache, um zwischen diesen Dateien dieselben Eigenschaftsnamen beizubehalten.

reservedNames

Type: string[] Default: []

Deaktiviert die Obfuskierung und die Generierung von Bezeichnern, die auf die übergebenen RegExp-Muster passen.

Beispiel:

	{
		reservedNames: [
			'^someVariable',
			'functionParameter_\d'
		]
	}

reservedStrings

Type: string[] Default: []

Deaktiviert die Transformation von String-Literalen, die auf die übergebenen RegExp-Muster passen. Passende Strings bleiben in der obfuskierten Ausgabe sichtbar.

Bei der VM-Obfuskierung werden reservierte Strings in einem separaten, unverschlüsselten Array abgelegt, damit sie sichtbar bleiben. Das ist für Strings nützlich, die lesbar bleiben müssen, etwa API-Endpunkte für das Monitoring oder Kennungen von Bibliotheken.

Beispiel:

	{
		reservedStrings: [
			'react-native',
			'\.\/src\/test',
			'some-string_\d'
		]
	}

seed

Type: string|number Default: 0

Diese Option legt den Startwert (Seed) für den Zufallsgenerator fest. Das ist nützlich, um reproduzierbare Ergebnisse zu erhalten.

Ist der Seed 0, arbeitet der Zufallsgenerator ohne Startwert.

selfDefending

Type: boolean Default: false

⚠️ Verändern Sie den obfuskierten Code nach einer Obfuskierung mit dieser Option in keiner Weise, denn jede Änderung – etwa das Uglifying des Codes – kann die Selbstverteidigung auslösen, sodass der Code nicht mehr funktioniert!
⚠️ Diese Option setzt compact zwangsweise auf true
⚠️ Diese Option wird stillschweigend deaktiviert, wenn vmObfuscation aktiviert ist. Verwenden Sie stattdessen vmSelfDefending.

Diese Option macht den Ausgabecode widerstandsfähig gegen Neuformatierung und das Umbenennen von Variablen. Wendet jemand einen JavaScript-Beautifier auf den obfuskierten Code an, funktioniert der Code nicht mehr, was sein Verständnis und seine Veränderung erschwert.

simplify

Type: boolean Default: true

Aktiviert zusätzliche Code-Obfuskierung durch Vereinfachung.

⚠️ In künftigen Releases wird die Obfuskierung von boolean-Literalen (true => !![]) unter diese Option verschoben.

Beispiel:

// 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

Aktiviert die Generierung einer Source Map für den obfuskierten Code.

Source Maps können hilfreich sein, um obfuskierten JavaScript-Quellcode zu debuggen. Wenn Sie in der Produktion debuggen möchten oder müssen, können Sie die separate Source-Map-Datei an einem geheimen Ort ablegen und Ihren Browser dorthin verweisen.

sourceMapBaseUrl

Type: string Default: ``

Legt die Basis-URL für die Import-URL der Source Map fest, wenn sourceMapMode: 'separate' gesetzt ist.

CLI-Beispiel:

javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'

Ergebnis:

//# sourceMappingURL=http://localhost:9000/out.js.map

sourceMapFileName

Type: string Default: ``

Legt den Dateinamen der ausgegebenen Source Map fest, wenn sourceMapMode: 'separate' gesetzt ist.

CLI-Beispiel:

javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example

Ergebnis:

//# sourceMappingURL=http://localhost:9000/example.js.map

sourceMapMode

Type: string Default: separate

Legt den Modus der Source-Map-Generierung fest:

  • inline – hängt die Source Map an das Ende jeder .js-Datei an;
  • separate – erzeugt eine zugehörige '.map'-Datei mit der Source Map. Führen Sie den Obfuscator über die CLI aus, wird am Ende der Datei mit dem obfuskierten Code ein Verweis auf die Source-Map-Datei eingefügt: //# sourceMappingUrl=file.js.map.

sourceMapSourcesMode

Type: string Default: sources-content

Ermöglicht die Steuerung der Felder sources und sourcesContent der Source Map:

  • sources-content – fügt ein Platzhalter-Feld sources sowie ein Feld sourcesContent mit dem ursprünglichen Quellcode hinzu;
  • sources – fügt ein Feld sources mit einer gültigen Quellenbeschreibung hinzu, jedoch kein Feld sourcesContent. Bei Verwendung der NodeJS-API muss die Option inputFileName definiert werden, deren Wert als Inhalt des Feldes sources verwendet wird.

splitStrings

Type: boolean Default: false

Teilt String-Literale in Blöcke der Länge auf, die mit der Option splitStringsChunkLength festgelegt wird.

Beispiel:

// input
(function(){
    var test = 'abcdefg';
})();

// output
(function(){
    var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();

splitStringsChunkLength

Type: number Default: 10

Legt die Blocklänge für die Option splitStrings fest.

stringArray

Type: boolean Default: true

Entfernt String-Literale und legt sie in einem speziellen Array ab. So wird zum Beispiel der String "Hello World" in var m = "Hello World"; durch etwas wie var m = _0x12c456[0x1]; ersetzt

stringArrayCallsTransform

Type: boolean Default: false

⚠️ Die Option stringArray muss aktiviert sein

Aktiviert die Transformation der Aufrufe des stringArray. Alle Argumente dieser Aufrufe können – abhängig vom Wert von stringArrayCallsTransformThreshold – in ein separates Objekt ausgelagert werden. Dadurch wird es noch schwerer, Aufrufe des String-Arrays automatisch aufzuspüren.

Beispiel:

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

⚠️ Die Optionen stringArray und stringArrayCallsTransformThreshold müssen aktiviert sein

Mit dieser Einstellung passen Sie die Wahrscheinlichkeit (von 0 bis 1) an, mit der Aufrufe des String-Arrays transformiert werden.

stringArrayEncoding

Type: string[] Default: []

⚠️ Die Option stringArray muss aktiviert sein

Diese Option kann Ihr Skript verlangsamen.

Codiert alle String-Literale des stringArray mit base64 oder rc4 und fügt speziellen Code ein, der sie zur Laufzeit wieder decodiert.

Jeder stringArray-Wert wird mit einer zufällig aus der übergebenen Liste ausgewählten Codierung codiert. Dadurch lassen sich mehrere Codierungen gleichzeitig verwenden.

Verfügbare Werte:

  • 'none' (boolean): codiert den stringArray-Wert nicht
  • 'base64' (string): codiert den stringArray-Wert mit base64
  • 'rc4' (string): codiert den stringArray-Wert mit rc4. Etwa 30–50 % langsamer als base64, dafür sind die ursprünglichen Werte schwerer zu ermitteln.

Mit den folgenden Optionswerten bleibt zum Beispiel ein Teil der stringArray-Werte uncodiert, während andere Werte mit base64- und rc4-Codierung codiert werden:

stringArrayEncoding: [
    'none',
    'base64',
    'rc4'
]

stringArrayIndexesType

Type: string[] Default: ['hexadecimal-number']

⚠️ Die Option stringArray muss aktiviert sein

Ermöglicht die Steuerung des Typs der Indizes von String-Array-Aufrufen.

Jeder Index eines stringArray-Aufrufs wird mit einem zufällig aus der übergebenen Liste ausgewählten Typ transformiert. Dadurch lassen sich mehrere Typen gleichzeitig verwenden.

Verfügbare Werte:

  • 'hexadecimal-number' (default): transformiert die Indizes von String-Array-Aufrufen zu hexadezimalen Zahlen
  • 'hexadecimal-numeric-string': transformiert die Indizes von String-Array-Aufrufen zu hexadezimalen numerischen Strings

Vor Version 2.9.0 hat javascript-obfuscator alle Indizes von String-Array-Aufrufen mit dem Typ hexadecimal-numeric-string transformiert. Das erschwert die manuelle Deobfuskierung geringfügig, erlaubt aber automatischen Deobfuskatoren, diese Aufrufe leicht zu erkennen.

Der neue Typ hexadecimal-number erschwert das automatische Erkennen der Aufrufmuster des String-Arrays im Code.

Weitere Typen werden künftig hinzukommen.

stringArrayIndexShift

Type: boolean Default: true

⚠️ Die Option stringArray muss aktiviert sein

Aktiviert eine zusätzliche Indexverschiebung für alle String-Array-Aufrufe

stringArrayRotate

Type: boolean Default: true

⚠️ stringArray muss aktiviert sein

Verschiebt das stringArray-Array um eine feste, bei der Obfuskierung zufällig erzeugte Anzahl von Positionen. Dadurch wird es schwerer, die Reihenfolge der entfernten Strings ihren ursprünglichen Stellen zuzuordnen.

stringArrayShuffle

Type: boolean Default: true

⚠️ stringArray muss aktiviert sein

Mischt die Elemente des stringArray-Arrays zufällig.

stringArrayWrappersCount

Type: number Default: 1

⚠️ Die Option stringArray muss aktiviert sein

Legt die Anzahl der Wrapper für das string array innerhalb jedes Wurzel- oder Funktionsgültigkeitsbereichs fest. Die tatsächliche Anzahl der Wrapper in einem Gültigkeitsbereich ist durch die Anzahl der literal-Knoten in diesem Bereich begrenzt.

Beispiel:

// 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

⚠️ Die Optionen stringArray und stringArrayWrappersCount müssen aktiviert sein

Aktiviert verkettete Aufrufe zwischen den string array-Wrappern.

Beispiel:

// 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

⚠️ Die Option stringArray muss aktiviert sein
⚠️ Derzeit betrifft diese Option nur Wrapper, die durch den Optionswert function von stringArrayWrappersType hinzugefügt werden

Ermöglicht die Steuerung der maximalen Anzahl von Parametern der String-Array-Wrapper. Standard- und Mindestwert ist 2. Empfohlen wird ein Wert zwischen 2 und 5.

stringArrayWrappersType

Type: string Default: variable

⚠️ Die Optionen stringArray und stringArrayWrappersCount müssen aktiviert sein

Ermöglicht die Auswahl des Typs der Wrapper, die durch die Option stringArrayWrappersCount hinzugefügt werden.

Verfügbare Werte:

  • 'variable': fügt Variablen-Wrapper am Anfang jedes Gültigkeitsbereichs ein. Schnelle Ausführung.
  • 'function': fügt Funktions-Wrapper an zufälligen Positionen innerhalb jedes Gültigkeitsbereichs ein. Langsamer als variable, bietet dafür aber eine strengere Obfuskierung.

Es wird dringend empfohlen, für eine stärkere Obfuskierung function-Wrapper zu verwenden, sofern sich ein Performanceverlust auf die obfuskierte Anwendung nicht stark auswirkt.

Beispiel für den Optionswert '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

⚠️ Die Option stringArray muss aktiviert sein

Mit dieser Einstellung passen Sie die Wahrscheinlichkeit (von 0 bis 1) an, mit der ein String-Literal in das stringArray aufgenommen wird.

Diese Einstellung ist besonders bei großem Codeumfang nützlich, denn das string array wird immer wieder aufgerufen, was Ihren Code verlangsamen kann.

stringArrayThreshold: 0 entspricht stringArray: false.

strictMode

Type: boolean | null Default: null

Legt fest, wie der Obfuscator den Code im Hinblick auf den Strict Mode von JavaScript behandeln soll.

Verfügbare Werte:

  • null (Standard) – erkennt den Strict Mode automatisch anhand des Codes. Enthält der Code eine ausdrückliche 'use strict'-Direktive, ES-Modul-Syntax oder Klassenmethoden, wird er als Strict-Mode-Code behandelt. Andernfalls wird der Sloppy Mode angenommen.
  • true – behandelt sämtlichen Code als Strict-Mode-Code, auch ohne ausdrückliche 'use strict'-Direktive. Verwenden Sie diesen Wert, wenn Ihr Code in einem Strict-Mode-Kontext ausgeführt wird (z. B. in ES-Modulen, Bundlern oder modernen Frameworks).
  • false – nur ausdrückliche Strict-Mode-Merkmale ('use strict', ES-Module, Klassenmethoden) gelten als Strict Mode. Die Vererbung aus dem übergeordneten Gültigkeitsbereich greift weiterhin gemäß JS-Spezifikation.

target

Type: string Default: browser

Legt die Zielumgebung für den obfuskierten Code fest.

Verfügbare Werte:

  • browser (Standard) – gewöhnliche Webseiten-Umgebung. Der Ausgabecode ist mit dem für node identisch, einige browserspezifische Optionen dürfen jedoch nicht mit dem Ziel node verwendet werden
  • browser-no-eval – wie browser, die Ausgabe verwendet jedoch kein eval(). Verwenden Sie dieses Ziel, wenn die Zielseite eine Content Security Policy besitzt, die eval/unsafe-eval verbietet.
  • node – Node.js-Umgebung. Browserspezifische Optionen sind deaktiviert (sie benötigen window/document und wären in Node wirkungslos oder würden einen Fehler auslösen). Einige vmSelfDefending-Abwehrmechanismen, die auf reine Browser-APIs angewiesen sind – Erkennung von Headless-Browsern, Wiederherstellung eines sauberen Realms über ein iframe, Anti-Inspector- und DOM-Prüfungen –, werden für dieses Ziel nicht ausgegeben.
  • service-worker – Service-Worker-Kontext. Kein window, kein document, ein anderes globales self.
  • userscript – Sandbox eines Userscript-Managers (z. B. Tampermonkey). Die vmSelfDefending-Abwehrmechanismen werden entsprechend angepasst.
  • bytenode – Node.js-Code, der nach der Obfuskierung mit dem bytenode-Loader kompiliert wird (von V8 zwischengespeicherter Bytecode, .jsc). Der Obfuscator ruft bytenode nicht selbst auf; er gibt VM-obfuskiertes JavaScript aus, dessen Laufzeit so aufgebaut ist, dass sie den Kompilierschritt von bytenode übersteht, und passt die vmSelfDefending-Abwehrmechanismen entsprechend an. Führen Sie bytenode anschließend selbst auf der obfuskierten Ausgabe aus, um die endgültige .jsc-Datei zu erzeugen.

transformObjectKeys

Type: boolean Default: false

Aktiviert die Transformation von Objektschlüsseln.

Beispiel:

// 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

Steuert, welche nicht fatalen Obfuskierungswarnungen über die Methode ObfuscationResult.getWarnings() gemeldet werden.

Verfügbare Werte:

  • 'all' (Standard) – jede Warnung wird gemeldet.
  • 'none' – alle Warnungen werden unterdrückt.
  • ein Objekt, das Warnungstypen auf Wahrheitswerte abbildet – ein auf false gesetzter Typ wird unterdrückt; jeder nicht aufgeführte (oder auf true gesetzte) Typ bleibt aktiv. { "VMGlobalFunctionNamesNotRenamed": false } behält zum Beispiel alle Warnungen bis auf diese eine bei.

Warnungstypen:

  • VMGlobalFunctionNamesNotRenamed – unter vmObfuscation wurden die Namen von Funktionsdeklarationen, Klassendeklarationen und Variablen der obersten Ebene, denen ein Funktions-, Pfeilfunktions- oder Klassenausdruck zugewiesen wurde, unverändert übernommen (die Option renameGlobals ist deaktiviert und der Code ist nicht in eine IIFE eingeschlossen). Sie bleiben in der Ausgabe daher lesbar, obwohl die Rümpfe als Bytecode verborgen sind. Exportierte Namen werden nicht gemeldet.
  • VMTopLevelInitializerNotVirtualized – Initialisierer von Variablen der obersten Ebene sind trotz VM-Obfuskierung als reines JavaScript erhalten geblieben, weil vmWrapTopLevelInitializers deaktiviert ist oder sie nicht virtualisieren konnte.
  • DynamicCodeRenameRisk – der Code erzeugt zur Laufzeit eine Funktion aus einem String (direktes eval, der Function-Konstruktor oder ein über fn.toString() in ein <script>/einen Worker eingefügter Code), die Bezeichner referenzieren kann, die der Obfuscator umbenannt hat.
  • VMDynamicCodeSkipped – eine Funktion wurde vom Bytecoding der VM ausgenommen, weil sie direktes eval, dynamisches new Function oder Function enthält (siehe vmForceCompileDynamicCode).
  • VMSyncFunctionSkippedInAsyncMode – bei aktiviertem vmAsyncExecutor hat sich eine von Ihnen im comment-Modus ausdrücklich markierte Funktion als synchron erwiesen und wurde übersprungen (in diesem Modus werden nur asynchrone Funktionen virtualisiert).
  • VMAsyncGeneratorSkippedInAsyncMode – bei aktivem vmAsyncExecutor und asynchronem Schlüssel-Getter konnte ein markierter Async-Generator nicht virtualisiert werden (er muss seinen Iterator synchron zurückgeben).
  • BrowserTargetWithNodeStyleCode – der Code sieht danach aus, als ziele er auf Node.js (etwa require('fs'), __dirname, process.argv), während die Option target auf eine browserähnliche Umgebung gesetzt ist.

vmObfuscation

Type: boolean Default: false

Aktiviert die VM-basierte Bytecode-Obfuskierung. Ist sie aktiviert, werden JavaScript-Funktionen in eigenen Bytecode kompiliert, der auf einer eingebetteten virtuellen Maschine läuft. Das bietet das höchste Schutzniveau, da die ursprüngliche Codelogik vollständig umgewandelt wird.

Beispiel: Aus Ihrem lesbaren Code wie return qty * price wird eine Liste von Zahlen wie [0x15,0x03,0x17,...], die nur der eingebettete VM-Interpreter ausführen kann. Die ursprüngliche Logik ist nicht mehr als JavaScript sichtbar.

vmTargetFunctions

Type: string[] Default: []

Legt namentlich fest, welche Funktionen der obersten Ebene genau VM-Schutz erhalten sollen.

Beispiel:

{
    vmObfuscation: true,
    vmTargetFunctions: ['someFunctionName']
}

Ergebnis: Nur diese drei Funktionen erhalten VM-Schutz. Alles andere bleibt normales (aber weiterhin obfuskiertes) JavaScript. Ideal, um sensible Lizenzprüfungen oder Authentifizierungslogik zu schützen und den Rest Ihres Codes schlank zu halten.

vmExcludeFunctions

Type: string[] Default: []

Legt Funktionen der obersten Ebene fest, die niemals VM-Schutz erhalten sollen. Hat Vorrang vor anderen Einstellungen.

Beispiel:

{
    vmObfuscation: true,
    vmExcludeFunctions: ['someFunctionName']
}

Wann verwenden: Performancekritische Funktionen der obersten Ebene (Animationsschleifen, Echtzeit-Datenverarbeitung) lassen sich ausschließen, um den VM-Mehraufwand zu vermeiden, während alles andere geschützt bleibt.

vmTargetFunctionsMode

Type: string Default: root

Steuert, wie Funktionen/Methoden für die VM-Obfuskierung ausgewählt werden.

ModusBeschreibung
rootStandardverhalten. Für die VM-Obfuskierung kommen nur Funktionen der obersten Ebene infrage. Verwendet die Erlaubnisliste vmTargetFunctions und die Sperrliste vmExcludeFunctions zum Filtern.
commentNur Funktionen/Methoden, die mit dem Kommentar /* javascript-obfuscator:vm */ versehen sind, werden VM-obfuskiert. Funktioniert mit Funktionen/Methoden auf jeder Verschachtelungsebene.

Beispiel – Comment-Modus:

// 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'
}

Wann verwenden: Wenn Sie punktgenau steuern müssen, welche Funktionen VM-Schutz erhalten – insbesondere verschachtelte Funktionen mit sensibler Logik. Anders als vmTargetFunctions, das nur mit benannten Funktionen der obersten Ebene funktioniert, können Sie im Comment-Modus jede beliebige Funktion an jeder Stelle Ihres Codes schützen.

vmForceCompileDynamicCode

Type: boolean Default: false

Steuert, was die VM-Obfuskierung mit einer Funktion tut, die einen direkten eval-, new Function(...)- oder Function(...)-Aufruf enthält.

Standardmäßig wird eine solche Funktion (und jede darin definierte Funktion) vom Bytecoding der VM ausgenommen, und über result.getWarnings() wird eine Warnung VMDynamicCodeSkipped gemeldet. Der Grund: Der zur Laufzeit erzeugte Quellcode kann Bezeichner aus der umgebenden Gültigkeitsbereichskette referenzieren – Bezeichner, die der Obfuscator umbenannt hat.

Ist der Wert true, wird die Funktion trotzdem in Bytecode überführt und die Warnung VMDynamicCodeSkipped nicht mehr ausgegeben.

Die separate Warnung DynamicCodeRenameRisk wird unabhängig von dieser Option weiterhin ausgelöst, denn das darin beschriebene Umbenennungsrisiko ist unabhängig vom VM-Überspringen – das Aktivieren dieser Option macht das zugrunde liegende Muster nicht sicherer.

// Source code
function loadConfig(src) {
    return eval(src);
}
loadConfig('1 + 2');
// Options
{
    vmObfuscation: true,
    vmForceCompileDynamicCode: true
}

Bei ausgeschalteter Option (Standard) bleibt loadConfig reines JavaScript. Bei eingeschalteter Option wird loadConfig wie jede andere Funktion in VM-Bytecode kompiliert. Verwenden Sie diese Option, wenn Sie die Aufrufstelle geprüft haben und wissen, dass der zur Laufzeit erzeugte Code nicht von durch Closures umbenannten Bezeichnern abhängt.

vmWrapTopLevelInitializers

Type: boolean Default: false

Schließt einige Initialisierer von Variablen der obersten Ebene in IIFEs (Immediately Invoked Function Expressions) ein, damit sie VM-obfuskiert werden können.

Was sie tut: Ohne diese Option bleiben Konstanten und Variablen der obersten Ebene in der Ausgabe sichtbar:

// Input
const MY_STRING = "my-string";

// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string";  // String is visible!

Mit aktivierter Option wird der Initialisierer in eine IIFE eingeschlossen, die VM-obfuskiert wird:

// Input
const MY_STRING = "my-string";

// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })();  // String hidden in bytecode

Hinweis: Diese Option funktioniert nur, wenn vmTargetFunctionsMode den Wert 'root' (Standard) hat.

Warnungen: Sobald ein Initialisierer der obersten Ebene trotz VM-Obfuskierung als reines JavaScript erhalten bleibt, wird eine Warnung VMTopLevelInitializerNotVirtualized mit den betroffenen Variablennamen gemeldet. Das umfasst: eine deaktivierte Option, Initialisierer, die diese Option überspringen musste (jeweils mit Grund – etwa weil der Initialisierer einen benachbarten Deklarator referenziert oder ein Top-Level-await enthält), sowie den vmAsyncExecutor-Modus, in dem sich die synchronen Wrapper überhaupt nicht virtualisieren lassen.

vmDynamicOpcodes

Type: boolean Default: false

Macht den VM-Interpreter kleiner und für jeden Build einzigartig.

Was sie tut:

  1. Filtert ungenutzte Instruktionen – Verwendet Ihr Code keine Klassen, werden klassenbezogene Instruktionen vollständig entfernt
  2. Randomisiert die Struktur – Die Reihenfolge der Instruktions-Handler wird bei jedem Build neu gemischt

Das Ergebnis: eine kleinere Ausgabe, und jeder Build sieht anders aus.

vmBytecodeEncoding

Type: boolean Default: false

Codiert jede Bytecode-Instruktion. Die Instruktionen werden während der Ausführung einzeln decodiert.

vmBytecodeArrayEncoding

Type: boolean Default: false

Codiert das gesamte Bytecode-Array als einen einzigen Block. Das Array wird einmalig beim Start decodiert, bevor die Ausführung beginnt. Verwenden Sie diese Option zusammen mit vmBytecodeEncoding für zwei Schutzschichten.

vmBytecodeArrayEncodingKey

Type: string Default: ''

Eigener Verschlüsselungsschlüssel für die Codierung des Bytecode-Arrays. Ist er gesetzt, wird dieser Schlüssel anstelle des standardmäßig aus der Umgebung abgeleiteten Schlüssels verwendet. Der Schlüssel muss zur Laufzeit über vmBytecodeArrayEncodingKeyGetter bereitgestellt werden.

Diese Option externalisiert den Verschlüsselungsschlüssel – er ist nicht im obfuskierten Code selbst eingebettet. Der Schlüssel ist zur Laufzeit zwar weiterhin zugänglich (und damit nicht wirklich geheim), doch diese Trennung verhindert, dass Werkzeuge zur statischen Analyse den Schlüssel allein durch Untersuchung des Codes finden.

Wichtig: Der Schlüssel muss synchron verfügbar sein, wenn der obfuskierte Code geladen wird. Verwenden Sie einen synchronen Speicher wie Cookies, localStorage, sessionStorage, globale Variablen oder DOM-Elemente (z. B. servergesetzte Meta-Tags). Asynchrone Methoden wie fetch() können im Ausdruck des Schlüssel-Getters nicht direkt verwendet werden.

vmBytecodeArrayEncodingKeyGetter

Type: string Default: ''

Synchroner JavaScript-Ausdruck, der den Verschlüsselungsschlüssel zur Laufzeit zurückgibt. Dieser Ausdruck wird ausgewertet, wenn der obfuskierte Code geladen wird, und muss denselben Schlüssel zurückgeben, der in vmBytecodeArrayEncodingKey angegeben wurde. Um den Schlüssel asynchron aufzulösen (ein Promise), aktivieren Sie vmAsyncExecutor.

Hinweis: Ein Getter, der ein Promise zurückgibt, erfordert vmAsyncExecutor. Das lässt sich zur Build-Zeit nicht prüfen, daher schlägt ein Promise-Getter bei ausgeschaltetem vmAsyncExecutor zur Laufzeit fehl – der Decoder erhält das Promise statt des Schlüssels.

Der obfuskierte Code funktioniert nur, wenn der Schlüssel-Getter genau denselben Schlüssel zurückgibt, der bei der Obfuskierung verwendet wurde. Stimmen die Schlüssel nicht überein, schlägt die Entschlüsselung fehl und der Code erzeugt Datenmüll oder Fehler. Gibt der Schlüssel-Getter undefined, null oder einen leeren String zurück, löst der Code einen Fehler aus: „VM decryption key not available“.

Wichtig: Bewahren Sie den Schlüssel nicht in derselben Datei bzw. demselben Skript wie den obfuskierten Code auf – wird er dort eingebettet, kann selbst ein rein statischer Scan des Bundles ihn wiederherstellen. Legen Sie ihn stattdessen in einer separaten Quelle ab: servergesetzte Cookies, ein von einem anderen Skript befülltes localStorage, ein servereingefügtes HTML-Meta-Tag, eine von einem anderen Skript gesetzte globale Variable oder (mit vmAsyncExecutor) zur Laufzeit von Ihrem Backend abgerufen.

Wird der Schlüssel von Ihrem Backend abgerufen (über vmAsyncExecutor), fügen Sie diesem Endpunkt sitzungs- oder ursprungsbasierte Prüfungen hinzu: Geben Sie echten Nutzern (gültige Sitzung, erwarteter Origin/Referer) den richtigen Schlüssel zurück und verdächtigen Anfragen (etwa ein localhost/unerwarteter Ursprung, keine Sitzung) einen Datenmüll-Schlüssel. Echte Nutzer laufen normal; eine Kopie, die außerhalb Ihrer Umgebung läuft, erhält einen Schlüssel, der zu nichts entschlüsselt. Die genaue Logik hängt von Ihrer Website ab.

Beispiele:

// 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())'

Anwendungsbeispiel:

// 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

Aktiviert den asynchronen VM-Executor, der es vmBytecodeArrayEncodingKeyGetter erlaubt, ein Promise zurückzugeben (ein asynchroner Schlüssel-Getter) – so kann der Entschlüsselungsschlüssel zur Laufzeit abgerufen werden (Netzwerkanfrage, IndexedDB usw.), statt beim Laden des Codes synchron verfügbar sein zu müssen.

Dringend empfohlen für vollständig asynchrone Codebasen. In diesem Modus werden nur async-Funktionen virtualisiert – eine synchrone Funktion lässt sich nicht asynchron machen, ohne ihren Rückgabewert in ein Promise zu verwandeln und ihre Aufrufer zu beschädigen –, daher erzielt durchgängig asynchroner Code die höchste Abdeckung. Er funktioniert auch, wenn die Wurzel synchron ist (etwa eine synchrone IIFE / ein UMD-Wrapper): Die äußersten async-Funktionen darin werden geschützt, die synchronen Teile bleiben unverändert.

Was transformiert wird: jede äußerste async-Funktion, wo immer sie auftritt (auch verschachtelt innerhalb synchroner Wrapper). Die äußerste async-Funktion jeder Kette ist die geschützte Einheit – alles in ihr, synchron wie asynchron, wird mit einkompiliert. Synchrone Funktionen und einfache Generatoren bleiben unobfuskiert.

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
    }
}

Übersprungenes und Warnungen. Async-Generatoren bleiben bei aktivem asynchronem Schlüssel-Getter ebenfalls unobfuskiert (ein Async-Generator muss seinen Iterator synchron zurückgeben und kann nicht auf den Schlüssel warten). Im standardmäßigen vmTargetFunctionsMode: 'root' erfolgen Auslassungen still (die Auswahl ist automatisch); im comment-Modus wird über ObfuscationResult.getWarnings() eine Warnung ausgegeben, sobald sich eine von Ihnen ausdrücklich markierte Funktion nicht virtualisieren lässt – weil sie sich als synchron erwiesen hat oder ein Async-Generator unter einem asynchronen Schlüssel-Getter ist.

Der asynchrone Schlüssel-Getter erfordert zusätzlich vmBytecodeArrayEncoding mit einem vmBytecodeArrayEncodingKeyGetter.

Anwendungsbeispiel:

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

Codiert die Sprungziele im Bytecode. Die Sprungoffsets werden zur Laufzeit berechnet und verbergen so die Kontrollflussstruktur (if/else, Schleifen usw.) vor der statischen Analyse.

vmMacroOps

Type: boolean Default: false

Fasst häufige Instruktionsfolgen zu einzelnen „Makro“-Opcodes zusammen. Aus LOAD + ADD + STORE kann zum Beispiel eine einzelne Instruktion MACRO_ADD_TO_VAR werden. Das durchbricht die Mustererkennung und kann die Performance verbessern.

vmDebugProtection

Type: boolean Default: false

Fügt der VM-Laufzeit mehrschichtige Abwehrmechanismen gegen Debugging, Analyse und LLMs hinzu. Funktioniert am besten mit den Zielen browser/browser-no-eval.

vmSelfDefending

Type: boolean Default: false

Fügt der VM-Laufzeit mehrschichtigen Schutz vor Manipulation, Hooking und Reverse Engineering hinzu.

⚠️ Diese Option aktiviert zwangsweise vmBytecodeArrayEncoding.

⚠️ Erkennung sensibler Umgebungen. Diese Option bindet den obfuskierten Code an seine Ziel-Laufzeitumgebung und nutzt fortgeschrittenes Browser-Fingerprinting, um Automatisierungswerkzeuge zu erkennen. Mit dieser Option geschützter Code bricht absichtlich ab, wenn er ausgeführt wird in:

  • Headless-Browsern (Headless Chrome/Chromium, PhantomJS)
  • Browser-Automatisierungswerkzeugen (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
  • Node.js (wenn target auf browser gesetzt ist)
  • jsdom oder ähnlichen serverseitigen DOM-Emulationen
  • Umgebungen, in denen native Browser-Builtins gehookt oder ersetzt wurden

Der Code funktioniert korrekt in normalen Browsern (Chrome, Firefox, Safari, Edge), auch wenn er innerhalb von iframes, Browser-Erweiterungen (Content Scripts) und Web Workern geladen wird. Wenn Sie automatisierte Tests gegen geschützten Code ausführen müssen, deaktivieren Sie vmSelfDefending für Test-Builds – diese Option soll die automatisierte Analyse verhindern und kann mit keinem Automatisierungs-Framework sicher verwendet werden.

Es wird dringend empfohlen, diese Option zusammen mit vmDebugProtection, vmBytecodeArrayEncodingKey und vmBytecodeArrayEncodingKeyGetter zu verwenden.

vmDefenseHook

Type: { name: string, aliases?: object } Default: ''

vmDefenseHook nimmt ein Objekt mit zwei Schlüsseln entgegen: name (erforderlich) und aliases (optional).

name ist eine globale Funktion, die Ihre Host-Seite definiert und die eine VM-Abwehr (vmDebugProtection / vmSelfDefending) mit einem Signalobjekt aufruft, sobald sie ein feindliches Signal erkennt – einen Debugger oder Inspector, einen Headless-/Automatisierungsbrowser, einen Prozess eines KI-Coding-Agenten, eine unzulässige Domain und so weiter. Verwenden Sie sie, um das Ereignis an Ihr Backend zu melden (etwa navigator.sendBeacon). Der Hook ist ein reiner Telemetrie-Empfänger: Sein Rückgabewert wird ignoriert, und ein fehlender oder auslösender Hook ist ein stiller No-op, der niemals eine Abwehr deaktivieren kann. Um zu ändern, was eine Abwehr bei einer Erkennung tut, verwenden Sie vmDefenseReaction.

aliases benennt optional die Felder dieses Signalobjekts um – behandelt weiter unten unter Die Signalfelder umbenennen.

Das Signalobjekt. Der Hook erhält ein einzelnes signal:

  • source – der konkrete Detektor, der ausgelöst hat (siehe Tabelle).
  • category – die Gruppe, unter der er meldet: automation (nichtmenschliche Browser), debugger (ein Debugger/Inspector ist aktiv), sandbox (instrumentierter/vorgetäuschter Host), domain (Verstoß gegen die Domain-Sperre), tamper (Builtins zur Laufzeit gepatcht) oder integrity (der VM-eigene Code wurde verändert).
  • score / threshold – wie stark der Detektor ausgelöst hat und der Wert, den er erreichen musste; der Hook feuert erst, sobald score >= threshold. Die meisten Prüfungen sind Alles-oder-nichts (ein einzelnes eindeutiges Signal); headless summiert mehrere Signale der Browser-Form, sodass sein score in der Regel höher ist als sein threshold.
sourceerkenntcategory
integrityder obfuskierte VM-Code selbst wurde verändertintegrity
nodefür den Browser gedachter Code, der unter Node.js läuftdebugger
debuggereine angehängte oder aktive Debugger- bzw. Inspector-Sitzung oder eine Debug-Umgebungdebugger
headlessein Headless-Browser wird zum Ausführen des Codes verwendetautomation
agentein KI-Coding-Agent, der den Code ausführtautomation
timingeine Ausführungspause, die auf einen Breakpoint oder einen schrittweise arbeitenden Debugger hindeutetdebugger
sandboxder Code läuft in einer Sandbox oder einer vorgetäuschten Host-Umgebungsandbox
domainder Ursprung der Seite steht nicht in der Erlaubnisliste von vmDomainLockdomain
nativeHookeine native Builtin-Funktion wurde ersetzt oder gehookttamper

Den Hook registrieren. Definieren Sie ihn als einfache globale Funktion bevor das obfuskierte Bundle geladen wird – die VM-Laufzeit und ihre Abwehrmechanismen laufen vor Ihrem (geschützten) Programm, sodass viele Erkennungen bereits während des Starts feuern:

// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }

Ein innerhalb des obfuskierten Quellcodes definierter Hook wird zu spät registriert, um Erkennungen zur Startzeit abzufangen, und falls er VM-kompiliert wird, ist er erst erreichbar, wenn Ihr Programm läuft. Er ist ohnehin abgesichert (ein fehlender Hook ist ein No-op, und ein Re-entrancy-Schutz verhindert Ausuferungen), doch für vollständige Abdeckung registrieren Sie ihn vorab. Um dennoch Ihre Meldelogik zu schützen, halten Sie den registrierten Hook als einzeiligen Puffer ((window.__vmDet = window.__vmDet || []).push(signal)) und lesen bzw. senden Sie diesen Puffer aus Ihrem obfuskierten Code.

Die Signalfelder umbenennen (aliases). Die Standardwerte von source/category sind beschreibende Namen, sodass jeder, der den Callback instrumentiert (oder die Ausgabe liest), den Schutz erkennen kann und weiß, welcher Detektor ausgelöst hat. aliases benennt Signalfelder in undurchsichtige Tokens Ihrer Wahl um, angewendet innerhalb der VM bevor das Signal ausgegeben wird, sodass diese Namen nie in der Ausgabe auftauchen oder den Callback erreichen. Ihre App kennt ihre eigene Zuordnung und leitet die Tokens an Ihr Backend weiter.

Die Aliase gelten pro Feld und halten das Umbenennen von Schlüsseln und Werten getrennt: Jedes Feld nimmt einen key (den Eigenschaftsnamen, den der Callback erhält); die string-basierten Namensfelder source und category nehmen zusätzlich eine values-Zuordnung, während score/threshold Zahlen sind und nur einen key nehmen. Die Namen, die Sie zuordnen können (alles andere wird zur Build-Zeit abgelehnt):

  • Feldschlüsselsource, category, score, threshold
  • source-Werteheadless, agent, node, debugger, timing, sandbox, domain, nativeHook, integrity
  • category-Werteautomation, 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> }
}

Dies dient der Vermeidung von Fingerprints, nicht der Geheimhaltung – die Zuordnung lässt sich durch wiederholtes Testen weiterhin erschließen –, sodass ihr einziger Nutzen darin besteht, keine stabilen, selbsterklärenden Namen preiszugeben. Nicht gesetzte Einträge behalten ihre Standardnamen.

Ein einfacher String (vmDefenseHook: '__vmDetection') wird als Kurzform für { name: '__vmDetection' } akzeptiert, ist aber veraltet – bevorzugen Sie die Objektform.

vmDefenseReaction

Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }

Konfiguriert, wie jede Erkennungskategorie reagiert. Sie aktiviert nichts – die Abwehrmechanismen selbst werden durch vmSelfDefending, vmDebugProtection und vmDomainLock eingeschaltet; diese Option wählt nur aus, wie eine aktivierte Abwehr reagiert. Die Kategorie ist die Steuerungseinheit – jeder Detektor einer Kategorie setzt die Reaktion dieser Kategorie um.

Jede Kategorie fasst die Detektoren zusammen, die auf eine bestimmte Art feindlicher Bedingung achten. Eine Kategorie reagiert nur, wenn die Option aktiviert ist, die ihre Detektoren ausgibt:

KategorieAktiviert durchReagiert, wenn
automationvmSelfDefending oder vmDebugProtectionDer Code wird von Software statt von einer Person gesteuert: ein Headless- oder automatisierter Browser, ein Scraping-/Test-Framework oder ein KI-Coding-Agent, der die Seite schrittweise durchgeht.
debuggervmDebugProtection oder vmSelfDefendingJemand hat einen Debugger oder den Inspector der Browser-Entwicklertools geöffnet und geht den laufenden Code schrittweise durch, um ihn zu verstehen.
sandboxvmDebugProtectionDer Code läuft überhaupt nicht in einem echten Browser – er wurde in eine emulierte oder skriptgesteuerte JavaScript-Umgebung überführt, um dort ausgeführt und offline untersucht zu werden.
domainvmDomainLockDer Code läuft auf einer Website, die Sie nicht autorisiert haben: ein Host, der nicht in Ihrer Erlaubnisliste von vmDomainLock steht (etwa Ihr Bundle, das auf die Domain eines anderen kopiert wurde).
tampervmSelfDefendingDie JavaScript-Umgebung rund um die VM wurde verändert, um sie zu beobachten oder zu kapern, etwa durch native Browser-Builtins, die gegen instrumentierte Versionen ausgetauscht wurden.
integrityvmSelfDefendingDer eigene Code des geschützten Bundles wurde seit seiner Erzeugung bearbeitet oder gepatcht.

Jede Kategorie ist einer oder mehreren der Optionen vmSelfDefending, vmDebugProtection und vmDomainLock zugeordnet; es gibt keine Kategorie außerhalb dieser drei Optionen, und eine Reaktion, die für eine Kategorie gesetzt ist, deren Option ausgeschaltet ist, hat schlicht keine Wirkung.

Schlüssel sind diese sechs Kategorienamen oder default (ein Rückfall für nicht angegebene Kategorien). Werte sind:

  • break – sofort abbrechen
  • decoy – auf vergiftetem Zustand weiterlaufen und dabei stillschweigend falsche Ergebnisse erzeugen
  • none – lokal nichts tun (nur Telemetrie)

Die kategoriespezifischen Standardwerte sind oben angegeben; eine Kategorie, die Sie nicht setzen (oder auf ihren Standardwert setzen), verwendet diesen Standard. default erreicht jede Kategorie, auch die per Konstruktion korrekten (integrity, tamper), sodass { default: 'none' } ein tatsächlich nicht abbrechender, reiner Telemetrie-Build ist:

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

Lässt die Bedeutung der Opcodes von der Position im Bytecode abhängen. Jede Position hat eine andere, aus einem Seed abgeleitete Zuordnung von Opcode zu Handler, sodass dieselbe Opcode-Nummer an unterschiedlichen Positionen unterschiedliche Operationen ausführt.

vmCallContextOpcodes

Type: boolean Default: false

Lässt eine geschützte Funktion davon abhängen, von wo aus sie aufgerufen wird, sodass sie sich nicht aus dem Code herauslösen und für sich allein ausführen oder analysieren lässt – sie verhält sich nur korrekt, wenn sie über ihre echten Aufrufstellen im Programm aufgerufen wird. Diese Option beeinträchtigt die Laufzeit-Performance.

Derzeit werden nur die folgenden Konstruktionen unterstützt:

  • Funktionsdeklarationen (function f() {});
  • einer Variablen zugewiesene Funktionsausdrücke und Pfeilfunktionen (const f = () => {});
  • private Instanzmethoden (this.#m()).

In jedem Fall muss die Funktion stets über einen direkten Aufruf erreicht werden (f(), this.#m()). Wird sie in einer anderen Variablen gespeichert, als Argument übergeben oder anderweitig als Wert verwendet, bleibt sie ungeschützt. Async-Funktionen werden unterstützt, Generatoren nicht.

Diese Option ist experimentell und kann Ihren Code beschädigen; testen Sie die Ausgabe daher gründlich, bevor Sie sie einsetzen.

vmStackEncoding

Type: boolean Default: false

Verschlüsselt die Werte auf dem VM-Stack während der Ausführung. Werte werden beim Ablegen codiert und beim Entnehmen decodiert, sodass eine Speicheruntersuchung verschlüsselte Daten statt der tatsächlichen Werte zeigt.

Diese Option beeinträchtigt die Performance stark.

vmCompactDispatcher

Type: boolean Default: false

Verwendet einen einzigen VM-Executor statt zweier Executoren (synchron + Generator). Reduziert die Größe des obfuskierten Codes, fügt aber bei rekursionsintensivem Code etwa 20 % Performance-Mehraufwand hinzu.

  • false (Standard): zwei Executoren – optimale Performance, größere Ausgabe
  • true: ein Executor – kleinere Ausgabe, etwas langsamer

vmStringArrayBytecodeOnly

Type: boolean Default: false

Ist die Option aktiviert, extrahiert das String-Array ausschließlich Strings aus Bytecode-Daten – keine anderen Strings im Code werden transformiert. Dadurch wird stringArray zwangsweise aktiviert, selbst wenn es nicht ausdrücklich gesetzt ist.

Warum verwenden: Sämtliche VM-Laufzeit-Strings in ein String-Array zu extrahieren, ist langsam. Diese Option richtet die String-Array-Extraktion nur auf Bytecode-Inhalte aus und verbessert so die Performance, während die Bytecode-Konstanten weiterhin geschützt bleiben.

  • Bei vmBytecodeArrayEncoding: false werden Strings innerhalb der Bytecode-Konstantenpools (c-Arrays) extrahiert
  • Bei vmBytecodeArrayEncoding: true werden die base64-codierten Bytecode-Strings der obersten Ebene extrahiert
  • stringArrayThreshold steuert weiterhin, welcher Prozentsatz dieser Bytecode-Strings extrahiert wird

vmDomainLock

Type: string[] Default: []

⚠️ Diese Option funktioniert nicht mit target: 'node', target: 'service-worker' oder target: 'bytenode'

Beschränkt den obfuskierten Code auf bestimmte Domains und/oder Subdomains und ist deutlich schwerer aufzuspüren und zu entfernen als domainLock.

Wird der Quellcode nicht auf den mit dieser Option angegebenen Domains ausgeführt, leitet der Browser auf die an vmDomainLockRedirectUrl übergebene URL um, und weitere geschützte Aufrufe liefern selbst dann falsche Ergebnisse, wenn die Weiterleitung unterdrückt wird.

Mehrere Domains und Subdomains

Sie können Ihren Code an mehr als eine Domain oder Subdomain binden. Um ihn zum Beispiel so zu sperren, dass er nur auf www.example.com läuft, fügen Sie www.example.com hinzu. Damit er auf der Root-Domain einschließlich aller Subdomains läuft (example.com, sub.example.com), verwenden Sie .example.com.

vmDomainLockRedirectUrl

Type: string Default: about:blank

⚠️ Diese Option funktioniert nicht mit target: 'node', target: 'service-worker' oder target: 'bytenode'

Leitet den Browser auf eine übergebene URL um, wenn der Quellcode nicht auf den unter vmDomainLock angegebenen Domains ausgeführt wird.

Preset Options

Hohe Obfuskierung, geringe Performance

Die Performance ist deutlich schlechter als ohne Obfuskierung

{
    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
}

Mittlere Obfuskierung, optimale Performance

Die Performance ist schlechter als ohne Obfuskierung

{
    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
}

Geringe Obfuskierung, hohe Performance

Die Performance bleibt auf einem relativ normalen Niveau

{
    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
}

Standardvoreinstellung, hohe Performance

{
    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
}

VM Ultra High – Obfuskierung (maximale Sicherheit)

Diese Voreinstellung aktiviert die VM-basierte Bytecode-Obfuskierung mit allen Härtungsfunktionen einschließlich indirektem Dispatch. Bietet den stärksten Schutz, jedoch mit größerer Ausgabe und deutlich langsamerer Ausführung.

{
    optionsPreset: 'vm-ultra-high-obfuscation'
}

Oder einzeln konfigurieren:

{
    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 (Schutz vor KI-Agenten)

Diese Voreinstellung ist eigens dafür ausgelegt, KI-Agenten und LLMs am Reverse Engineering von VM-Bytecode-Code zu hindern. Basiert auf vm-default mit aktiviertem Self Defending und Debug Protection. Leichter als vm-high-obfuscation, aber gezielt gegen automatisierte Analyse gehärtet.

{
    optionsPreset: 'vm-anti-llm'
}

Enthält:

  • VM-Bytecode-Obfuskierung mit String-Array (aus vm-default)
  • vmSelfDefending – Anti-Hook-Erkennung, Integritäts-Hash, Quell-Fingerprint, iframe-basierte Verifikation eines sauberen Realms, ARX-Cipher-Schlüsselableitung
  • vmDebugProtection – Anti-Debugging-Prüfungen in der VM-Dispatch-Schleife
  • debugProtection: false – keine veraltete Debug Protection (der VM-Debug-Schutz ist überlegen)

VM High – Obfuskierung (höchste Sicherheit)

Diese Voreinstellung aktiviert die VM-basierte Bytecode-Obfuskierung mit den meisten Härtungsfunktionen. Bietet starken Schutz bei besserer Performance als die Ultra-High-Voreinstellung.

{
    optionsPreset: 'vm-high-obfuscation'
}

Oder einzeln konfigurieren:

{
    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
}

VM Medium – Obfuskierung (ausgewogene Sicherheit)

Diese Voreinstellung aktiviert die VM-basierte Bytecode-Obfuskierung mit einem ausgewogenen Satz an Härtungsfunktionen. Guter Kompromiss zwischen Sicherheit und Performance.

{
    optionsPreset: 'vm-medium-obfuscation'
}

Oder einzeln konfigurieren:

{
    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
}

VM Low – Obfuskierung (Basissicherheit, bessere Performance)

Diese Voreinstellung aktiviert eine grundlegende VM-basierte Bytecode-Obfuskierung ohne zusätzliche Härtungsfunktionen. Gute Balance zwischen Sicherheit und Ausgabegröße.

{
    optionsPreset: 'vm-low-obfuscation'
}

Oder einzeln konfigurieren:

{
    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- + String-Array-Schutz)

Diese Voreinstellung kombiniert eine grundlegende VM-basierte Bytecode-Obfuskierung mit String-Array-Schutz. Guter Ausgangspunkt für die VM-Obfuskierung mit String-Schutz.

{
    optionsPreset: 'vm-default'
}

Oder einzeln konfigurieren:

{
    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
}