Как VM преобразует код
Смотреть
Obfuscator.io: Targeting Functions in VM Obfuscation (IIFE and Comment Mode)
При vmTargetFunctionsMode: 'root' (по умолчанию) VM-обфускация превращает в байт-код тело каждой функции корневого уровня (или, с vmAsyncExecutor, каждой самой внешней async-функции). Функции корневого уровня сохраняют свои имена; вложенные переименовываются как обычно. Чтобы вместо этого выбирать отдельные функции на любом уровне вложенности, используйте режим комментариев.
Такой подход сохраняет совместимость с кодом, который вызывает эти функции из глобальной области видимости или ожидает найти их в глобальном объекте. Тело функции полностью защищено, но имя остаётся видимым, и обфускатор выдаёт предупреждение VMGlobalFunctionNamesNotRenamed со списком таких имён.
VM-обфускация защищает тела функций, а также инициализаторы переменных верхнего уровня, когда включена vmWrapTopLevelInitializers (см. ниже). Если во входном коде нет ни функций, ни таких инициализаторов - только код верхнего уровня, например alert(1);, - ничего не виртуализируется: остальная обфускация по-прежнему выполняется, но VM-защита не применяется, и обфускатор выдаёт предупреждение VMNoFunctionsToVirtualize (v7.14.1+; сама версия 7.14.0 отключена). Оно также выдаётся, когда функции есть, но все они были пропущены (например, из-за прямого eval или динамического new Function, из-за того, что vmTargetFunctions/vmExcludeFunctions ничего не оставили выбранным, или из-за того, что vmAsyncExecutor не нашла ни одной async-функции). Оберните код, который хотите защитить, в функцию, например в IIFE.
Инициализаторы верхнего уровня
В режиме root опция vmWrapTopLevelInitializers оборачивает подходящие инициализаторы переменных верхнего уровня, такие как const MY_STRING = 'my-string';, в IIFE, чтобы их значения переносились в байт-код, а не оставались на виду в виде обычного JavaScript. Текущие VM-пресеты её включают. Она охватывает только инициализаторы переменных, а не другие инструкции верхнего уровня, и не действует в режиме комментариев. Инициализаторы, оставшиеся обычным JavaScript, перечисляются в предупреждении VMTopLevelInitializerNotVirtualized.
Как скрыть чувствительные имена функций
Поскольку режим root сохраняет имя, говорящее имя вроде validateLicense или decryptData остаётся читаемым, даже когда тело функции стало байт-кодом. Решение - убрать функцию с верхнего уровня (обернуть её в IIFE, где она уже не относится к корневому уровню и полностью преобразуется VM, включая имя) или переименовать идентификаторы корневого уровня с помощью renameGlobals. Оба приёма и их компромиссы описаны в разделе Как скрыть имена функций от анализа LLM.
