Direktes eval() deaktiviert die VM-Obfuskierung
Enthält eine Funktion irgendwo in ihrem Rumpf (auch in verschachtelten Funktionen) einen direkten eval(code)-Aufruf, wird diese Funktion von der VM-Obfuskierung übersprungen, und der Obfuscator meldet eine Warnung VMDynamicCodeSkipped (die die Funktion benennt, sofern sie einen Namen hat). Im Root-Modus (der Standardeinstellung) wird die gesamte Funktion samt aller verschachtelten Funktionen übersprungen; im Kommentarmodus wird eine verschachtelte Funktion, die Sie separat markieren, dennoch virtualisiert, sofern sie nicht selbst eval enthält. Ein direktes eval mit nicht statischem Argument gibt außerdem eine Warnung DynamicCodeRenameRisk aus. Der Grund: Direktes eval hat Zugriff auf die lokalen Variablen der umschließenden Funktion, die nicht mehr verfügbar sind, wenn die Funktion zu VM-Bytecode kompiliert wird.
Wichtig für in eine IIFE eingebetteten Code. Enthält eine IIFE auf oberster Ebene irgendwo tief im Inneren ein direktes eval, wird die gesamte IIFE (einschließlich Ihres gesamten Codes) nicht VM-obfuskiert.
Das Auflösen der IIFE hat einen Nachteil: Sobald Ihre Funktionen auf oberster Ebene liegen, wird zwar nur die betroffene Funktion übersprungen, doch die übrigen Funktionen befinden sich nun auf oberster Ebene, sodass die VM-Obfuskierung ihre Namen beibehält. Wie Sie diese Namen aus der Ausgabe heraushalten, erfahren Sie unter Funktionsnamen vor der LLM-Analyse verbergen.
Indirekte Formen wie (0, eval)(code) und window.eval(code) blockieren die VM-Obfuskierung nicht. Eine Ausnahme ist eval?.(code): JavaScript führt es als indirektes eval aus, doch der Obfuscator behandelt es vorsichtshalber wie direktes eval und überspringt die Funktion.
Der Function-Konstruktor (new Function(body) / Function(body)) wird genauso behandelt, wenn das Rumpf-Argument dynamisch ist. Eine Funktion mit einem dynamischen new Function(...)-Aufruf wird ebenfalls übersprungen, mit einer Warnung VMDynamicCodeSkipped. Wie bei einem dynamischen direkten eval gibt der Obfuscator zusätzlich eine Warnung DynamicCodeRenameRisk aus, weil der zur Laufzeit erzeugte Rumpf auf umbenannte Bezeichner verweisen kann. Vollständig statische Aufrufe wie new Function('a', 'b', 'return a + b') werden nicht übersprungen.
Indirektes eval und der Function-Konstruktor werden im globalen Gültigkeitsbereich ausgeführt. Sie können die lokalen Variablen des Aufrufers nicht lesen, aber dennoch fehlschlagen, wenn sie auf globale Bezeichner verweisen, die umbenannt oder entfernt wurden. Ein statischer Rumpf, der nur seine eigenen Parameter verwendet, etwa new Function('a', 'b', 'return a + b'), vermeidet diese Abhängigkeit. Prüfen Sie die Warnungen und testen Sie das fertige Bundle; eine bloße Änderung der eval-Syntax macht beliebigen dynamischen Code nicht sicher.
Ausweg (v6.14.0+): Setzen Sie vmForceCompileDynamicCode: true (oder aktivieren Sie den Schalter Force Compile Dynamic Code in der Gruppe Überschreibungen des VM-Bereichs), um die umgebende Funktion trotzdem in Bytecode umzuwandeln und VMDynamicCodeSkipped zu unterdrücken. Probleme mit dem Gültigkeitsbereich behebt das nicht: Innerhalb einer zwangsweise kompilierten Funktion kann direktes eval weder die lokalen Variablen der Funktion noch ihre Parameter oder die Variablen einer virtualisierten umschließenden Funktion lesen oder schreiben, selbst wenn der Code ein String-Literal ist. Verwenden Sie die Option nur, wenn der ausgewertete Code ausschließlich auf globale Bezeichner verweist. DynamicCodeRenameRisk wird auch mit aktivierter Option weiterhin ausgegeben, weil das beschriebene Umbenennungsrisiko unabhängig vom Überspringen durch die VM ist.
Unter VM-Obfuskierung mit eval und new Function finden Sie die vollständige Übersicht, die Form der Warnungen und Umgehungen.
