Справочник опций
Содержание
compact
config
controlFlowFlattening
controlFlowFlatteningThreshold
deadCodeInjection
deadCodeInjectionThreshold
debugProtection
debugProtectionInterval
disableConsoleOutput
domainLock
Несколько доменов и поддоменов
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
Несколько доменов и поддоменов
vmDomainLockRedirectUrl
Preset Options
Высокая обфускация, низкая производительность
Средняя обфускация, оптимальная производительность
Низкая обфускация, высокая производительность
Пресет по умолчанию, высокая производительность
VM Ultra High obfuscation (максимальная безопасность)
VM Anti-LLM (защита от ИИ-агентов)
VM High obfuscation (наивысшая безопасность)
VM Medium obfuscation (сбалансированная безопасность)
VM Low obfuscation (базовая безопасность, лучшая производительность)
VM Default (VM + защита массивом строк)
compact
Type: boolean Default: true
Компактный вывод кода в одну строку.
config
Type: string Default: ``
Имя JS/JSON-файла конфигурации, содержащего опции обфускатора. Эти опции будут переопределены опциями, переданными напрямую в CLI
controlFlowFlattening
Type: boolean Default: false
⚠️ Эта опция сильно влияет на производительность — скорость выполнения падает вплоть до 1,5 раз. Используйте controlFlowFlatteningThreshold, чтобы задать процент узлов, к которым будет применено уплощение потока управления.
Включает уплощение потока управления кода. Уплощение потока управления — это структурное преобразование исходного кода, затрудняющее понимание программы.
Пример:
// 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
Вероятность того, что преобразование controlFlowFlattening будет применено к тому или иному узлу.
Эта настройка особенно полезна для кода большого размера, поскольку большое количество преобразований потока управления может замедлить ваш код и увеличить его размер.
controlFlowFlatteningThreshold: 0 эквивалентно controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Резко увеличивает размер обфусцированного кода (до 200%), используйте только если размер обфусцированного кода не имеет значения. Используйте deadCodeInjectionThreshold, чтобы задать процент узлов, к которым будет применено внедрение мёртвого кода.
⚠️ Эта опция принудительно включает опцию stringArray.
⚠️ Эта опция незаметно отключается, когда включена vmObfuscation.
С этой опцией в обфусцированный код будут добавлены случайные блоки мёртвого кода.
Пример:
// 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
Позволяет задать процент узлов, к которым будет применён deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Может подвесить ваш браузер, если вы откроете инструменты разработчика.
⚠️ Эта опция незаметно отключается, когда включена vmObfuscation. Используйте вместо неё vmDebugProtection.
Эта опция делает практически невозможным использование функции debugger в инструментах разработчика (как в браузерах на основе WebKit, так и в Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Может подвесить ваш браузер! Используйте на свой страх и риск.
⚠️ Эта опция незаметно отключается, когда включена vmObfuscation. Используйте вместо неё vmDebugProtection.
Если значение задано, интервал в миллисекундах используется для принудительного входа в режим отладки на вкладке Console, что затрудняет использование других возможностей инструментов разработчика. Работает, если включена опция debugProtection. Рекомендуемое значение — от 2000 до 4000 миллисекунд.
disableConsoleOutput
Type: boolean Default: false
⚠️ Эта опция отключает вызовы console глобально для всех скриптов
Отключает использование console.log, console.info, console.error, console.warn, console.debug, console.exception и console.trace, заменяя их пустыми функциями. Это усложняет работу с отладчиком.
domainLock
Type: string[] Default: []
⚠️ Эта опция не работает с target: 'node', target: 'service-worker' или target: 'bytenode'
Позволяет запускать обфусцированный исходный код только на определённых доменах и/или поддоменах. Из-за этого становится по-настоящему сложно просто скопировать ваш исходный код и запустить его в другом месте.
Если исходный код запущен не на доменах, указанных в этой опции, браузер будет перенаправлен на URL, переданный в опции domainLockRedirectUrl.
Несколько доменов и поддоменов
Код можно привязать более чем к одному домену или поддомену. Например, чтобы код работал только на www.example.com, добавьте www.example.com. Чтобы он работал на корневом домене, включая любые поддомены (example.com, sub.example.com), используйте .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Эта опция не работает с target: 'node', target: 'service-worker' или target: 'bytenode'
Позволяет перенаправить браузер на переданный URL, если исходный код запущен не на доменах, указанных в domainLock
exclude
Type: string[] Default: []
Имена файлов или glob-шаблоны, указывающие, какие файлы нужно исключить из обфускации.
forceTransformStrings
Type: string[] Default: []
Включает принудительное преобразование строковых литералов, которые соответствуют переданным шаблонам RegExp.
⚠️ Эта опция влияет только на строки, которые не должны преобразовываться из-за stringArrayThreshold (или, возможно, других порогов в будущем)
Эта опция имеет приоритет над опцией reservedStrings, но не имеет приоритета над условными комментариями.
Пример:
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
Главная цель этой опции — возможность использовать одни и те же имена идентификаторов при обфускации нескольких исходников/файлов.
В настоящее время поддерживаются два типа идентификаторов:
- Глобальные идентификаторы:
- Все глобальные идентификаторы будут записаны в кэш;
- Все совпавшие необъявленные глобальные идентификаторы будут заменены значениями из кэша.
- Идентификаторы свойств, только когда включена опция
renameProperties:- Все идентификаторы свойств будут записаны в кэш;
- Все совпавшие идентификаторы свойств будут заменены значениями из кэша.
Node.js API
Если передано значение null, кэш полностью отключается.
Если передан пустой объект ({}), включается запись имён идентификаторов в кэш-объект (тип TIdentifierNamesCache). Доступ к этому кэш-объекту можно получить через вызов метода getIdentifierNamesCache объекта ObfuscationResult.
Полученный кэш-объект затем можно использовать как значение опции identifierNamesGenerator, чтобы применять эти имена при обфускации всех совпавших имён идентификаторов в следующих исходниках.
Пример:
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
В CLI есть отдельная опция --identifier-names-cache-path, которая позволяет задать путь к существующему .json-файлу, используемому для чтения и записи кэша имён идентификаторов.
Если передать путь к пустому файлу — кэш имён идентификаторов будет записан в этот файл.
Этот файл с уже имеющимся кэшем можно снова использовать как значение опции --identifier-names-cache-path, чтобы применять эти имена при обфускации всех совпавших имён идентификаторов в следующих файлах.
identifierNamesGenerator
Type: string Default: hexadecimal
Задаёт генератор имён идентификаторов.
Доступные значения:
dictionary: имена идентификаторов из спискаidentifiersDictionaryhexadecimal: имена идентификаторов вида_0xabc123mangled: короткие имена идентификаторов, напримерa,b,cmangled-shuffled: то же, что иmangled, но с перемешанным алфавитом
identifiersDictionary
Type: string[] Default: []
Задаёт словарь идентификаторов для identifierNamesGenerator со значением dictionary. Каждый идентификатор из словаря будет использован в нескольких вариантах с разным регистром каждого символа. Поэтому количество идентификаторов в словаре должно зависеть от количества идентификаторов в исходном коде.
identifiersPrefix
Type: string Default: ''
Задаёт префикс для всех глобальных идентификаторов.
Используйте эту опцию, когда нужно обфусцировать несколько файлов. Она помогает избежать конфликтов между глобальными идентификаторами этих файлов. Префикс должен быть разным для каждого файла.
randomIdentifiersPrefix
Type: boolean Default: false
Добавляет случайный префикс на основе зерна (6 буквенно-цифровых символов) ко всем глобальным идентификаторам. Используйте эту опцию, чтобы избежать коллизий между обфусцированными по отдельности бандлами, которые загружаются в одну и ту же глобальную область видимости, — она избавляет от необходимости вручную выбирать уникальный identifiersPrefix для каждого бандла.
- Случайное значение выводится из опции
seedи хеша исходного кода, поэтому воспроизводимые сборки с одним и тем же зерном дают один и тот же префикс. - В сочетании с
identifiersPrefixслучайные символы добавляются к заданному пользователем префиксу (например,myApp+ случайноеaBc123→myAppaBc123). - В сочетании с
vmObfuscationслучайное значение заменяет префиксvmпо умолчанию — случайность уже гарантирует уникальность.
ignoreImports
Type: boolean Default: false
Предотвращает обфускацию импортов require. Может быть полезно в тех случаях, когда среда выполнения по какой-то причине требует, чтобы такие импорты содержали только статические строки.
inputFileName
Type: string Default: ''
Позволяет задать имя входного файла с исходным кодом. Это имя будет использоваться внутри для генерации source map.
Обязательна при использовании NodeJS API, когда опция sourceMapSourcesMode имеет значение sources.
log
Type: boolean Default: false
Включает вывод информации в консоль.
numbersToExpressions
Type: boolean Default: false
Включает преобразование чисел в выражения
Пример:
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Позволяет задать пресет опций.
Доступные значения:
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.
Все дополнительные опции будут объединены с выбранным пресетом опций.
parseHtml
Type: boolean Default: false
Включает обфускацию JavaScript внутри HTML-тегов <script>.
Когда опция включена, обфускатор будет:
- Автоматически определять, является ли входные данные HTML (по наличию тегов
<!DOCTYPE,<html>,<head>,<body>или<script>) - Извлекать JavaScript из тегов
<script>, помеченных атрибутомdata-javascript-obfuscator - Обфусцировать каждый помеченный скрипт по отдельности, сохраняя структуру HTML
- Вставлять обфусцированный код обратно на исходные позиции
Важно: обфусцируются только скрипты с атрибутом data-javascript-obfuscator. Каждый помеченный скрипт обфусцируется по отдельности и независимо. Это означает:
- Код внутри помеченных тегов script должен быть изолированным — он НЕ должен ссылаться на переменные, функции или классы, определённые в других помеченных тегах script
- Непомеченные скрипты по-прежнему могут обращаться к глобальным переменным, определённым помеченными скриптами (через объявления
varили явные присваиванияglobalThis) - Это даёт вам явный контроль над тем, какие скрипты защищать
Обфусцируются (должны иметь атрибут data-javascript-obfuscator):
<script data-javascript-obfuscator>— обычные скрипты<script type="text/javascript" data-javascript-obfuscator>— скрипты с явно указанным типом- Скрипты с любыми дополнительными атрибутами (
id,class, другиеdata-*и т. д.)
Пропускаются (остаются без изменений):
- Скрипты без атрибута
data-javascript-obfuscator <script type="module">— ES-модули (даже с атрибутом)<script src="...">— внешние скрипты (даже с атрибутом)- Пустые теги script
Примечание: при включённой parseHtml source map не генерируются, так как они не соотносились бы корректно с выводом HTML.
Пример:
// 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
⚠️ эта опция может сломать ваш код. Включайте её, только если понимаете, что она делает!
Включает обфускацию имён глобальных переменных и функций с объявлением.
Когда эта опция отключена, а входной код объявляет функции или классы в глобальной области видимости (то есть код не обёрнут в IIFE), их имена сохраняются как есть в обфусцированном выводе — другие скрипты могут ссылаться на них по имени. При vmObfuscation выдаётся предупреждение VMGlobalFunctionNamesNotRenamed со списком этих имён, поскольку тело функции скрыто в виде байт-кода, но читаемое имя верхнего уровня всё равно раскрывает, что делает код (например, для LLM). Чтобы избежать этого раскрытия, оберните код в IIFE или включите эту опцию.
renameProperties
Type: boolean Default: false
⚠️ эта опция МОЖЕТ сломать ваш код. Включайте её, только если понимаете, что она делает!
Включает переименование имён свойств. Все встроенные свойства DOM и свойства базовых классов JavaScript будут проигнорированы.
Для переключения между режимами safe и unsafe этой опции используйте опцию renamePropertiesMode.
Чтобы задать формат переименованных имён свойств, используйте опцию identifierNamesGenerator.
Чтобы управлять тем, какие свойства будут переименованы, используйте опцию reservedNames.
Пример:
// 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
⚠️ Даже в режиме safe опция renameProperties МОЖЕТ сломать ваш код.
Задаёт режим опции renameProperties:
safe— поведение по умолчанию после релиза2.11.0. Пытается переименовывать свойства более безопасным образом, чтобы предотвратить ошибки во время выполнения. В этом режиме часть свойств будет исключена из переименования.unsafe— поведение по умолчанию до релиза2.11.0. Переименовывает свойства небезопасным образом, без каких-либо ограничений.
Если один файл использует свойства из другого файла, используйте опцию identifierNamesCache, чтобы сохранить одинаковые имена свойств в этих файлах.
reservedNames
Type: string[] Default: []
Отключает обфускацию и генерацию идентификаторов, которые соответствуют переданным шаблонам RegExp.
Пример:
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Отключает преобразование строковых литералов, которые соответствуют переданным шаблонам RegExp. Совпавшие строки останутся видимыми в обфусцированном выводе.
При VM-обфускации зарезервированные строки хранятся в отдельном незашифрованном массиве, чтобы оставаться видимыми. Это полезно для строк, которые должны оставаться читаемыми, например для API-эндпоинтов мониторинга или идентификаторов библиотек.
Пример:
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Эта опция задаёт зерно (seed) для генератора случайных чисел. Это полезно для получения воспроизводимых результатов.
Если seed равен 0 — генератор случайных чисел будет работать без зерна.
selfDefending
Type: boolean Default: false
⚠️ Не изменяйте обфусцированный код никаким образом после обфускации с этой опцией, поскольку любое изменение, например минификация кода, может сработать как триггер самозащиты, и код перестанет работать!
⚠️ Эта опция принудительно устанавливает значение compact в true
⚠️ Эта опция незаметно отключается, когда включена vmObfuscation. Используйте вместо неё vmSelfDefending.
Эта опция делает выходной код устойчивым к форматированию и переименованию переменных. Если кто-то попытается применить к обфусцированному коду JavaScript-beautifier, код перестанет работать, что усложнит его понимание и изменение.
simplify
Type: boolean Default: true
Включает дополнительную обфускацию кода за счёт упрощения.
⚠️ в будущих релизах обфускация литералов boolean (true => !![]) будет перенесена под эту опцию.
Пример:
// 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
Включает генерацию source map для обфусцированного кода.
Source map могут помочь вам отлаживать обфусцированный исходный код JavaScript. Если вы хотите или вам необходимо отлаживать код в продакшене, вы можете загрузить отдельный файл source map в секретное место и указать на него браузеру.
sourceMapBaseUrl
Type: string Default: ``
Задаёт базовый URL для URL импорта source map при sourceMapMode: 'separate'.
Пример для CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Результат:
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Задаёт имя файла для выходного source map при sourceMapMode: 'separate'.
Пример для CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Результат:
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Задаёт режим генерации source map:
inline— добавляет source map в конец каждого .js-файла;separate— генерирует соответствующий файл '.map' с source map. Если вы запускаете обфускатор через CLI — добавляет в конец файла с обфусцированным кодом ссылку на файл source map//# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Позволяет управлять полями sources и sourcesContent в source map:
sources-content— добавляет фиктивное полеsourcesи полеsourcesContentс исходным кодом;sources— добавляет полеsourcesс корректным описанием источника и не добавляет полеsourcesContent. При использовании NodeJS API необходимо задать опциюinputFileName, значение которой будет использовано как значение поляsources.
splitStrings
Type: boolean Default: false
Разбивает строковые литералы на части длиной, равной значению опции splitStringsChunkLength.
Пример:
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Задаёт длину части для опции splitStrings.
stringArray
Type: boolean Default: true
Убирает строковые литералы и помещает их в специальный массив. Например, строка "Hello World" в var m = "Hello World"; будет заменена на что-то вроде var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ должна быть включена опция stringArray
Включает преобразование вызовов к stringArray. Все аргументы этих вызовов могут быть вынесены в отдельный объект в зависимости от значения stringArrayCallsTransformThreshold.
Благодаря этому автоматически найти вызовы массива строк становится ещё сложнее.
Пример:
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
⚠️ должны быть включены опции stringArray и stringArrayCallsTransformThreshold
С помощью этой настройки можно отрегулировать вероятность (от 0 до 1) того, что вызовы массива строк будут преобразованы.
stringArrayEncoding
Type: string[] Default: []
⚠️ должна быть включена опция stringArray
Эта опция может замедлить ваш скрипт.
Кодирует все строковые литералы stringArray с помощью base64 или rc4 и вставляет специальный код, который декодирует их обратно во время выполнения.
Каждое значение stringArray будет закодировано случайно выбранной кодировкой из переданного списка. Это позволяет использовать несколько кодировок сразу.
Доступные значения:
'none'(boolean): не кодирует значениеstringArray'base64'(string): кодирует значениеstringArrayс помощьюbase64'rc4'(string): кодирует значениеstringArrayс помощьюrc4. Примерно на 30–50% медленнее, чемbase64, но получить исходные значения сложнее.
Например, при следующих значениях опций часть значений stringArray не будет закодирована, а часть будет закодирована кодировками base64 и rc4:
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ должна быть включена опция stringArray
Позволяет управлять типом индексов в вызовах массива строк.
Каждый индекс вызова stringArray будет преобразован случайно выбранным типом из переданного списка. Это позволяет использовать несколько типов сразу.
Доступные значения:
'hexadecimal-number'(default): преобразует индексы вызовов массива строк в шестнадцатеричные числа'hexadecimal-numeric-string': преобразует индексы вызовов массива строк в шестнадцатеричные числовые строки
До релиза 2.9.0 javascript-obfuscator преобразовывал все индексы вызовов массива строк с типом hexadecimal-numeric-string. Это немного усложняет ручную деобфускацию, но позволяет автоматическим деобфускаторам легко обнаруживать такие вызовы.
Новый тип hexadecimal-number призван усложнить автоматическое обнаружение шаблонов вызовов массива строк в коде.
В будущем будут добавлены и другие типы.
stringArrayIndexShift
Type: boolean Default: true
⚠️ должна быть включена опция stringArray
Включает дополнительный сдвиг индекса для всех вызовов массива строк
stringArrayRotate
Type: boolean Default: true
⚠️ должна быть включена опция stringArray
Сдвигает массив stringArray на фиксированное случайное число позиций (генерируется при обфускации кода). Это усложняет сопоставление порядка вынесенных строк с их исходным местом.
stringArrayShuffle
Type: boolean Default: true
⚠️ должна быть включена опция stringArray
Случайным образом перемешивает элементы массива stringArray.
stringArrayWrappersCount
Type: number Default: 1
⚠️ должна быть включена опция stringArray
Задаёт количество обёрток для string array внутри каждой корневой или функциональной области видимости.
Фактическое количество обёрток внутри каждой области видимости ограничено количеством узлов literal в этой области.
Пример:
// 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
⚠️ должны быть включены опции stringArray и stringArrayWrappersCount
Включает цепочки вызовов между обёртками string array.
Пример:
// 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
⚠️ должна быть включена опция stringArray
⚠️ В настоящее время эта опция влияет только на обёртки, добавляемые при значении function опции stringArrayWrappersType
Позволяет управлять максимальным количеством параметров обёрток массива строк.
Значение по умолчанию и минимальное значение — 2. Рекомендуемое значение — от 2 до 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ должны быть включены опции stringArray и stringArrayWrappersCount
Позволяет выбрать тип обёрток, добавляемых опцией stringArrayWrappersCount.
Доступные значения:
'variable': добавляет обёртки-переменные в начало каждой области видимости. Высокая производительность.'function': добавляет обёртки-функции в случайных местах внутри каждой области видимости. Производительность ниже, чем уvariable, но обфускация строже.
Настоятельно рекомендуется использовать обёртки function для более сильной обфускации, когда потеря производительности не оказывает существенного влияния на обфусцированное приложение.
Пример для значения опции '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
⚠️ должна быть включена опция stringArray
С помощью этой настройки можно отрегулировать вероятность (от 0 до 1) того, что строковый литерал будет помещён в stringArray.
Эта настройка особенно полезна для кода большого размера, так как обращения к string array происходят многократно и могут замедлить ваш код.
stringArrayThreshold: 0 эквивалентно stringArray: false.
strictMode
Type: boolean | null Default: null
Позволяет указать, как обфускатор должен обрабатывать код в отношении строгого режима JavaScript.
Доступные значения:
null(по умолчанию) — автоматически определять строгий режим по коду. Если в коде есть явная директива'use strict', синтаксис ES-модулей или методы классов, он считается кодом в строгом режиме. В противном случае предполагается нестрогий (sloppy) режим.true— принудительно обрабатывать весь код как код в строгом режиме, даже без явной директивы'use strict'. Используйте, когда ваш код будет выполняться в контексте строгого режима (например, в ES-модулях, сборщиках или современных фреймворках).false— только явные признаки строгого режима ('use strict', ES-модули, методы классов) считаются строгими. Наследование от родительской области видимости по-прежнему применяется согласно спецификации JS.
target
Type: string Default: browser
Позволяет задать целевую среду для обфусцированного кода.
Доступные значения:
browser(по умолчанию) — стандартная среда веб-страницы. Выходной код идентиченnode, но некоторые специфичные для браузера опции нельзя использовать с цельюnodebrowser-no-eval— то же, что иbrowser, но вывод не используетeval(). Используйте, когда на целевой странице есть Content Security Policy, запрещающаяeval/unsafe-eval.node— среда Node.js. Специфичные для браузера опции отключены (им нужныwindow/document, и в Node они были бы бездействием или бросали бы исключение). Некоторые защитыvmSelfDefending, полагающиеся на API только для браузера — обнаружение headless-браузера, восстановление через чистый realm на основе iframe, проверки на инспектор/DOM — для этой цели не генерируются.service-worker— контекст Service Worker. Нетwindow, нетdocument, другая глобальная переменнаяself.userscript— песочница менеджера пользовательских скриптов (например, Tampermonkey). ЗащитыvmSelfDefendingкорректируются соответствующим образом.bytenode— код Node.js, который после обфускации будет скомпилирован загрузчиком bytenode (кэшированный байт-код V8.jsc). Сам обфускатор не вызываетbytenode; он генерирует VM-обфусцированный JavaScript, среда выполнения которого устроена так, чтобы пережить шаг компиляции bytenode, а защитыvmSelfDefendingкорректируются соответствующим образом. Запуститеbytenodeна обфусцированном выводе самостоятельно, чтобы получить итоговый.jsc.
transformObjectKeys
Type: boolean Default: false
Включает преобразование ключей объектов.
Пример:
// 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
Управляет тем, какие некритичные предупреждения обфускации выдаются через метод ObfuscationResult.getWarnings().
Доступные значения:
'all'(по умолчанию) — выдаётся каждое предупреждение.'none'— все предупреждения подавляются.- объект, сопоставляющий типы предупреждений с булевыми значениями — тип, сопоставленный с
false, подавляется; каждый тип, который отсутствует (или сопоставлен сtrue), остаётся включённым. Например,{ "VMGlobalFunctionNamesNotRenamed": false }сохраняет все предупреждения, кроме этого.
Типы предупреждений:
VMGlobalFunctionNamesNotRenamed— приvmObfuscationимена объявлений функций верхнего уровня, объявлений классов и переменных, которым присвоено функциональное/стрелочное/классовое выражение, были сохранены как есть (опцияrenameGlobalsотключена, а код не обёрнут в IIFE), поэтому они остаются читаемыми в выводе, хотя тела скрыты в виде байт-кода. Экспортируемые имена не сообщаются.VMTopLevelInitializerNotVirtualized— инициализаторы переменных верхнего уровня остались в обычном JavaScript при VM-обфускации, посколькуvmWrapTopLevelInitializersотключена или не смогла их виртуализировать.DynamicCodeRenameRisk— код строит функцию из строки во время выполнения (прямойeval, конструкторFunctionилиfn.toString(), внедрённый в<script>/Worker), что может ссылаться на идентификаторы, которые обфускатор переименовал.VMDynamicCodeSkipped— функция была пропущена при преобразовании в VM-байт-код, поскольку содержит прямойeval/ динамическийnew Function/Function(см.vmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— при включённойvmAsyncExecutorфункция, которую вы явно пометили в режимеcomment, оказалась синхронной и была пропущена (в этом режиме виртуализируются только асинхронные функции).VMAsyncGeneratorSkippedInAsyncMode— при активныхvmAsyncExecutorи асинхронном геттере ключа помеченный асинхронный генератор не удалось виртуализировать (он должен возвращать свой итератор синхронно).BrowserTargetWithNodeStyleCode— код выглядит как нацеленный на Node.js (например,require('fs'),__dirname,process.argv), тогда как опцияtargetустановлена на среду, похожую на браузер.
vmObfuscation
Type: boolean Default: false
Включает VM-обфускацию на основе байт-кода. Когда опция включена, функции JavaScript компилируются в собственный байт-код, который выполняется на встроенной виртуальной машине. Это обеспечивает наивысший уровень защиты, поскольку исходная логика кода полностью преобразуется.
Пример:
Ваш читаемый код вроде return qty * price превращается в список чисел вида [0x15,0x03,0x17,...], который может выполнить только встроенный интерпретатор VM. Исходная логика больше не видна как JavaScript.
vmTargetFunctions
Type: string[] Default: []
Позволяет точно указать по имени, какие функции корневого уровня должны получить VM-защиту.
Пример:
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Результат: VM-защиту получают только эти три функции. Всё остальное остаётся обычным (но всё ещё обфусцированным) JavaScript. Идеально для защиты чувствительных проверок лицензии или логики аутентификации, оставляя остальной код лёгким.
vmExcludeFunctions
Type: string[] Default: []
Позволяет указать функции корневого уровня, которые никогда не должны получать VM-защиту. Имеет приоритет над другими настройками.
Пример:
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Когда использовать: критичные к производительности функции корневого уровня (циклы анимации, обработка данных в реальном времени) можно исключить, чтобы избежать накладных расходов VM, при этом защищая всё остальное.
vmTargetFunctionsMode
Type: string Default: root
Управляет тем, как функции/методы выбираются для VM-обфускации.
Пример — режим comment:
// 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'
}
Когда использовать: когда вам нужен хирургический контроль над тем, какие именно функции получают VM-защиту, особенно вложенные функции, содержащие чувствительную логику. В отличие от vmTargetFunctions, который работает только с именованными функциями корневого уровня, режим comment позволяет защитить любую функцию в любом месте вашего кода.
vmForceCompileDynamicCode
Type: boolean Default: false
Управляет тем, что VM-обфускация делает с функцией, содержащей прямой вызов eval, new Function(...) или Function(...).
По умолчанию такая функция (и каждая функция, определённая внутри неё) пропускается при преобразовании в VM-байт-код, а в result.getWarnings() сообщается предупреждение VMDynamicCodeSkipped. Это связано с тем, что построенный во время выполнения исходник может ссылаться на идентификаторы из окружающей цепочки областей видимости — идентификаторы, которые обфускатор переименовал.
При значении true функция всё равно преобразуется в байт-код, и предупреждение VMDynamicCodeSkipped больше не выдаётся.
Отдельное предупреждение DynamicCodeRenameRisk продолжает срабатывать независимо от этой опции, поскольку описываемый им риск переименования не зависит от пропуска VM — включение этой опции не делает исходный паттерн безопаснее.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
При выключенной опции (по умолчанию) loadConfig остаётся обычным JavaScript. При включённой опции loadConfig компилируется в VM-байт-код, как и любая другая функция. Используйте это, когда вы проверили место вызова и знаете, что построенный во время выполнения код не зависит от переименованных в замыкании идентификаторов.
vmWrapTopLevelInitializers
Type: boolean Default: false
Оборачивает некоторые инициализаторы переменных верхнего уровня в IIFE (немедленно вызываемые функциональные выражения), чтобы их можно было VM-обфусцировать.
Что она делает: Без этой опции константы и переменные верхнего уровня остаются видимыми в выводе:
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
При включённой опции инициализатор оборачивается в IIFE, которое VM-обфусцируется:
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Примечание: эта опция работает, только когда vmTargetFunctionsMode имеет значение 'root' (по умолчанию).
Предупреждения: всякий раз, когда инициализатор верхнего уровня остаётся в обычном JavaScript при VM-обфускации, выдаётся предупреждение VMTopLevelInitializerNotVirtualized со списком затронутых имён переменных. Это охватывает: отключение этой опции, инициализаторы, которые этой опции пришлось пропустить (каждый с причиной — например, инициализатор ссылается на соседний деклератор или содержит top-level await), и режим vmAsyncExecutor, где синхронные обёртки вообще не могут быть виртуализированы.
vmDynamicOpcodes
Type: boolean Default: false
Делает интерпретатор VM меньше и уникальным для каждой сборки.
Что она делает:
- Отфильтровывает неиспользуемые инструкции — если ваш код не использует классы, инструкции, связанные с классами, полностью удаляются
- Рандомизирует структуру — порядок обработчиков инструкций перемешивается при каждой сборке
В результате — меньший размер вывода, и каждая сборка выглядит по-разному.
vmBytecodeEncoding
Type: boolean Default: false
Кодирует каждую инструкцию байт-кода. Инструкции декодируются по одной во время выполнения.
vmBytecodeArrayEncoding
Type: boolean Default: false
Кодирует весь массив байт-кода как единый блок. Массив декодируется один раз при запуске, до начала выполнения. Используйте вместе с vmBytecodeEncoding для двух слоёв защиты.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Свой ключ шифрования для кодирования массива байт-кода. Когда он задан, этот ключ используется вместо ключа по умолчанию, выводимого из окружения. Ключ должен предоставляться во время выполнения через vmBytecodeArrayEncodingKeyGetter.
Эта опция выносит ключ шифрования наружу — он не встроен в сам обфусцированный код. Хотя ключ всё равно доступен во время выполнения (и потому не является по-настоящему секретным), такое разделение не позволяет инструментам статического анализа найти ключ, изучая только код.
Важно: ключ должен быть доступен синхронно в момент загрузки обфусцированного кода. Используйте синхронное хранилище, например cookie, localStorage, sessionStorage, глобальные переменные или DOM-элементы (например, внедрённые сервером мета-теги). Асинхронные методы вроде fetch() нельзя использовать напрямую в выражении геттера ключа.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Синхронное выражение JavaScript, которое возвращает ключ шифрования во время выполнения. Это выражение вычисляется при загрузке обфусцированного кода и должно вернуть тот же ключ, который был передан в vmBytecodeArrayEncodingKey. Чтобы получать ключ асинхронно (Promise), включите vmAsyncExecutor.
Примечание: геттер, возвращающий Promise, требует vmAsyncExecutor. Это нельзя проверить на этапе сборки, поэтому геттер, возвращающий Promise, при выключенной vmAsyncExecutor завершится ошибкой во время выполнения — декодер получит Promise вместо ключа.
Обфусцированный код будет работать только тогда, когда геттер ключа возвращает ровно тот же ключ, что использовался при обфускации. Если ключи не совпадают, расшифровка завершится неудачей, и код выдаст мусор или ошибки. Если геттер ключа возвращает undefined, null или пустую строку, код бросит ошибку: "VM decryption key not available".
Важно: держите ключ вне того же файла/скрипта, что и обфусцированный код — встраивание его туда позволяет восстановить его даже чисто статическим сканированием бандла. Храните его в отдельном источнике: заданные сервером cookie, localStorage, заполняемый другим скриптом, внедрённый сервером HTML-мета-тег, глобальная переменная, заданная другим скриптом, или (с vmAsyncExecutor) получаемый с вашего бэкенда во время выполнения.
Когда ключ получается с вашего бэкенда (через vmAsyncExecutor), добавьте на этот эндпоинт проверки на основе сессии или источника: возвращайте правильный ключ реальным пользователям (действительная сессия, ожидаемый Origin/Referer) и мусорный ключ подозрительным запросам (например, localhost/неожиданный источник, отсутствие сессии). Реальные пользователи работают нормально; копия, запущенная вне вашего окружения, получает ключ, расшифровка которым не даёт ничего. Точная логика зависит от вашего сайта.
Примеры:
// 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())'
Пример использования:
// 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
Включает асинхронный исполнитель VM, который позволяет vmBytecodeArrayEncodingKeyGetter возвращать Promise (асинхронный геттер ключа) — так что ключ расшифровки можно получать во время выполнения (сетевой запрос, IndexedDB и т. д.), а не иметь его синхронно доступным в момент загрузки кода.
Настоятельно рекомендуется для полностью асинхронных кодовых баз. В этом режиме виртуализируются только async-функции — синхронную функцию нельзя сделать асинхронной, не превратив её возвращаемое значение в Promise и не сломав вызывающий код, — поэтому код, асинхронный на всём протяжении, получает наибольший охват. Он всё равно работает, когда корень синхронный (например, синхронное IIFE / UMD-обёртка): защищаются самые внешние async-функции внутри, а синхронные части остаются как есть.
Что преобразуется: каждая самая внешняя async-функция, где бы она ни находилась (в том числе вложенная в синхронные обёртки). Самая внешняя async в каждой цепочке — это защищаемая единица; всё внутри неё, синхронное и асинхронное, компилируется целиком. Синхронные функции и обычные генераторы остаются необфусцированными.
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
}
}
Пропуски и предупреждения. Асинхронные генераторы также остаются необфусцированными, когда активен асинхронный геттер ключа (асинхронный генератор должен возвращать свой итератор синхронно и не может ждать ключ). В режиме по умолчанию vmTargetFunctionsMode: 'root' пропуски происходят молча (выбор автоматический); в режиме comment выдаётся предупреждение через ObfuscationResult.getWarnings() всякий раз, когда явно помеченную вами функцию не удаётся виртуализировать — она оказалась синхронной или это асинхронный генератор при асинхронном геттере ключа.
Асинхронный геттер ключа дополнительно требует vmBytecodeArrayEncoding с vmBytecodeArrayEncodingKeyGetter.
Пример использования:
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
Кодирует цели переходов в байт-коде. Смещения переходов вычисляются во время выполнения, скрывая структуру потока управления (if/else, циклы и т. д.) от статического анализа.
vmMacroOps
Type: boolean Default: false
Объединяет частые последовательности инструкций в единые «макро»-опкоды. Например, LOAD + ADD + STORE может стать одной инструкцией MACRO_ADD_TO_VAR. Это ломает распознавание паттернов и может повысить производительность.
vmDebugProtection
Type: boolean Default: false
Добавляет многоуровневые средства защиты от отладки, анализа и LLM в среду выполнения VM. Лучше всего работает с целями browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Добавляет многоуровневую защиту от вмешательства, от хуков и от реверс-инжиниринга в среду выполнения VM.
⚠️ Эта опция принудительно включает vmBytecodeArrayEncoding.
⚠️ Обнаружение чувствительной среды. Эта опция привязывает обфусцированный код к его целевой среде выполнения и использует продвинутый браузерный фингерпринтинг для обнаружения инструментов автоматизации. Код, защищённый этой опцией, намеренно сломается при запуске в:
- Headless-браузерах (headless Chrome/Chromium, PhantomJS)
- Инструментах автоматизации браузера (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (когда
targetустановлен наbrowser) - jsdom или подобных серверных эмуляциях DOM
- Средах, где встроенные объекты браузера были перехвачены или подменены
Код будет работать корректно в обычных браузерах (Chrome, Firefox, Safari, Edge), в том числе при загрузке внутри iframe, в расширениях браузера (content scripts) и в Web Workers. Если вам нужно запускать автоматические тесты против защищённого кода, отключите vmSelfDefending для тестовых сборок — эта опция предназначена для предотвращения автоматического анализа и не может безопасно использоваться ни с одним фреймворком автоматизации.
Настоятельно рекомендуется использовать вместе с vmDebugProtection, vmBytecodeArrayEncodingKey и vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook принимает объект с двумя ключами: name (обязательный) и aliases (необязательный).
name — это глобальная функция, которую определяет ваша страница-хост и которую защита VM (vmDebugProtection / vmSelfDefending) вызывает с объектом-сигналом, когда обнаруживает враждебный сигнал — отладчик или инспектор, headless-/автоматизированный браузер, процесс ИИ-агента для написания кода, недопустимый домен и так далее. Используйте её, чтобы сообщать о событии на свой бэкенд (например, через navigator.sendBeacon). Хук — это чистый приёмник телеметрии: его возвращаемое значение игнорируется, а отсутствующий или бросающий исключение хук — это тихая пустая операция, которая никогда не может отключить защиту. Чтобы изменить то, что защита делает при обнаружении, используйте vmDefenseReaction.
aliases необязательно переименовывает поля этого объекта-сигнала — это описано ниже в разделе Переименование полей сигнала.
Объект-сигнал. Хук получает единственный signal:
source— конкретный детектор, который сработал (см. таблицу).category— группа, под которой он сообщает:automation(нечеловеческие браузеры),debugger(активен отладчик/инспектор),sandbox(инструментированный/поддельный хост),domain(нарушение привязки к домену),tamper(встроенные объекты пропатчены во время выполнения) илиintegrity(изменён собственный код VM).score/threshold— насколько сильно сработал детектор и значение, которого он должен был достичь; хук срабатывает только приscore >= threshold. Большинство проверок работают по принципу «всё или ничего» (один решающий сигнал);headlessсуммирует несколько сигналов о форме браузера, поэтому егоscoreобычно выше, чемthreshold.
Регистрация хука. Определите его как обычную глобальную функцию до загрузки обфусцированного бандла — среда выполнения VM и её защиты работают до вашей (защищённой) программы, поэтому многие обнаружения происходят во время старта:
// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }
Хук, определённый внутри обфусцированного исходника, регистрируется слишком поздно, чтобы ловить обнаружения на старте, и если он попадёт под VM-компиляцию, до него не добраться, пока не запустится ваша программа. Он безопасен в любом случае (отсутствующий хук — пустая операция, а защита от повторного входа предотвращает разгон), но для полного охвата регистрируйте его заранее. Чтобы всё же защитить логику отправки, оставьте зарегистрированный хук однострочным буфером ((window.__vmDet = window.__vmDet || []).push(signal)) и читайте/отправляйте этот буфер из своего обфусцированного кода.
Переименование полей сигнала (aliases). Значения source/category по умолчанию — описательные имена, поэтому любой, кто инструментирует коллбэк (или читает вывод), может распознать защиту и то, какой детектор сработал. aliases переименовывает поля сигнала в непрозрачные токены на ваш выбор, применяемые внутри VM до того, как сигнал будет выпущен, так что эти имена никогда не появляются в выводе и не попадают в коллбэк. Ваше приложение знает собственное сопоставление и пересылает токены на бэкенд.
Псевдонимы задаются на каждое поле, разделяя переименование ключей и значений: каждое поле принимает key (имя свойства, которое получает коллбэк); строковые поля-имена source и category также принимают карту values, тогда как score/threshold — числа и принимают только key. Имена, которые можно сопоставить (всё остальное отклоняется на этапе сборки):
- ключи полей —
source,category,score,threshold - значения
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - значения
category—automation,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> }
}
Это уход от отпечатка, а не секретность — сопоставление всё равно можно вывести повторным тестированием, — так что единственная его польза в том, чтобы не раскрывать стабильные, самоочевидные имена. Незаданные записи сохраняют имена по умолчанию.
Голая строка (vmDefenseHook: '__vmDetection') принимается как сокращение для { name: '__vmDetection' }, но устарела — предпочитайте форму-объект.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Настраивает, как реагирует каждая категория срабатываний. Она ничего не включает — сами защиты включаются через vmSelfDefending, vmDebugProtection и vmDomainLock; эта опция лишь выбирает, как реагирует включённая защита. Категория — единица управления: каждый детектор в категории применяет реакцию этой категории.
Каждая категория группирует детекторы, следящие за одним видом враждебного условия. Категория реагирует только тогда, когда включена опция, выпускающая её детекторы:
Каждая категория соответствует одной или нескольким из vmSelfDefending, vmDebugProtection и vmDomainLock; вне этих трёх опций категорий нет, а реакция, заданная для категории с выключенной опцией, просто не имеет эффекта.
Ключи — это шесть названий категорий или default (запасной вариант для неуказанных категорий). Значения:
break— сломаться немедленноdecoy— продолжать работать на отравленном состоянии, незаметно выдавая неверные результатыnone— ничего не делать локально (только телеметрия)
Значения по умолчанию для каждой категории показаны выше; категория, которую вы не задали (или задали её значением по умолчанию), использует это значение по умолчанию. default охватывает каждую категорию, включая корректные по построению (integrity, tamper), поэтому { default: 'none' } — это по-настоящему неразрушающая сборка, отправляющая только телеметрию:
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
Делает значения опкодов зависящими от позиции в байт-коде. Каждая позиция имеет своё сопоставление опкода с обработчиком, выведенное из зерна, поэтому один и тот же номер опкода выполняет разные операции на разных позициях.
vmCallContextOpcodes
Type: boolean Default: false
Делает защищённую функцию зависящей от того, откуда она вызвана, так что её нельзя вынести из кода и запустить или проанализировать саму по себе — она ведёт себя корректно только при вызове через реальные места вызова в программе. Эта опция влияет на производительность во время выполнения.
В настоящее время поддерживаются только следующие конструкции:
- объявления функций (
function f() {}); - функциональные и стрелочные выражения, присвоенные переменной (
const f = () => {}); - приватные методы экземпляра (
this.#m()).
Во всех случаях функция всегда должна достигаться через прямой вызов (f(), this.#m()). Если она сохраняется в другую переменную, передаётся как аргумент или иным образом используется как значение, она остаётся незащищённой. Асинхронные функции поддерживаются; генераторы — нет.
Эта опция экспериментальна и может сломать ваш код, поэтому тщательно тестируйте вывод перед её использованием.
vmStackEncoding
Type: boolean Default: false
Шифрует значения на стеке VM во время выполнения. Значения кодируются при помещении в стек и декодируются при извлечении, поэтому при инспекции памяти видны зашифрованные данные вместо реальных значений.
Эта опция сильно влияет на производительность.
vmCompactDispatcher
Type: boolean Default: false
Использует один исполнитель VM вместо двух (синхронный + генераторный). Уменьшает размер обфусцированного кода, но добавляет около 20% накладных расходов на производительность для кода с большим количеством рекурсии.
false(по умолчанию): два исполнителя — оптимальная производительность, больший размер выводаtrue: один исполнитель — меньший размер вывода, немного медленнее
vmStringArrayBytecodeOnly
Type: boolean Default: false
Когда опция включена, массив строк будет извлекать строки только из данных байт-кода — никакие другие строки в коде не преобразуются. Это принудительно включает stringArray, даже если он не задан явно.
Зачем это использовать: извлечение всех строк среды выполнения VM в массив строк — медленно. Эта опция нацеливает извлечение в массив строк только на содержимое байт-кода, повышая производительность и при этом защищая константы байт-кода.
- Когда
vmBytecodeArrayEncoding: false— извлекаются строки внутри пулов констант байт-кода (массивыc) - Когда
vmBytecodeArrayEncoding: true— извлекаются строки байт-кода верхнего уровня, закодированные в base64 stringArrayThresholdпо-прежнему управляет тем, какой процент этих строк байт-кода извлекается
vmDomainLock
Type: string[] Default: []
⚠️ Эта опция не работает с target: 'node', target: 'service-worker' или target: 'bytenode'
Ограничивает обфусцированный код определёнными доменами и/или поддоменами, и её гораздо сложнее найти и вырезать, чем domainLock.
Если исходный код запущен не на доменах, указанных в этой опции, браузер будет перенаправлен на URL, переданный в vmDomainLockRedirectUrl, а дальнейшие защищённые вызовы будут возвращать неверные результаты, даже если перенаправление подавлено.
Несколько доменов и поддоменов
Код можно привязать более чем к одному домену или поддомену. Например, чтобы код работал только на www.example.com, добавьте www.example.com. Чтобы он работал на корневом домене, включая любые поддомены (example.com, sub.example.com), используйте .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Эта опция не работает с target: 'node', target: 'service-worker' или target: 'bytenode'
Позволяет перенаправить браузер на переданный URL, если исходный код запущен не на доменах, указанных в vmDomainLock.
Preset Options
Высокая обфускация, низкая производительность
Производительность будет значительно ниже, чем без обфускации
{
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
}
Средняя обфускация, оптимальная производительность
Производительность будет ниже, чем без обфускации
{
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
}
Низкая обфускация, высокая производительность
Производительность будет на относительно нормальном уровне
{
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
}
Пресет по умолчанию, высокая производительность
{
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 obfuscation (максимальная безопасность)
Этот пресет включает VM-обфускацию на основе байт-кода со всеми функциями усиления защиты, включая непрямую диспетчеризацию. Обеспечивает самую сильную защиту, но с большим размером вывода и значительно более медленным выполнением.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Или настройте по отдельности:
{
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 (защита от ИИ-агентов)
Этот пресет специально разработан, чтобы не дать ИИ-агентам и LLM реверс-инжинирить код в VM-байт-коде. Основан на vm-default с включёнными самозащитой и защитой от отладки. Легче, чем vm-high-obfuscation, но специально усилен против автоматического анализа.
{
optionsPreset: 'vm-anti-llm'
}
Включает:
- VM-обфускацию байт-кода с массивом строк (из
vm-default) vmSelfDefending— обнаружение хуков, хеш целостности, отпечаток исходника, проверку чистого realm через iframe, вывод ключа шифра ARXvmDebugProtection— проверки против отладки в цикле диспетчеризации VMdebugProtection: false— без устаревшей защиты от отладки (VM-защита от отладки лучше)
VM High obfuscation (наивысшая безопасность)
Этот пресет включает VM-обфускацию на основе байт-кода с большинством функций усиления защиты. Обеспечивает сильную защиту с лучшей производительностью, чем пресет ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Или настройте по отдельности:
{
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 obfuscation (сбалансированная безопасность)
Этот пресет включает VM-обфускацию на основе байт-кода со сбалансированным набором функций усиления защиты. Хороший компромисс между безопасностью и производительностью.
{
optionsPreset: 'vm-medium-obfuscation'
}
Или настройте по отдельности:
{
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 obfuscation (базовая безопасность, лучшая производительность)
Этот пресет включает базовую VM-обфускацию на основе байт-кода без дополнительных функций усиления защиты. Хороший баланс между безопасностью и размером вывода.
{
optionsPreset: 'vm-low-obfuscation'
}
Или настройте по отдельности:
{
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 + защита массивом строк)
Этот пресет сочетает базовую VM-обфускацию на основе байт-кода с защитой массивом строк. Хорошая отправная точка для VM-обфускации со строковой защитой.
{
optionsPreset: 'vm-default'
}
Или настройте по отдельности:
{
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
Компактный вывод кода в одну строку.
config
Type: string Default: ``
Имя JS/JSON-файла конфигурации, содержащего опции обфускатора. Эти опции будут переопределены опциями, переданными напрямую в CLI
controlFlowFlattening
Type: boolean Default: false
⚠️ Эта опция сильно влияет на производительность — скорость выполнения падает вплоть до 1,5 раз. Используйте controlFlowFlatteningThreshold, чтобы задать процент узлов, к которым будет применено уплощение потока управления.
Включает уплощение потока управления кода. Уплощение потока управления — это структурное преобразование исходного кода, затрудняющее понимание программы.
Пример:
// 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
Вероятность того, что преобразование controlFlowFlattening будет применено к тому или иному узлу.
Эта настройка особенно полезна для кода большого размера, поскольку большое количество преобразований потока управления может замедлить ваш код и увеличить его размер.
controlFlowFlatteningThreshold: 0 эквивалентно controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Резко увеличивает размер обфусцированного кода (до 200%), используйте только если размер обфусцированного кода не имеет значения. Используйте deadCodeInjectionThreshold, чтобы задать процент узлов, к которым будет применено внедрение мёртвого кода.
⚠️ Эта опция принудительно включает опцию stringArray.
⚠️ Эта опция незаметно отключается, когда включена vmObfuscation.
С этой опцией в обфусцированный код будут добавлены случайные блоки мёртвого кода.
Пример:
// 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
Позволяет задать процент узлов, к которым будет применён deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Может подвесить ваш браузер, если вы откроете инструменты разработчика.
⚠️ Эта опция незаметно отключается, когда включена vmObfuscation. Используйте вместо неё vmDebugProtection.
Эта опция делает практически невозможным использование функции debugger в инструментах разработчика (как в браузерах на основе WebKit, так и в Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Может подвесить ваш браузер! Используйте на свой страх и риск.
⚠️ Эта опция незаметно отключается, когда включена vmObfuscation. Используйте вместо неё vmDebugProtection.
Если значение задано, интервал в миллисекундах используется для принудительного входа в режим отладки на вкладке Console, что затрудняет использование других возможностей инструментов разработчика. Работает, если включена опция debugProtection. Рекомендуемое значение — от 2000 до 4000 миллисекунд.
disableConsoleOutput
Type: boolean Default: false
⚠️ Эта опция отключает вызовы console глобально для всех скриптов
Отключает использование console.log, console.info, console.error, console.warn, console.debug, console.exception и console.trace, заменяя их пустыми функциями. Это усложняет работу с отладчиком.
domainLock
Type: string[] Default: []
⚠️ Эта опция не работает с target: 'node', target: 'service-worker' или target: 'bytenode'
Позволяет запускать обфусцированный исходный код только на определённых доменах и/или поддоменах. Из-за этого становится по-настоящему сложно просто скопировать ваш исходный код и запустить его в другом месте.
Если исходный код запущен не на доменах, указанных в этой опции, браузер будет перенаправлен на URL, переданный в опции domainLockRedirectUrl.
Несколько доменов и поддоменов
Код можно привязать более чем к одному домену или поддомену. Например, чтобы код работал только на www.example.com, добавьте www.example.com. Чтобы он работал на корневом домене, включая любые поддомены (example.com, sub.example.com), используйте .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Эта опция не работает с target: 'node', target: 'service-worker' или target: 'bytenode'
Позволяет перенаправить браузер на переданный URL, если исходный код запущен не на доменах, указанных в domainLock
exclude
Type: string[] Default: []
Имена файлов или glob-шаблоны, указывающие, какие файлы нужно исключить из обфускации.
forceTransformStrings
Type: string[] Default: []
Включает принудительное преобразование строковых литералов, которые соответствуют переданным шаблонам RegExp.
⚠️ Эта опция влияет только на строки, которые не должны преобразовываться из-за stringArrayThreshold (или, возможно, других порогов в будущем)
Эта опция имеет приоритет над опцией reservedStrings, но не имеет приоритета над условными комментариями.
Пример:
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
Главная цель этой опции — возможность использовать одни и те же имена идентификаторов при обфускации нескольких исходников/файлов.
В настоящее время поддерживаются два типа идентификаторов:
- Глобальные идентификаторы:
- Все глобальные идентификаторы будут записаны в кэш;
- Все совпавшие необъявленные глобальные идентификаторы будут заменены значениями из кэша.
- Идентификаторы свойств, только когда включена опция
renameProperties:- Все идентификаторы свойств будут записаны в кэш;
- Все совпавшие идентификаторы свойств будут заменены значениями из кэша.
Node.js API
Если передано значение null, кэш полностью отключается.
Если передан пустой объект ({}), включается запись имён идентификаторов в кэш-объект (тип TIdentifierNamesCache). Доступ к этому кэш-объекту можно получить через вызов метода getIdentifierNamesCache объекта ObfuscationResult.
Полученный кэш-объект затем можно использовать как значение опции identifierNamesGenerator, чтобы применять эти имена при обфускации всех совпавших имён идентификаторов в следующих исходниках.
Пример:
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
В CLI есть отдельная опция --identifier-names-cache-path, которая позволяет задать путь к существующему .json-файлу, используемому для чтения и записи кэша имён идентификаторов.
Если передать путь к пустому файлу — кэш имён идентификаторов будет записан в этот файл.
Этот файл с уже имеющимся кэшем можно снова использовать как значение опции --identifier-names-cache-path, чтобы применять эти имена при обфускации всех совпавших имён идентификаторов в следующих файлах.
identifierNamesGenerator
Type: string Default: hexadecimal
Задаёт генератор имён идентификаторов.
Доступные значения:
dictionary: имена идентификаторов из спискаidentifiersDictionaryhexadecimal: имена идентификаторов вида_0xabc123mangled: короткие имена идентификаторов, напримерa,b,cmangled-shuffled: то же, что иmangled, но с перемешанным алфавитом
identifiersDictionary
Type: string[] Default: []
Задаёт словарь идентификаторов для identifierNamesGenerator со значением dictionary. Каждый идентификатор из словаря будет использован в нескольких вариантах с разным регистром каждого символа. Поэтому количество идентификаторов в словаре должно зависеть от количества идентификаторов в исходном коде.
identifiersPrefix
Type: string Default: ''
Задаёт префикс для всех глобальных идентификаторов.
Используйте эту опцию, когда нужно обфусцировать несколько файлов. Она помогает избежать конфликтов между глобальными идентификаторами этих файлов. Префикс должен быть разным для каждого файла.
randomIdentifiersPrefix
Type: boolean Default: false
Добавляет случайный префикс на основе зерна (6 буквенно-цифровых символов) ко всем глобальным идентификаторам. Используйте эту опцию, чтобы избежать коллизий между обфусцированными по отдельности бандлами, которые загружаются в одну и ту же глобальную область видимости, — она избавляет от необходимости вручную выбирать уникальный identifiersPrefix для каждого бандла.
- Случайное значение выводится из опции
seedи хеша исходного кода, поэтому воспроизводимые сборки с одним и тем же зерном дают один и тот же префикс. - В сочетании с
identifiersPrefixслучайные символы добавляются к заданному пользователем префиксу (например,myApp+ случайноеaBc123→myAppaBc123). - В сочетании с
vmObfuscationслучайное значение заменяет префиксvmпо умолчанию — случайность уже гарантирует уникальность.
ignoreImports
Type: boolean Default: false
Предотвращает обфускацию импортов require. Может быть полезно в тех случаях, когда среда выполнения по какой-то причине требует, чтобы такие импорты содержали только статические строки.
inputFileName
Type: string Default: ''
Позволяет задать имя входного файла с исходным кодом. Это имя будет использоваться внутри для генерации source map.
Обязательна при использовании NodeJS API, когда опция sourceMapSourcesMode имеет значение sources.
log
Type: boolean Default: false
Включает вывод информации в консоль.
numbersToExpressions
Type: boolean Default: false
Включает преобразование чисел в выражения
Пример:
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Позволяет задать пресет опций.
Доступные значения:
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.
Все дополнительные опции будут объединены с выбранным пресетом опций.
parseHtml
Type: boolean Default: false
Включает обфускацию JavaScript внутри HTML-тегов <script>.
Когда опция включена, обфускатор будет:
- Автоматически определять, является ли входные данные HTML (по наличию тегов
<!DOCTYPE,<html>,<head>,<body>или<script>) - Извлекать JavaScript из тегов
<script>, помеченных атрибутомdata-javascript-obfuscator - Обфусцировать каждый помеченный скрипт по отдельности, сохраняя структуру HTML
- Вставлять обфусцированный код обратно на исходные позиции
Важно: обфусцируются только скрипты с атрибутом data-javascript-obfuscator. Каждый помеченный скрипт обфусцируется по отдельности и независимо. Это означает:
- Код внутри помеченных тегов script должен быть изолированным — он НЕ должен ссылаться на переменные, функции или классы, определённые в других помеченных тегах script
- Непомеченные скрипты по-прежнему могут обращаться к глобальным переменным, определённым помеченными скриптами (через объявления
varили явные присваиванияglobalThis) - Это даёт вам явный контроль над тем, какие скрипты защищать
Обфусцируются (должны иметь атрибут data-javascript-obfuscator):
<script data-javascript-obfuscator>— обычные скрипты<script type="text/javascript" data-javascript-obfuscator>— скрипты с явно указанным типом- Скрипты с любыми дополнительными атрибутами (
id,class, другиеdata-*и т. д.)
Пропускаются (остаются без изменений):
- Скрипты без атрибута
data-javascript-obfuscator <script type="module">— ES-модули (даже с атрибутом)<script src="...">— внешние скрипты (даже с атрибутом)- Пустые теги script
Примечание: при включённой parseHtml source map не генерируются, так как они не соотносились бы корректно с выводом HTML.
Пример:
// 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
⚠️ эта опция может сломать ваш код. Включайте её, только если понимаете, что она делает!
Включает обфускацию имён глобальных переменных и функций с объявлением.
Когда эта опция отключена, а входной код объявляет функции или классы в глобальной области видимости (то есть код не обёрнут в IIFE), их имена сохраняются как есть в обфусцированном выводе — другие скрипты могут ссылаться на них по имени. При vmObfuscation выдаётся предупреждение VMGlobalFunctionNamesNotRenamed со списком этих имён, поскольку тело функции скрыто в виде байт-кода, но читаемое имя верхнего уровня всё равно раскрывает, что делает код (например, для LLM). Чтобы избежать этого раскрытия, оберните код в IIFE или включите эту опцию.
renameProperties
Type: boolean Default: false
⚠️ эта опция МОЖЕТ сломать ваш код. Включайте её, только если понимаете, что она делает!
Включает переименование имён свойств. Все встроенные свойства DOM и свойства базовых классов JavaScript будут проигнорированы.
Для переключения между режимами safe и unsafe этой опции используйте опцию renamePropertiesMode.
Чтобы задать формат переименованных имён свойств, используйте опцию identifierNamesGenerator.
Чтобы управлять тем, какие свойства будут переименованы, используйте опцию reservedNames.
Пример:
// 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
⚠️ Даже в режиме safe опция renameProperties МОЖЕТ сломать ваш код.
Задаёт режим опции renameProperties:
safe— поведение по умолчанию после релиза2.11.0. Пытается переименовывать свойства более безопасным образом, чтобы предотвратить ошибки во время выполнения. В этом режиме часть свойств будет исключена из переименования.unsafe— поведение по умолчанию до релиза2.11.0. Переименовывает свойства небезопасным образом, без каких-либо ограничений.
Если один файл использует свойства из другого файла, используйте опцию identifierNamesCache, чтобы сохранить одинаковые имена свойств в этих файлах.
reservedNames
Type: string[] Default: []
Отключает обфускацию и генерацию идентификаторов, которые соответствуют переданным шаблонам RegExp.
Пример:
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Отключает преобразование строковых литералов, которые соответствуют переданным шаблонам RegExp. Совпавшие строки останутся видимыми в обфусцированном выводе.
При VM-обфускации зарезервированные строки хранятся в отдельном незашифрованном массиве, чтобы оставаться видимыми. Это полезно для строк, которые должны оставаться читаемыми, например для API-эндпоинтов мониторинга или идентификаторов библиотек.
Пример:
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Эта опция задаёт зерно (seed) для генератора случайных чисел. Это полезно для получения воспроизводимых результатов.
Если seed равен 0 — генератор случайных чисел будет работать без зерна.
selfDefending
Type: boolean Default: false
⚠️ Не изменяйте обфусцированный код никаким образом после обфускации с этой опцией, поскольку любое изменение, например минификация кода, может сработать как триггер самозащиты, и код перестанет работать!
⚠️ Эта опция принудительно устанавливает значение compact в true
⚠️ Эта опция незаметно отключается, когда включена vmObfuscation. Используйте вместо неё vmSelfDefending.
Эта опция делает выходной код устойчивым к форматированию и переименованию переменных. Если кто-то попытается применить к обфусцированному коду JavaScript-beautifier, код перестанет работать, что усложнит его понимание и изменение.
simplify
Type: boolean Default: true
Включает дополнительную обфускацию кода за счёт упрощения.
⚠️ в будущих релизах обфускация литералов boolean (true => !![]) будет перенесена под эту опцию.
Пример:
// 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
Включает генерацию source map для обфусцированного кода.
Source map могут помочь вам отлаживать обфусцированный исходный код JavaScript. Если вы хотите или вам необходимо отлаживать код в продакшене, вы можете загрузить отдельный файл source map в секретное место и указать на него браузеру.
sourceMapBaseUrl
Type: string Default: ``
Задаёт базовый URL для URL импорта source map при sourceMapMode: 'separate'.
Пример для CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Результат:
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Задаёт имя файла для выходного source map при sourceMapMode: 'separate'.
Пример для CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Результат:
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Задаёт режим генерации source map:
inline— добавляет source map в конец каждого .js-файла;separate— генерирует соответствующий файл '.map' с source map. Если вы запускаете обфускатор через CLI — добавляет в конец файла с обфусцированным кодом ссылку на файл source map//# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Позволяет управлять полями sources и sourcesContent в source map:
sources-content— добавляет фиктивное полеsourcesи полеsourcesContentс исходным кодом;sources— добавляет полеsourcesс корректным описанием источника и не добавляет полеsourcesContent. При использовании NodeJS API необходимо задать опциюinputFileName, значение которой будет использовано как значение поляsources.
splitStrings
Type: boolean Default: false
Разбивает строковые литералы на части длиной, равной значению опции splitStringsChunkLength.
Пример:
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Задаёт длину части для опции splitStrings.
stringArray
Type: boolean Default: true
Убирает строковые литералы и помещает их в специальный массив. Например, строка "Hello World" в var m = "Hello World"; будет заменена на что-то вроде var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ должна быть включена опция stringArray
Включает преобразование вызовов к stringArray. Все аргументы этих вызовов могут быть вынесены в отдельный объект в зависимости от значения stringArrayCallsTransformThreshold.
Благодаря этому автоматически найти вызовы массива строк становится ещё сложнее.
Пример:
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
⚠️ должны быть включены опции stringArray и stringArrayCallsTransformThreshold
С помощью этой настройки можно отрегулировать вероятность (от 0 до 1) того, что вызовы массива строк будут преобразованы.
stringArrayEncoding
Type: string[] Default: []
⚠️ должна быть включена опция stringArray
Эта опция может замедлить ваш скрипт.
Кодирует все строковые литералы stringArray с помощью base64 или rc4 и вставляет специальный код, который декодирует их обратно во время выполнения.
Каждое значение stringArray будет закодировано случайно выбранной кодировкой из переданного списка. Это позволяет использовать несколько кодировок сразу.
Доступные значения:
'none'(boolean): не кодирует значениеstringArray'base64'(string): кодирует значениеstringArrayс помощьюbase64'rc4'(string): кодирует значениеstringArrayс помощьюrc4. Примерно на 30–50% медленнее, чемbase64, но получить исходные значения сложнее.
Например, при следующих значениях опций часть значений stringArray не будет закодирована, а часть будет закодирована кодировками base64 и rc4:
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ должна быть включена опция stringArray
Позволяет управлять типом индексов в вызовах массива строк.
Каждый индекс вызова stringArray будет преобразован случайно выбранным типом из переданного списка. Это позволяет использовать несколько типов сразу.
Доступные значения:
'hexadecimal-number'(default): преобразует индексы вызовов массива строк в шестнадцатеричные числа'hexadecimal-numeric-string': преобразует индексы вызовов массива строк в шестнадцатеричные числовые строки
До релиза 2.9.0 javascript-obfuscator преобразовывал все индексы вызовов массива строк с типом hexadecimal-numeric-string. Это немного усложняет ручную деобфускацию, но позволяет автоматическим деобфускаторам легко обнаруживать такие вызовы.
Новый тип hexadecimal-number призван усложнить автоматическое обнаружение шаблонов вызовов массива строк в коде.
В будущем будут добавлены и другие типы.
stringArrayIndexShift
Type: boolean Default: true
⚠️ должна быть включена опция stringArray
Включает дополнительный сдвиг индекса для всех вызовов массива строк
stringArrayRotate
Type: boolean Default: true
⚠️ должна быть включена опция stringArray
Сдвигает массив stringArray на фиксированное случайное число позиций (генерируется при обфускации кода). Это усложняет сопоставление порядка вынесенных строк с их исходным местом.
stringArrayShuffle
Type: boolean Default: true
⚠️ должна быть включена опция stringArray
Случайным образом перемешивает элементы массива stringArray.
stringArrayWrappersCount
Type: number Default: 1
⚠️ должна быть включена опция stringArray
Задаёт количество обёрток для string array внутри каждой корневой или функциональной области видимости.
Фактическое количество обёрток внутри каждой области видимости ограничено количеством узлов literal в этой области.
Пример:
// 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
⚠️ должны быть включены опции stringArray и stringArrayWrappersCount
Включает цепочки вызовов между обёртками string array.
Пример:
// 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
⚠️ должна быть включена опция stringArray
⚠️ В настоящее время эта опция влияет только на обёртки, добавляемые при значении function опции stringArrayWrappersType
Позволяет управлять максимальным количеством параметров обёрток массива строк.
Значение по умолчанию и минимальное значение — 2. Рекомендуемое значение — от 2 до 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ должны быть включены опции stringArray и stringArrayWrappersCount
Позволяет выбрать тип обёрток, добавляемых опцией stringArrayWrappersCount.
Доступные значения:
'variable': добавляет обёртки-переменные в начало каждой области видимости. Высокая производительность.'function': добавляет обёртки-функции в случайных местах внутри каждой области видимости. Производительность ниже, чем уvariable, но обфускация строже.
Настоятельно рекомендуется использовать обёртки function для более сильной обфускации, когда потеря производительности не оказывает существенного влияния на обфусцированное приложение.
Пример для значения опции '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
⚠️ должна быть включена опция stringArray
С помощью этой настройки можно отрегулировать вероятность (от 0 до 1) того, что строковый литерал будет помещён в stringArray.
Эта настройка особенно полезна для кода большого размера, так как обращения к string array происходят многократно и могут замедлить ваш код.
stringArrayThreshold: 0 эквивалентно stringArray: false.
strictMode
Type: boolean | null Default: null
Позволяет указать, как обфускатор должен обрабатывать код в отношении строгого режима JavaScript.
Доступные значения:
null(по умолчанию) — автоматически определять строгий режим по коду. Если в коде есть явная директива'use strict', синтаксис ES-модулей или методы классов, он считается кодом в строгом режиме. В противном случае предполагается нестрогий (sloppy) режим.true— принудительно обрабатывать весь код как код в строгом режиме, даже без явной директивы'use strict'. Используйте, когда ваш код будет выполняться в контексте строгого режима (например, в ES-модулях, сборщиках или современных фреймворках).false— только явные признаки строгого режима ('use strict', ES-модули, методы классов) считаются строгими. Наследование от родительской области видимости по-прежнему применяется согласно спецификации JS.
target
Type: string Default: browser
Позволяет задать целевую среду для обфусцированного кода.
Доступные значения:
browser(по умолчанию) — стандартная среда веб-страницы. Выходной код идентиченnode, но некоторые специфичные для браузера опции нельзя использовать с цельюnodebrowser-no-eval— то же, что иbrowser, но вывод не используетeval(). Используйте, когда на целевой странице есть Content Security Policy, запрещающаяeval/unsafe-eval.node— среда Node.js. Специфичные для браузера опции отключены (им нужныwindow/document, и в Node они были бы бездействием или бросали бы исключение). Некоторые защитыvmSelfDefending, полагающиеся на API только для браузера — обнаружение headless-браузера, восстановление через чистый realm на основе iframe, проверки на инспектор/DOM — для этой цели не генерируются.service-worker— контекст Service Worker. Нетwindow, нетdocument, другая глобальная переменнаяself.userscript— песочница менеджера пользовательских скриптов (например, Tampermonkey). ЗащитыvmSelfDefendingкорректируются соответствующим образом.bytenode— код Node.js, который после обфускации будет скомпилирован загрузчиком bytenode (кэшированный байт-код V8.jsc). Сам обфускатор не вызываетbytenode; он генерирует VM-обфусцированный JavaScript, среда выполнения которого устроена так, чтобы пережить шаг компиляции bytenode, а защитыvmSelfDefendingкорректируются соответствующим образом. Запуститеbytenodeна обфусцированном выводе самостоятельно, чтобы получить итоговый.jsc.
transformObjectKeys
Type: boolean Default: false
Включает преобразование ключей объектов.
Пример:
// 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
Управляет тем, какие некритичные предупреждения обфускации выдаются через метод ObfuscationResult.getWarnings().
Доступные значения:
'all'(по умолчанию) — выдаётся каждое предупреждение.'none'— все предупреждения подавляются.- объект, сопоставляющий типы предупреждений с булевыми значениями — тип, сопоставленный с
false, подавляется; каждый тип, который отсутствует (или сопоставлен сtrue), остаётся включённым. Например,{ "VMGlobalFunctionNamesNotRenamed": false }сохраняет все предупреждения, кроме этого.
Типы предупреждений:
VMGlobalFunctionNamesNotRenamed— приvmObfuscationимена объявлений функций верхнего уровня, объявлений классов и переменных, которым присвоено функциональное/стрелочное/классовое выражение, были сохранены как есть (опцияrenameGlobalsотключена, а код не обёрнут в IIFE), поэтому они остаются читаемыми в выводе, хотя тела скрыты в виде байт-кода. Экспортируемые имена не сообщаются.VMTopLevelInitializerNotVirtualized— инициализаторы переменных верхнего уровня остались в обычном JavaScript при VM-обфускации, посколькуvmWrapTopLevelInitializersотключена или не смогла их виртуализировать.DynamicCodeRenameRisk— код строит функцию из строки во время выполнения (прямойeval, конструкторFunctionилиfn.toString(), внедрённый в<script>/Worker), что может ссылаться на идентификаторы, которые обфускатор переименовал.VMDynamicCodeSkipped— функция была пропущена при преобразовании в VM-байт-код, поскольку содержит прямойeval/ динамическийnew Function/Function(см.vmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— при включённойvmAsyncExecutorфункция, которую вы явно пометили в режимеcomment, оказалась синхронной и была пропущена (в этом режиме виртуализируются только асинхронные функции).VMAsyncGeneratorSkippedInAsyncMode— при активныхvmAsyncExecutorи асинхронном геттере ключа помеченный асинхронный генератор не удалось виртуализировать (он должен возвращать свой итератор синхронно).BrowserTargetWithNodeStyleCode— код выглядит как нацеленный на Node.js (например,require('fs'),__dirname,process.argv), тогда как опцияtargetустановлена на среду, похожую на браузер.
vmObfuscation
Type: boolean Default: false
Включает VM-обфускацию на основе байт-кода. Когда опция включена, функции JavaScript компилируются в собственный байт-код, который выполняется на встроенной виртуальной машине. Это обеспечивает наивысший уровень защиты, поскольку исходная логика кода полностью преобразуется.
Пример:
Ваш читаемый код вроде return qty * price превращается в список чисел вида [0x15,0x03,0x17,...], который может выполнить только встроенный интерпретатор VM. Исходная логика больше не видна как JavaScript.
vmTargetFunctions
Type: string[] Default: []
Позволяет точно указать по имени, какие функции корневого уровня должны получить VM-защиту.
Пример:
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Результат: VM-защиту получают только эти три функции. Всё остальное остаётся обычным (но всё ещё обфусцированным) JavaScript. Идеально для защиты чувствительных проверок лицензии или логики аутентификации, оставляя остальной код лёгким.
vmExcludeFunctions
Type: string[] Default: []
Позволяет указать функции корневого уровня, которые никогда не должны получать VM-защиту. Имеет приоритет над другими настройками.
Пример:
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Когда использовать: критичные к производительности функции корневого уровня (циклы анимации, обработка данных в реальном времени) можно исключить, чтобы избежать накладных расходов VM, при этом защищая всё остальное.
vmTargetFunctionsMode
Type: string Default: root
Управляет тем, как функции/методы выбираются для VM-обфускации.
Пример — режим comment:
// 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'
}
Когда использовать: когда вам нужен хирургический контроль над тем, какие именно функции получают VM-защиту, особенно вложенные функции, содержащие чувствительную логику. В отличие от vmTargetFunctions, который работает только с именованными функциями корневого уровня, режим comment позволяет защитить любую функцию в любом месте вашего кода.
vmForceCompileDynamicCode
Type: boolean Default: false
Управляет тем, что VM-обфускация делает с функцией, содержащей прямой вызов eval, new Function(...) или Function(...).
По умолчанию такая функция (и каждая функция, определённая внутри неё) пропускается при преобразовании в VM-байт-код, а в result.getWarnings() сообщается предупреждение VMDynamicCodeSkipped. Это связано с тем, что построенный во время выполнения исходник может ссылаться на идентификаторы из окружающей цепочки областей видимости — идентификаторы, которые обфускатор переименовал.
При значении true функция всё равно преобразуется в байт-код, и предупреждение VMDynamicCodeSkipped больше не выдаётся.
Отдельное предупреждение DynamicCodeRenameRisk продолжает срабатывать независимо от этой опции, поскольку описываемый им риск переименования не зависит от пропуска VM — включение этой опции не делает исходный паттерн безопаснее.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
При выключенной опции (по умолчанию) loadConfig остаётся обычным JavaScript. При включённой опции loadConfig компилируется в VM-байт-код, как и любая другая функция. Используйте это, когда вы проверили место вызова и знаете, что построенный во время выполнения код не зависит от переименованных в замыкании идентификаторов.
vmWrapTopLevelInitializers
Type: boolean Default: false
Оборачивает некоторые инициализаторы переменных верхнего уровня в IIFE (немедленно вызываемые функциональные выражения), чтобы их можно было VM-обфусцировать.
Что она делает: Без этой опции константы и переменные верхнего уровня остаются видимыми в выводе:
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
При включённой опции инициализатор оборачивается в IIFE, которое VM-обфусцируется:
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Примечание: эта опция работает, только когда vmTargetFunctionsMode имеет значение 'root' (по умолчанию).
Предупреждения: всякий раз, когда инициализатор верхнего уровня остаётся в обычном JavaScript при VM-обфускации, выдаётся предупреждение VMTopLevelInitializerNotVirtualized со списком затронутых имён переменных. Это охватывает: отключение этой опции, инициализаторы, которые этой опции пришлось пропустить (каждый с причиной — например, инициализатор ссылается на соседний деклератор или содержит top-level await), и режим vmAsyncExecutor, где синхронные обёртки вообще не могут быть виртуализированы.
vmDynamicOpcodes
Type: boolean Default: false
Делает интерпретатор VM меньше и уникальным для каждой сборки.
Что она делает:
- Отфильтровывает неиспользуемые инструкции — если ваш код не использует классы, инструкции, связанные с классами, полностью удаляются
- Рандомизирует структуру — порядок обработчиков инструкций перемешивается при каждой сборке
В результате — меньший размер вывода, и каждая сборка выглядит по-разному.
vmBytecodeEncoding
Type: boolean Default: false
Кодирует каждую инструкцию байт-кода. Инструкции декодируются по одной во время выполнения.
vmBytecodeArrayEncoding
Type: boolean Default: false
Кодирует весь массив байт-кода как единый блок. Массив декодируется один раз при запуске, до начала выполнения. Используйте вместе с vmBytecodeEncoding для двух слоёв защиты.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Свой ключ шифрования для кодирования массива байт-кода. Когда он задан, этот ключ используется вместо ключа по умолчанию, выводимого из окружения. Ключ должен предоставляться во время выполнения через vmBytecodeArrayEncodingKeyGetter.
Эта опция выносит ключ шифрования наружу — он не встроен в сам обфусцированный код. Хотя ключ всё равно доступен во время выполнения (и потому не является по-настоящему секретным), такое разделение не позволяет инструментам статического анализа найти ключ, изучая только код.
Важно: ключ должен быть доступен синхронно в момент загрузки обфусцированного кода. Используйте синхронное хранилище, например cookie, localStorage, sessionStorage, глобальные переменные или DOM-элементы (например, внедрённые сервером мета-теги). Асинхронные методы вроде fetch() нельзя использовать напрямую в выражении геттера ключа.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Синхронное выражение JavaScript, которое возвращает ключ шифрования во время выполнения. Это выражение вычисляется при загрузке обфусцированного кода и должно вернуть тот же ключ, который был передан в vmBytecodeArrayEncodingKey. Чтобы получать ключ асинхронно (Promise), включите vmAsyncExecutor.
Примечание: геттер, возвращающий Promise, требует vmAsyncExecutor. Это нельзя проверить на этапе сборки, поэтому геттер, возвращающий Promise, при выключенной vmAsyncExecutor завершится ошибкой во время выполнения — декодер получит Promise вместо ключа.
Обфусцированный код будет работать только тогда, когда геттер ключа возвращает ровно тот же ключ, что использовался при обфускации. Если ключи не совпадают, расшифровка завершится неудачей, и код выдаст мусор или ошибки. Если геттер ключа возвращает undefined, null или пустую строку, код бросит ошибку: "VM decryption key not available".
Важно: держите ключ вне того же файла/скрипта, что и обфусцированный код — встраивание его туда позволяет восстановить его даже чисто статическим сканированием бандла. Храните его в отдельном источнике: заданные сервером cookie, localStorage, заполняемый другим скриптом, внедрённый сервером HTML-мета-тег, глобальная переменная, заданная другим скриптом, или (с vmAsyncExecutor) получаемый с вашего бэкенда во время выполнения.
Когда ключ получается с вашего бэкенда (через vmAsyncExecutor), добавьте на этот эндпоинт проверки на основе сессии или источника: возвращайте правильный ключ реальным пользователям (действительная сессия, ожидаемый Origin/Referer) и мусорный ключ подозрительным запросам (например, localhost/неожиданный источник, отсутствие сессии). Реальные пользователи работают нормально; копия, запущенная вне вашего окружения, получает ключ, расшифровка которым не даёт ничего. Точная логика зависит от вашего сайта.
Примеры:
// 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())'
Пример использования:
// 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
Включает асинхронный исполнитель VM, который позволяет vmBytecodeArrayEncodingKeyGetter возвращать Promise (асинхронный геттер ключа) — так что ключ расшифровки можно получать во время выполнения (сетевой запрос, IndexedDB и т. д.), а не иметь его синхронно доступным в момент загрузки кода.
Настоятельно рекомендуется для полностью асинхронных кодовых баз. В этом режиме виртуализируются только async-функции — синхронную функцию нельзя сделать асинхронной, не превратив её возвращаемое значение в Promise и не сломав вызывающий код, — поэтому код, асинхронный на всём протяжении, получает наибольший охват. Он всё равно работает, когда корень синхронный (например, синхронное IIFE / UMD-обёртка): защищаются самые внешние async-функции внутри, а синхронные части остаются как есть.
Что преобразуется: каждая самая внешняя async-функция, где бы она ни находилась (в том числе вложенная в синхронные обёртки). Самая внешняя async в каждой цепочке — это защищаемая единица; всё внутри неё, синхронное и асинхронное, компилируется целиком. Синхронные функции и обычные генераторы остаются необфусцированными.
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
}
}
Пропуски и предупреждения. Асинхронные генераторы также остаются необфусцированными, когда активен асинхронный геттер ключа (асинхронный генератор должен возвращать свой итератор синхронно и не может ждать ключ). В режиме по умолчанию vmTargetFunctionsMode: 'root' пропуски происходят молча (выбор автоматический); в режиме comment выдаётся предупреждение через ObfuscationResult.getWarnings() всякий раз, когда явно помеченную вами функцию не удаётся виртуализировать — она оказалась синхронной или это асинхронный генератор при асинхронном геттере ключа.
Асинхронный геттер ключа дополнительно требует vmBytecodeArrayEncoding с vmBytecodeArrayEncodingKeyGetter.
Пример использования:
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
Кодирует цели переходов в байт-коде. Смещения переходов вычисляются во время выполнения, скрывая структуру потока управления (if/else, циклы и т. д.) от статического анализа.
vmMacroOps
Type: boolean Default: false
Объединяет частые последовательности инструкций в единые «макро»-опкоды. Например, LOAD + ADD + STORE может стать одной инструкцией MACRO_ADD_TO_VAR. Это ломает распознавание паттернов и может повысить производительность.
vmDebugProtection
Type: boolean Default: false
Добавляет многоуровневые средства защиты от отладки, анализа и LLM в среду выполнения VM. Лучше всего работает с целями browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Добавляет многоуровневую защиту от вмешательства, от хуков и от реверс-инжиниринга в среду выполнения VM.
⚠️ Эта опция принудительно включает vmBytecodeArrayEncoding.
⚠️ Обнаружение чувствительной среды. Эта опция привязывает обфусцированный код к его целевой среде выполнения и использует продвинутый браузерный фингерпринтинг для обнаружения инструментов автоматизации. Код, защищённый этой опцией, намеренно сломается при запуске в:
- Headless-браузерах (headless Chrome/Chromium, PhantomJS)
- Инструментах автоматизации браузера (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (когда
targetустановлен наbrowser) - jsdom или подобных серверных эмуляциях DOM
- Средах, где встроенные объекты браузера были перехвачены или подменены
Код будет работать корректно в обычных браузерах (Chrome, Firefox, Safari, Edge), в том числе при загрузке внутри iframe, в расширениях браузера (content scripts) и в Web Workers. Если вам нужно запускать автоматические тесты против защищённого кода, отключите vmSelfDefending для тестовых сборок — эта опция предназначена для предотвращения автоматического анализа и не может безопасно использоваться ни с одним фреймворком автоматизации.
Настоятельно рекомендуется использовать вместе с vmDebugProtection, vmBytecodeArrayEncodingKey и vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook принимает объект с двумя ключами: name (обязательный) и aliases (необязательный).
name — это глобальная функция, которую определяет ваша страница-хост и которую защита VM (vmDebugProtection / vmSelfDefending) вызывает с объектом-сигналом, когда обнаруживает враждебный сигнал — отладчик или инспектор, headless-/автоматизированный браузер, процесс ИИ-агента для написания кода, недопустимый домен и так далее. Используйте её, чтобы сообщать о событии на свой бэкенд (например, через navigator.sendBeacon). Хук — это чистый приёмник телеметрии: его возвращаемое значение игнорируется, а отсутствующий или бросающий исключение хук — это тихая пустая операция, которая никогда не может отключить защиту. Чтобы изменить то, что защита делает при обнаружении, используйте vmDefenseReaction.
aliases необязательно переименовывает поля этого объекта-сигнала — это описано ниже в разделе Переименование полей сигнала.
Объект-сигнал. Хук получает единственный signal:
source— конкретный детектор, который сработал (см. таблицу).category— группа, под которой он сообщает:automation(нечеловеческие браузеры),debugger(активен отладчик/инспектор),sandbox(инструментированный/поддельный хост),domain(нарушение привязки к домену),tamper(встроенные объекты пропатчены во время выполнения) илиintegrity(изменён собственный код VM).score/threshold— насколько сильно сработал детектор и значение, которого он должен был достичь; хук срабатывает только приscore >= threshold. Большинство проверок работают по принципу «всё или ничего» (один решающий сигнал);headlessсуммирует несколько сигналов о форме браузера, поэтому егоscoreобычно выше, чемthreshold.
Регистрация хука. Определите его как обычную глобальную функцию до загрузки обфусцированного бандла — среда выполнения VM и её защиты работают до вашей (защищённой) программы, поэтому многие обнаружения происходят во время старта:
// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }
Хук, определённый внутри обфусцированного исходника, регистрируется слишком поздно, чтобы ловить обнаружения на старте, и если он попадёт под VM-компиляцию, до него не добраться, пока не запустится ваша программа. Он безопасен в любом случае (отсутствующий хук — пустая операция, а защита от повторного входа предотвращает разгон), но для полного охвата регистрируйте его заранее. Чтобы всё же защитить логику отправки, оставьте зарегистрированный хук однострочным буфером ((window.__vmDet = window.__vmDet || []).push(signal)) и читайте/отправляйте этот буфер из своего обфусцированного кода.
Переименование полей сигнала (aliases). Значения source/category по умолчанию — описательные имена, поэтому любой, кто инструментирует коллбэк (или читает вывод), может распознать защиту и то, какой детектор сработал. aliases переименовывает поля сигнала в непрозрачные токены на ваш выбор, применяемые внутри VM до того, как сигнал будет выпущен, так что эти имена никогда не появляются в выводе и не попадают в коллбэк. Ваше приложение знает собственное сопоставление и пересылает токены на бэкенд.
Псевдонимы задаются на каждое поле, разделяя переименование ключей и значений: каждое поле принимает key (имя свойства, которое получает коллбэк); строковые поля-имена source и category также принимают карту values, тогда как score/threshold — числа и принимают только key. Имена, которые можно сопоставить (всё остальное отклоняется на этапе сборки):
- ключи полей —
source,category,score,threshold - значения
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - значения
category—automation,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> }
}
Это уход от отпечатка, а не секретность — сопоставление всё равно можно вывести повторным тестированием, — так что единственная его польза в том, чтобы не раскрывать стабильные, самоочевидные имена. Незаданные записи сохраняют имена по умолчанию.
Голая строка (vmDefenseHook: '__vmDetection') принимается как сокращение для { name: '__vmDetection' }, но устарела — предпочитайте форму-объект.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Настраивает, как реагирует каждая категория срабатываний. Она ничего не включает — сами защиты включаются через vmSelfDefending, vmDebugProtection и vmDomainLock; эта опция лишь выбирает, как реагирует включённая защита. Категория — единица управления: каждый детектор в категории применяет реакцию этой категории.
Каждая категория группирует детекторы, следящие за одним видом враждебного условия. Категория реагирует только тогда, когда включена опция, выпускающая её детекторы:
Каждая категория соответствует одной или нескольким из vmSelfDefending, vmDebugProtection и vmDomainLock; вне этих трёх опций категорий нет, а реакция, заданная для категории с выключенной опцией, просто не имеет эффекта.
Ключи — это шесть названий категорий или default (запасной вариант для неуказанных категорий). Значения:
break— сломаться немедленноdecoy— продолжать работать на отравленном состоянии, незаметно выдавая неверные результатыnone— ничего не делать локально (только телеметрия)
Значения по умолчанию для каждой категории показаны выше; категория, которую вы не задали (или задали её значением по умолчанию), использует это значение по умолчанию. default охватывает каждую категорию, включая корректные по построению (integrity, tamper), поэтому { default: 'none' } — это по-настоящему неразрушающая сборка, отправляющая только телеметрию:
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
Делает значения опкодов зависящими от позиции в байт-коде. Каждая позиция имеет своё сопоставление опкода с обработчиком, выведенное из зерна, поэтому один и тот же номер опкода выполняет разные операции на разных позициях.
vmCallContextOpcodes
Type: boolean Default: false
Делает защищённую функцию зависящей от того, откуда она вызвана, так что её нельзя вынести из кода и запустить или проанализировать саму по себе — она ведёт себя корректно только при вызове через реальные места вызова в программе. Эта опция влияет на производительность во время выполнения.
В настоящее время поддерживаются только следующие конструкции:
- объявления функций (
function f() {}); - функциональные и стрелочные выражения, присвоенные переменной (
const f = () => {}); - приватные методы экземпляра (
this.#m()).
Во всех случаях функция всегда должна достигаться через прямой вызов (f(), this.#m()). Если она сохраняется в другую переменную, передаётся как аргумент или иным образом используется как значение, она остаётся незащищённой. Асинхронные функции поддерживаются; генераторы — нет.
Эта опция экспериментальна и может сломать ваш код, поэтому тщательно тестируйте вывод перед её использованием.
vmStackEncoding
Type: boolean Default: false
Шифрует значения на стеке VM во время выполнения. Значения кодируются при помещении в стек и декодируются при извлечении, поэтому при инспекции памяти видны зашифрованные данные вместо реальных значений.
Эта опция сильно влияет на производительность.
vmCompactDispatcher
Type: boolean Default: false
Использует один исполнитель VM вместо двух (синхронный + генераторный). Уменьшает размер обфусцированного кода, но добавляет около 20% накладных расходов на производительность для кода с большим количеством рекурсии.
false(по умолчанию): два исполнителя — оптимальная производительность, больший размер выводаtrue: один исполнитель — меньший размер вывода, немного медленнее
vmStringArrayBytecodeOnly
Type: boolean Default: false
Когда опция включена, массив строк будет извлекать строки только из данных байт-кода — никакие другие строки в коде не преобразуются. Это принудительно включает stringArray, даже если он не задан явно.
Зачем это использовать: извлечение всех строк среды выполнения VM в массив строк — медленно. Эта опция нацеливает извлечение в массив строк только на содержимое байт-кода, повышая производительность и при этом защищая константы байт-кода.
- Когда
vmBytecodeArrayEncoding: false— извлекаются строки внутри пулов констант байт-кода (массивыc) - Когда
vmBytecodeArrayEncoding: true— извлекаются строки байт-кода верхнего уровня, закодированные в base64 stringArrayThresholdпо-прежнему управляет тем, какой процент этих строк байт-кода извлекается
vmDomainLock
Type: string[] Default: []
⚠️ Эта опция не работает с target: 'node', target: 'service-worker' или target: 'bytenode'
Ограничивает обфусцированный код определёнными доменами и/или поддоменами, и её гораздо сложнее найти и вырезать, чем domainLock.
Если исходный код запущен не на доменах, указанных в этой опции, браузер будет перенаправлен на URL, переданный в vmDomainLockRedirectUrl, а дальнейшие защищённые вызовы будут возвращать неверные результаты, даже если перенаправление подавлено.
Несколько доменов и поддоменов
Код можно привязать более чем к одному домену или поддомену. Например, чтобы код работал только на www.example.com, добавьте www.example.com. Чтобы он работал на корневом домене, включая любые поддомены (example.com, sub.example.com), используйте .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Эта опция не работает с target: 'node', target: 'service-worker' или target: 'bytenode'
Позволяет перенаправить браузер на переданный URL, если исходный код запущен не на доменах, указанных в vmDomainLock.
Preset Options
Высокая обфускация, низкая производительность
Производительность будет значительно ниже, чем без обфускации
{
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
}
Средняя обфускация, оптимальная производительность
Производительность будет ниже, чем без обфускации
{
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
}
Низкая обфускация, высокая производительность
Производительность будет на относительно нормальном уровне
{
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
}
Пресет по умолчанию, высокая производительность
{
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 obfuscation (максимальная безопасность)
Этот пресет включает VM-обфускацию на основе байт-кода со всеми функциями усиления защиты, включая непрямую диспетчеризацию. Обеспечивает самую сильную защиту, но с большим размером вывода и значительно более медленным выполнением.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Или настройте по отдельности:
{
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 (защита от ИИ-агентов)
Этот пресет специально разработан, чтобы не дать ИИ-агентам и LLM реверс-инжинирить код в VM-байт-коде. Основан на vm-default с включёнными самозащитой и защитой от отладки. Легче, чем vm-high-obfuscation, но специально усилен против автоматического анализа.
{
optionsPreset: 'vm-anti-llm'
}
Включает:
- VM-обфускацию байт-кода с массивом строк (из
vm-default) vmSelfDefending— обнаружение хуков, хеш целостности, отпечаток исходника, проверку чистого realm через iframe, вывод ключа шифра ARXvmDebugProtection— проверки против отладки в цикле диспетчеризации VMdebugProtection: false— без устаревшей защиты от отладки (VM-защита от отладки лучше)
VM High obfuscation (наивысшая безопасность)
Этот пресет включает VM-обфускацию на основе байт-кода с большинством функций усиления защиты. Обеспечивает сильную защиту с лучшей производительностью, чем пресет ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Или настройте по отдельности:
{
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 obfuscation (сбалансированная безопасность)
Этот пресет включает VM-обфускацию на основе байт-кода со сбалансированным набором функций усиления защиты. Хороший компромисс между безопасностью и производительностью.
{
optionsPreset: 'vm-medium-obfuscation'
}
Или настройте по отдельности:
{
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 obfuscation (базовая безопасность, лучшая производительность)
Этот пресет включает базовую VM-обфускацию на основе байт-кода без дополнительных функций усиления защиты. Хороший баланс между безопасностью и размером вывода.
{
optionsPreset: 'vm-low-obfuscation'
}
Или настройте по отдельности:
{
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 + защита массивом строк)
Этот пресет сочетает базовую VM-обфускацию на основе байт-кода с защитой массивом строк. Хорошая отправная точка для VM-обфускации со строковой защитой.
{
optionsPreset: 'vm-default'
}
Или настройте по отдельности:
{
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
}
