Documentation
/
Obfuscation VM
/

Comportement de l'eval direct

Un eval() direct désactive l'obfuscation VM

Si une fonction contient un appel direct eval(code) n'importe où dans son corps (y compris dans des fonctions imbriquées), cette fonction est ignorée par l'obfuscation VM et l'obfuscateur émet un avertissement VMDynamicCodeSkipped (qui nomme la fonction lorsqu'elle a un nom). En mode root (le mode par défaut), la fonction entière et toutes ses fonctions imbriquées sont ignorées ; en mode comment, une fonction imbriquée que vous marquez séparément est tout de même virtualisée, sauf si elle contient elle-même l'eval. Un eval direct avec un argument non statique émet aussi un avertissement DynamicCodeRenameRisk. En effet, un eval direct a accès aux variables locales de la fonction englobante, qui ne sont plus disponibles une fois la fonction compilée en bytecode VM.

Important pour le code enveloppé dans une IIFE. Si une IIFE de premier niveau contient un eval direct, même profondément imbriqué, l'IIFE entière (y compris tout votre code) ne sera pas obfusquée par la VM.

JavaScript

Désenvelopper l'IIFE a une contrepartie : une fois vos fonctions au niveau racine, seule la fonction fautive est ignorée, mais les fonctions restantes sont désormais de premier niveau, et l'obfuscation VM conserve donc leurs noms. Consultez Masquer les noms de fonctions à l'analyse par LLM pour savoir comment garder ces noms hors de la sortie.

Les formes indirectes comme (0, eval)(code) et window.eval(code) ne bloquent pas l'obfuscation VM. eval?.(code) fait exception : JavaScript l'exécute comme un eval indirect, mais l'obfuscateur le traite par prudence comme un eval direct et ignore la fonction.

Le constructeur Function (new Function(body) / Function(body)) est traité de la même manière lorsque l'argument du corps est dynamique. Une fonction contenant un appel dynamique new Function(...) est elle aussi ignorée, avec un avertissement VMDynamicCodeSkipped. Comme pour un eval direct dynamique, l'obfuscateur ajoute un avertissement DynamicCodeRenameRisk, car le corps construit à l'exécution peut faire référence à des identifiants renommés. Les appels entièrement statiques comme new Function('a', 'b', 'return a + b') ne sont pas ignorés.

Un eval indirect et le constructeur Function s'exécutent dans la portée globale. Ils ne peuvent pas lire les variables locales de l'appelant, mais peuvent quand même échouer s'ils font référence à des globales renommées ou supprimées. Un corps statique qui n'utilise que ses propres paramètres, comme new Function('a', 'b', 'return a + b'), évite cette dépendance. Examinez les avertissements et testez le bundle final ; changer la syntaxe de l'eval ne suffit pas à rendre sûr du code dynamique arbitraire.

Échappatoire (v6.14.0+) : définissez vmForceCompileDynamicCode: true (ou activez l'interrupteur Force Compile Dynamic Code dans le groupe Surcharges de la section VM) pour convertir malgré tout la fonction englobante en bytecode et supprimer l'avertissement VMDynamicCodeSkipped. Cela ne peut pas corriger la portée : dans une fonction compilée de force, un eval direct ne peut ni lire ni écrire les variables locales de la fonction, ses paramètres ou les variables d'une fonction englobante virtualisée, même lorsque le code est un littéral de chaîne. Ne l'utilisez que si le code évalué ne fait référence qu'à des globales. DynamicCodeRenameRisk continue de se déclencher avec cette option activée, car le risque de renommage qu'il décrit est indépendant de l'exclusion de la VM.

Consultez Obfuscation VM avec eval et new Function pour la matrice complète, la forme des avertissements et les solutions de contournement.