Cómo transforma el código la VM
Ver
Obfuscator.io: Targeting Functions in VM Obfuscation (IIFE and Comment Mode)
Con vmTargetFunctionsMode: 'root' (el valor predeterminado), la ofuscación VM transforma el cuerpo de cada función de nivel raíz (o, con vmAsyncExecutor, de cada función async más externa) en bytecode. Las funciones de nivel raíz conservan su nombre; las anidadas se renombran como de costumbre. Para seleccionar funciones individuales en cualquier nivel de anidamiento, usa el modo comment.
Este diseño mantiene la compatibilidad con el código que llama a estas funciones desde el ámbito global o espera encontrarlas en el objeto global. El cuerpo de la función queda totalmente protegido, pero el nombre sigue siendo visible, y el ofuscador emite una advertencia VMGlobalFunctionNamesNotRenamed con la lista de esos nombres.
La ofuscación VM protege los cuerpos de las funciones, además de los inicializadores de variables de nivel superior cuando vmWrapTopLevelInitializers está activada (ver más abajo). Si la entrada no contiene ninguna función ni ningún inicializador de ese tipo (código solo de nivel superior, como alert(1);), no se virtualiza nada: el resto de la ofuscación se ejecuta igualmente, pero no se aplica protección VM, y el ofuscador emite una advertencia VMNoFunctionsToVirtualize (v7.14.1+; la propia 7.14.0 está deshabilitada). También se emite cuando hay funciones pero se omitieron todas (por ejemplo, un eval directo o un new Function dinámico, que vmTargetFunctions/vmExcludeFunctions no dejen nada seleccionado, o que vmAsyncExecutor no encuentre ninguna función async). Envuelve en una función el código que quieras proteger, por ejemplo en una IIFE.
Inicializadores de nivel superior
En el modo root, vmWrapTopLevelInitializers envuelve en IIFE los inicializadores de variables de nivel superior elegibles, como const MY_STRING = 'my-string';, para que sus valores pasen al bytecode en lugar de quedar visibles como JavaScript normal. Los preajustes VM actuales lo activan. Solo cubre inicializadores de variables, no otras sentencias de nivel superior, y no tiene efecto en el modo comment. Los inicializadores que se quedan en JavaScript normal aparecen en una advertencia VMTopLevelInitializerNotVirtualized.
Ocultar nombres de funciones sensibles
Como el modo root conserva el nombre, un nombre revelador como validateLicense o decryptData sigue siendo legible aunque su cuerpo se convierta en bytecode. La solución es sacar la función del nivel superior (envolverla en una IIFE, donde deja de ser de nivel raíz y se transforma por completo con la VM, nombre incluido) o renombrar los identificadores de nivel raíz con renameGlobals. Consulta Ocultar los nombres de las funciones al análisis con LLM para ver ambas técnicas y sus contrapartidas.
