Referência de opções
Conteúdo
compact
config
controlFlowFlattening
controlFlowFlatteningThreshold
deadCodeInjection
deadCodeInjectionThreshold
debugProtection
debugProtectionInterval
disableConsoleOutput
domainLock
Múltiplos domínios e subdomínios
domainLockRedirectUrl
exclude
forceTransformStrings
identifierNamesCache
API do Node.js
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
Múltiplos domínios e subdomínios
vmDomainLockRedirectUrl
Preset Options
Ofuscação alta, baixo desempenho
Ofuscação média, desempenho ótimo
Ofuscação baixa, alto desempenho
Predefinição padrão, alto desempenho
Ofuscação VM Ultra High (Segurança Máxima)
VM Anti-LLM (Proteção contra Agentes de IA)
Ofuscação VM High (Segurança Mais Alta)
Ofuscação VM Medium (Segurança Equilibrada)
Ofuscação VM Low (Segurança Básica, Melhor Desempenho)
VM Default (VM + Proteção de Array de Strings)
compact
Type: boolean Default: true
Compacta a saída do código em uma única linha.
config
Type: string Default: ``
Nome do arquivo de configuração JS/JSON que contém as opções do ofuscador. Elas serão sobrescritas pelas opções passadas diretamente pela CLI
controlFlowFlattening
Type: boolean Default: false
⚠️ Esta opção afeta muito o desempenho, tornando a execução até 1,5x mais lenta. Use controlFlowFlatteningThreshold para definir a porcentagem de nós que serão afetados pelo achatamento do fluxo de controle.
Ativa o achatamento do fluxo de controle do código. O achatamento do fluxo de controle é uma transformação da estrutura do código-fonte que dificulta a compreensão do programa.
Exemplo:
// 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
A probabilidade de que a transformação controlFlowFlattening seja aplicada a um determinado nó.
Esta configuração é especialmente útil para códigos grandes, pois grandes quantidades de transformações de fluxo de controle podem deixar seu código mais lento e aumentar seu tamanho.
controlFlowFlatteningThreshold: 0 equivale a controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Aumenta drasticamente o tamanho do código ofuscado (até 200%); use apenas se o tamanho do código ofuscado não importar. Use deadCodeInjectionThreshold para definir a porcentagem de nós que serão afetados pela injeção de código morto.
⚠️ Esta opção ativa forçadamente a opção stringArray.
⚠️ Esta opção é silenciosamente desativada quando vmObfuscation está ativado.
Com esta opção, blocos aleatórios de código morto serão adicionados ao código ofuscado.
Exemplo:
// 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
Permite definir a porcentagem de nós que serão afetados por deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Pode travar seu navegador se você abrir as Ferramentas de Desenvolvedor.
⚠️ Esta opção é silenciosamente desativada quando vmObfuscation está ativado. Use vmDebugProtection em seu lugar.
Esta opção torna praticamente impossível usar a função debugger das Ferramentas de Desenvolvedor (tanto em navegadores baseados em WebKit quanto no Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Pode travar seu navegador! Use por sua conta e risco.
⚠️ Esta opção é silenciosamente desativada quando vmObfuscation está ativado. Use vmDebugProtection em seu lugar.
Se definido, um intervalo em milissegundos é usado para forçar o modo de depuração na aba Console, dificultando o uso de outros recursos das Ferramentas de Desenvolvedor. Funciona se debugProtection estiver ativado. O valor recomendado fica entre 2000 e 4000 milissegundos.
disableConsoleOutput
Type: boolean Default: false
⚠️ Esta opção desativa as chamadas de console globalmente para todos os scripts
Desativa o uso de console.log, console.info, console.error, console.warn, console.debug, console.exception e console.trace substituindo-os por funções vazias. Isso dificulta o uso do depurador.
domainLock
Type: string[] Default: []
⚠️ Esta opção não funciona com target: 'node', target: 'service-worker' ou target: 'bytenode'
Permite executar o código-fonte ofuscado apenas em domínios e/ou subdomínios específicos. Isso torna realmente difícil que alguém simplesmente copie e cole seu código-fonte e o execute em outro lugar.
Se o código-fonte não for executado nos domínios especificados por esta opção, o navegador será redirecionado para a URL passada à opção domainLockRedirectUrl.
Múltiplos domínios e subdomínios
É possível restringir seu código a mais de um domínio ou subdomínio. Por exemplo, para restringi-lo de modo que o código só rode em www.example.com, adicione www.example.com. Para que funcione no domínio raiz incluindo quaisquer subdomínios (example.com, sub.example.com), use .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Esta opção não funciona com target: 'node', target: 'service-worker' ou target: 'bytenode'
Permite que o navegador seja redirecionado para uma URL passada caso o código-fonte não seja executado nos domínios especificados por domainLock.
exclude
Type: string[] Default: []
Nomes de arquivos ou globs que indicam os arquivos a serem excluídos da ofuscação.
forceTransformStrings
Type: string[] Default: []
Ativa a transformação forçada dos literais de string que correspondam aos padrões RegExp passados.
⚠️ Esta opção afeta apenas as strings que não deveriam ser transformadas por stringArrayThreshold (ou possivelmente outros thresholds no futuro)
A opção tem prioridade sobre a opção reservedStrings, mas não tem prioridade sobre os conditional comments.
Exemplo:
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
O principal objetivo desta opção é a capacidade de usar os mesmos nomes de identificadores durante a ofuscação de múltiplos códigos-fonte/arquivos.
Atualmente, há suporte para dois tipos de identificadores:
- Identificadores globais:
- Todos os identificadores globais serão escritos no cache;
- Todos os identificadores globais não declarados que corresponderem serão substituídos pelos valores do cache.
- Identificadores de propriedades, apenas quando a opção
renamePropertiesestá ativada:- Todos os identificadores de propriedades serão escritos no cache;
- Todos os identificadores de propriedades que corresponderem serão substituídos pelos valores do cache.
API do Node.js
Se um valor null for passado, o cache é completamente desativado.
Se um objeto vazio ({}) for passado, ativa a escrita dos nomes de identificadores no objeto de cache (tipo TIdentifierNamesCache). Esse objeto de cache será acessado por meio da chamada do método getIdentifierNamesCache do objeto ObfuscationResult.
O objeto de cache resultante pode ser usado em seguida como valor da opção identifierNamesGenerator para usar esses nomes durante a ofuscação de todos os nomes de identificadores correspondentes dos próximos códigos-fonte.
Exemplo:
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
A CLI tem uma opção diferente, --identifier-names-cache-path, que permite definir um caminho para o arquivo .json existente que será usado para ler e escrever o cache de nomes de identificadores.
Se um caminho para um arquivo vazio for passado, o cache de nomes de identificadores será escrito nesse arquivo.
Esse arquivo com o cache existente pode ser reutilizado como valor da opção --identifier-names-cache-path para usar esses nomes durante a ofuscação de todos os nomes de identificadores correspondentes dos próximos arquivos.
identifierNamesGenerator
Type: string Default: hexadecimal
Define o gerador de nomes de identificadores.
Valores disponíveis:
dictionary: nomes de identificadores da listaidentifiersDictionaryhexadecimal: nomes de identificadores como_0xabc123mangled: nomes de identificadores curtos comoa,b,cmangled-shuffled: igual amangled, mas com o alfabeto embaralhado
identifiersDictionary
Type: string[] Default: []
Define o dicionário de identificadores para identifierNamesGenerator: opção dictionary. Cada identificador do dicionário será usado em algumas variações com diferentes combinações de maiúsculas e minúsculas de cada caractere. Assim, a quantidade de identificadores no dicionário deve depender da quantidade de identificadores no código-fonte original.
identifiersPrefix
Type: string Default: ''
Define um prefixo para todos os identificadores globais.
Use esta opção quando quiser ofuscar múltiplos arquivos. Ela ajuda a evitar conflitos entre os identificadores globais desses arquivos. O prefixo deve ser diferente para cada arquivo.
randomIdentifiersPrefix
Type: boolean Default: false
Acrescenta um prefixo aleatório com semente (6 caracteres alfanuméricos) a todos os identificadores globais. Use esta opção para evitar colisões entre bundles ofuscados separadamente que são carregados no mesmo escopo global — ela elimina a necessidade de escolher manualmente um identifiersPrefix único para cada bundle.
- O valor aleatório é derivado da opção
seede do hash do código-fonte, então builds reproduzíveis com a mesma semente produzem o mesmo prefixo. - Quando combinado com
identifiersPrefix, os caracteres aleatórios são acrescentados ao prefixo fornecido pelo usuário (por exemplo,myApp+ aleatórioaBc123→myAppaBc123). - Quando combinado com
vmObfuscation, o valor aleatório substitui o prefixo padrãovm— a aleatoriedade já garante a unicidade.
ignoreImports
Type: boolean Default: false
Impede a ofuscação de imports require. Pode ser útil em alguns casos quando, por algum motivo, o ambiente de execução exige esses imports apenas com strings estáticas.
inputFileName
Type: string Default: ''
Permite definir o nome do arquivo de entrada com o código-fonte. Esse nome será usado internamente para a geração do source map.
Obrigatório ao usar a API do NodeJS e quando a opção sourceMapSourcesMode tem o valor sources.
log
Type: boolean Default: false
Ativa o registro de informações no console.
numbersToExpressions
Type: boolean Default: false
Ativa a conversão de números em expressões
Exemplo:
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Permite definir uma predefinição de opções.
Valores disponíveis:
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.
Todas as opções adicionais serão mescladas com a predefinição de opções selecionada.
parseHtml
Type: boolean Default: false
Ativa a ofuscação de JavaScript dentro de tags <script> de HTML.
Quando ativada, o ofuscador irá:
- Detectar automaticamente se a entrada é HTML (verificando as tags
<!DOCTYPE,<html>,<head>,<body>ou<script>) - Extrair o JavaScript das tags
<script>marcadas com o atributodata-javascript-obfuscator - Ofuscar cada script marcado individualmente, preservando a estrutura do HTML
- Injetar o código ofuscado de volta nas posições originais
Importante: Apenas os scripts com o atributo data-javascript-obfuscator são ofuscados. Cada script marcado é ofuscado de forma individual e independente. Isso significa que:
- O código dentro das tags de script marcadas deve estar isolado - ele NÃO pode referenciar variáveis, funções ou classes definidas em outras tags de script marcadas
- Scripts não marcados ainda podem acessar globais definidos por scripts marcados (por meio de declarações
varou atribuições explícitas aglobalThis) - Isso dá a você controle explícito sobre quais scripts proteger
Ofuscados (devem ter o atributo data-javascript-obfuscator):
<script data-javascript-obfuscator>- scripts comuns<script type="text/javascript" data-javascript-obfuscator>- scripts com tipo explícito- Scripts com quaisquer atributos adicionais (
id,class, outrosdata-*, etc.)
Ignorados (mantidos inalterados):
- Scripts sem o atributo
data-javascript-obfuscator <script type="module">- módulos ES (mesmo com o atributo)<script src="...">- scripts externos (mesmo com o atributo)- Tags de script vazias
Nota: Os source maps não são gerados quando parseHtml está ativado, pois não mapeariam corretamente para a saída em HTML.
Exemplo:
// 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
⚠️ esta opção pode quebrar seu código. Ative-a apenas se você souber o que ela faz!
Ativa a ofuscação de nomes de variáveis e funções globais com declaração.
Quando esta opção está desativada e o código de entrada declara funções ou classes no escopo global (ou seja, o código não está envolvido em uma IIFE), seus nomes são mantidos como estão na saída ofuscada — outros scripts podem referenciá-los pelo nome. Sob vmObfuscation, um aviso VMGlobalFunctionNamesNotRenamed listando esses nomes é reportado, já que o corpo da função fica oculto como bytecode, mas o nome legível de nível superior ainda revela o que o código faz (por exemplo, para uma LLM). Para evitar essa exposição, envolva o código em uma IIFE ou ative esta opção.
renameProperties
Type: boolean Default: false
⚠️ esta opção PODE quebrar seu código. Ative-a apenas se você souber o que ela faz!
Ativa a renomeação de nomes de propriedades. Todas as propriedades DOM nativas e as propriedades das classes principais do JavaScript serão ignoradas.
Para alternar entre os modos safe e unsafe desta opção, use a opção renamePropertiesMode.
Para definir o formato dos nomes de propriedades renomeados, use a opção identifierNamesGenerator.
Para controlar quais propriedades serão renomeadas, use a opção reservedNames.
Exemplo:
// 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
⚠️ Mesmo no modo safe, a opção renameProperties PODE quebrar seu código.
Especifica o modo da opção renameProperties:
safe- comportamento padrão após a versão2.11.0. Tenta renomear propriedades de forma mais segura para evitar erros em tempo de execução. Com este modo, algumas propriedades serão excluídas da renomeação.unsafe- comportamento padrão antes da versão2.11.0. Renomeia as propriedades de forma insegura, sem quaisquer restrições.
Se um arquivo estiver usando propriedades de outro arquivo, use a opção identifierNamesCache para manter os mesmos nomes de propriedades entre esses arquivos.
reservedNames
Type: string[] Default: []
Desativa a ofuscação e a geração de identificadores que correspondam aos padrões RegExp passados.
Exemplo:
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Desativa a transformação dos literais de string que correspondam aos padrões RegExp passados. As strings correspondentes permanecerão visíveis na saída ofuscada.
Ao usar a ofuscação VM, as strings reservadas são armazenadas em um array separado e não criptografado para mantê-las visíveis. Isso é útil para strings que precisam permanecer legíveis, como endpoints de API para monitoramento ou identificadores de bibliotecas.
Exemplo:
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Esta opção define a semente (seed) do gerador aleatório. Isso é útil para criar resultados reproduzíveis.
Se a semente for 0, o gerador aleatório funcionará sem semente.
selfDefending
Type: boolean Default: false
⚠️ Não altere o código ofuscado de forma alguma após a ofuscação com esta opção, pois qualquer alteração, como a minificação do código, pode acionar a autodefesa e o código deixará de funcionar!
⚠️ Esta opção define forçadamente o valor de compact como true
⚠️ Esta opção é silenciosamente desativada quando vmObfuscation está ativado. Use vmSelfDefending em seu lugar.
Esta opção torna o código de saída resistente à formatação e à renomeação de variáveis. Se alguém tentar usar um beautifier de JavaScript no código ofuscado, o código deixará de funcionar, tornando-o mais difícil de entender e modificar.
simplify
Type: boolean Default: true
Ativa ofuscação adicional do código por meio de simplificação.
⚠️ em versões futuras, a ofuscação de literais boolean (true => !![]) será movida para esta opção.
Exemplo:
// 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
Ativa a geração de source map para o código ofuscado.
Os source maps podem ser úteis para ajudar você a depurar seu código-fonte JavaScript ofuscado. Se você quiser ou precisar depurar em produção, pode enviar o arquivo separado de source map para um local secreto e apontar seu navegador para lá.
sourceMapBaseUrl
Type: string Default: ``
Define a URL base da URL de import do source map quando sourceMapMode: 'separate'.
Exemplo de CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Resultado:
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Define o nome do arquivo do source map de saída quando sourceMapMode: 'separate'.
Exemplo de CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Resultado:
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Especifica o modo de geração do source map:
inline- adiciona o source map ao final de cada arquivo .js;separate- gera o arquivo '.map' correspondente com o source map. Caso você execute o ofuscador pela CLI, adiciona ao final do arquivo com o código ofuscado o link para o arquivo de source map//# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Permite controlar os campos sources e sourcesContent do source map:
sources-content- adiciona um camposourcesfictício e adiciona o camposourcesContentcom o código-fonte original;sources- adiciona o camposourcescom uma descrição de fonte válida e não adiciona o camposourcesContent. Ao usar a API do NodeJS, é necessário definir a opçãoinputFileName, que será usada como valor do camposources.
splitStrings
Type: boolean Default: false
Divide os literais de string em partes com o comprimento definido pelo valor da opção splitStringsChunkLength.
Exemplo:
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Define o comprimento das partes da opção splitStrings.
stringArray
Type: boolean Default: true
Remove os literais de string e os coloca em um array especial. Por exemplo, a string "Hello World" em var m = "Hello World"; será substituída por algo como var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ a opção stringArray deve estar ativada
Ativa a transformação das chamadas ao stringArray. Todos os argumentos dessas chamadas podem ser extraídos para um objeto diferente dependendo do valor de stringArrayCallsTransformThreshold.
Assim, fica ainda mais difícil encontrar automaticamente as chamadas ao array de strings.
Exemplo:
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
⚠️ as opções stringArray e stringArrayCallsTransformThreshold devem estar ativadas
Você pode usar esta configuração para ajustar a probabilidade (de 0 a 1) de que as chamadas ao array de strings sejam transformadas.
stringArrayEncoding
Type: string[] Default: []
⚠️ a opção stringArray deve estar ativada
Esta opção pode deixar seu script mais lento.
Codifica todos os literais de string do stringArray usando base64 ou rc4 e insere um código especial usado para decodificá-los de volta em tempo de execução.
Cada valor do stringArray será codificado pela codificação escolhida aleatoriamente na lista passada. Isso possibilita usar múltiplas codificações.
Valores disponíveis:
'none'(boolean): não codifica o valor dostringArray'base64'(string): codifica o valor dostringArrayusandobase64'rc4'(string): codifica o valor dostringArrayusandorc4. Cerca de 30-50% mais lento quebase64, mas dificulta mais a obtenção dos valores iniciais.
Por exemplo, com os seguintes valores de opção, alguns valores do stringArray não serão codificados, e outros valores serão codificados com as codificações base64 e rc4:
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ a opção stringArray deve estar ativada
Permite controlar o tipo dos índices de chamada ao array de strings.
Cada índice de chamada ao stringArray será transformado pelo tipo escolhido aleatoriamente na lista passada. Isso possibilita usar múltiplos tipos.
Valores disponíveis:
'hexadecimal-number'(default): transforma os índices de chamada ao array de strings como números hexadecimais'hexadecimal-numeric-string': transforma os índices de chamada ao array de strings como strings numéricas hexadecimais
Antes da versão 2.9.0, o javascript-obfuscator transformava todos os índices de chamada ao array de strings com o tipo hexadecimal-numeric-string. Isso torna alguma desofuscação manual um pouco mais difícil, mas permite a fácil detecção dessas chamadas por desofuscadores automáticos.
O novo tipo hexadecimal-number busca dificultar a autodetecção de padrões de chamada ao array de strings no código.
Mais tipos serão adicionados no futuro.
stringArrayIndexShift
Type: boolean Default: true
⚠️ a opção stringArray deve estar ativada
Ativa o deslocamento adicional de índice para todas as chamadas ao array de strings
stringArrayRotate
Type: boolean Default: true
⚠️ stringArray deve estar ativado
Desloca o array stringArray por um número de posições fixo e aleatório (gerado na ofuscação do código). Isso dificulta associar a ordem das strings removidas ao seu local original.
stringArrayShuffle
Type: boolean Default: true
⚠️ stringArray deve estar ativado
Embaralha aleatoriamente os itens do array stringArray.
stringArrayWrappersCount
Type: number Default: 1
⚠️ a opção stringArray deve estar ativada
Define a quantidade de wrappers para o string array dentro de cada escopo raiz ou de função.
A quantidade real de wrappers dentro de cada escopo é limitada pela quantidade de nós literal dentro desse escopo.
Exemplo:
// 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
⚠️ as opções stringArray e stringArrayWrappersCount devem estar ativadas
Ativa as chamadas encadeadas entre os wrappers do string array.
Exemplo:
// 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
⚠️ a opção stringArray deve estar ativada
⚠️ Atualmente esta opção afeta apenas os wrappers adicionados pelo valor function da opção stringArrayWrappersType
Permite controlar o número máximo de parâmetros dos wrappers do array de strings.
O valor padrão e mínimo é 2. Valor recomendado entre 2 e 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ as opções stringArray e stringArrayWrappersCount devem estar ativadas
Permite selecionar o tipo dos wrappers que são adicionados pela opção stringArrayWrappersCount.
Valores disponíveis:
'variable': adiciona wrappers de variável no topo de cada escopo. Desempenho rápido.'function': adiciona wrappers de função em posições aleatórias dentro de cada escopo. Desempenho mais lento que comvariable, mas oferece uma ofuscação mais rigorosa.
Altamente recomendável usar wrappers function para uma ofuscação maior quando a perda de desempenho não tem grande impacto em uma aplicação ofuscada.
Exemplo do valor de opção '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
⚠️ a opção stringArray deve estar ativada
Você pode usar esta configuração para ajustar a probabilidade (de 0 a 1) de que um literal de string seja inserido no stringArray.
Esta configuração é especialmente útil para códigos grandes, pois ela chama o string array repetidamente e pode deixar seu código mais lento.
stringArrayThreshold: 0 equivale a stringArray: false.
strictMode
Type: boolean | null Default: null
Permite especificar como o ofuscador deve tratar o código em relação ao modo estrito (strict mode) do JavaScript.
Valores disponíveis:
null(padrão) - detecta automaticamente o modo estrito a partir do código. Se o código tiver uma diretiva'use strict'explícita, sintaxe de módulo ES ou métodos de classe, ele é tratado como modo estrito. Caso contrário, presume-se o modo não estrito (sloppy).true- força o tratamento em modo estrito para todo o código, mesmo sem uma diretiva'use strict'explícita. Use isto quando seu código for executar em um contexto de modo estrito (por exemplo, em módulos ES, bundlers ou frameworks modernos).false- apenas indicadores explícitos de modo estrito ('use strict', módulos ES, métodos de classe) são tratados como estritos. A herança do escopo pai ainda se aplica conforme a especificação do JS.
target
Type: string Default: browser
Permite definir o ambiente de destino para o código ofuscado.
Valores disponíveis:
browser(padrão) — ambiente padrão de página web. O código de saída é idêntico ao denode, mas algumas opções específicas de navegador não podem ser usadas com o alvonodebrowser-no-eval— igual abrowser, mas a saída não usaeval(). Use quando a página de destino tiver uma Content Security Policy que proíbeeval/unsafe-eval.node— ambiente Node.js. As opções específicas de navegador são desativadas (elas exigemwindow/documente não teriam efeito ou lançariam erro no Node). Algumas defesas devmSelfDefendingque dependem de APIs exclusivas de navegador — detecção de navegador headless, recuperação de realm limpo baseada em iframe, verificações anti-inspetor/DOM — não são emitidas para este alvo.service-worker— contexto de Service Worker. Semwindow, semdocument, com um globalselfdiferente.userscript— sandbox de gerenciador de userscripts (por exemplo, Tampermonkey). As defesas devmSelfDefendingsão ajustadas de acordo.bytenode— código Node.js que será compilado com o loader bytenode (bytecode em cache do V8,.jsc) após a ofuscação. O próprio ofuscador não invoca obytenode; ele emite JavaScript ofuscado por VM cujo runtime é estruturado para sobreviver à etapa de compilação do bytenode, e as defesas devmSelfDefendingsão ajustadas de acordo. Execute obytenodena saída ofuscada você mesmo para produzir o.jscfinal.
transformObjectKeys
Type: boolean Default: false
Ativa a transformação das chaves de objetos.
Exemplo:
// 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
Controla quais avisos de ofuscação não fatais são emitidos pelo método ObfuscationResult.getWarnings().
Valores disponíveis:
'all'(padrão) — todos os avisos são emitidos.'none'— todos os avisos são suprimidos.- um objeto que mapeia tipos de aviso para booleanos — um tipo mapeado para
falseé suprimido; todo tipo não presente (ou mapeado paratrue) permanece ativado. Por exemplo,{ "VMGlobalFunctionNamesNotRenamed": false }mantém todos os avisos, exceto esse.
Tipos de aviso:
VMGlobalFunctionNamesNotRenamed— sobvmObfuscation, os nomes de declarações de função de nível superior, declarações de classe e variáveis às quais é atribuída uma expressão de função/arrow/classe foram mantidos como estão (a opçãorenameGlobalsestá desativada e o código não está envolvido em uma IIFE), então eles permanecem legíveis na saída mesmo que os corpos estejam ocultos como bytecode. Nomes exportados não são reportados.VMTopLevelInitializerNotVirtualized— os inicializadores de variáveis de nível superior permaneceram em JavaScript puro sob a ofuscação VM porquevmWrapTopLevelInitializersestá desativado ou não conseguiu virtualizá-los.DynamicCodeRenameRisk— o código constrói uma função a partir de uma string em tempo de execução (evaldireto, o construtorFunctionoufn.toString()injetado em um<script>/Worker), o que pode referenciar identificadores que o ofuscador renomeou.VMDynamicCodeSkipped— uma função foi ignorada na conversão para bytecode da VM porque contémevaldireto /new Functiondinâmico /Function(vejavmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— comvmAsyncExecutorativado, uma função que você marcou explicitamente no modocommentmostrou-se síncrona e foi ignorada (apenas funções assíncronas são virtualizadas nesse modo).VMAsyncGeneratorSkippedInAsyncMode— comvmAsyncExecutore um getter de chave assíncrono ativo, um gerador assíncrono marcado não pôde ser virtualizado (ele deve retornar seu iterador de forma síncrona).BrowserTargetWithNodeStyleCode— o código aparenta ter o Node.js como alvo (por exemplo,require('fs'),__dirname,process.argv) enquanto a opçãotargetestá definida como um ambiente semelhante a navegador.
vmObfuscation
Type: boolean Default: false
Ativa a ofuscação por bytecode baseada em VM. Quando ativada, as funções JavaScript são compiladas em bytecode personalizado que roda em uma máquina virtual embutida. Isso oferece o nível mais alto de proteção, pois a lógica original do código é completamente transformada.
Exemplo:
Seu código legível, como return qty * price, torna-se uma lista de números como [0x15,0x03,0x17,...] que apenas o interpretador da VM embutida consegue executar. A lógica original deixa de ser visível como JavaScript.
vmTargetFunctions
Type: string[] Default: []
Especifica exatamente quais funções de nível raiz devem receber proteção de VM, por nome.
Exemplo:
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Resultado: Apenas essas três funções recebem proteção de VM. Todo o restante permanece como JavaScript comum (mas ainda ofuscado). Perfeito para proteger verificações sensíveis de licença ou lógica de autenticação, mantendo o restante do seu código enxuto.
vmExcludeFunctions
Type: string[] Default: []
Especifica funções de nível raiz que nunca devem receber proteção de VM. Tem precedência sobre outras configurações.
Exemplo:
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Quando usar: Funções de nível raiz críticas para o desempenho (loops de animação, processamento de dados em tempo real) podem ser excluídas para evitar a sobrecarga da VM, ainda protegendo todo o restante.
vmTargetFunctionsMode
Type: string Default: root
Controla como as funções/métodos são selecionados para a ofuscação VM.
Exemplo - modo 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'
}
Quando usar: Quando você precisa de controle cirúrgico sobre exatamente quais funções recebem proteção de VM, especialmente funções aninhadas que contêm lógica sensível. Ao contrário de vmTargetFunctions, que só funciona com funções nomeadas de nível raiz, o modo comment permite proteger qualquer função em qualquer lugar do seu código.
vmForceCompileDynamicCode
Type: boolean Default: false
Controla o que a ofuscação VM faz com uma função que contém uma chamada direta a eval, new Function(...) ou Function(...).
Por padrão, essa função (e toda função definida dentro dela) é ignorada na conversão para bytecode da VM e um aviso VMDynamicCodeSkipped é reportado em result.getWarnings(). Isso ocorre porque o código-fonte construído em tempo de execução pode referenciar identificadores da cadeia de escopos ao redor — identificadores que o ofuscador renomeou.
Quando definido como true, a função é convertida em bytecode de qualquer forma e o aviso VMDynamicCodeSkipped deixa de ser emitido.
O aviso separado DynamicCodeRenameRisk continua sendo disparado independentemente desta opção, porque o risco de renomeação que ele descreve é independente da exclusão da VM — ativar esta opção não torna o padrão subjacente mais seguro.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
Com a opção desativada (padrão), loadConfig é deixada como JavaScript puro. Com a opção ativada, loadConfig é compilada em bytecode da VM como qualquer outra função. Use isto quando você tiver auditado o local da chamada e souber que o código construído em tempo de execução não depende de identificadores renomeados por closure.
vmWrapTopLevelInitializers
Type: boolean Default: false
Envolve alguns inicializadores de variáveis de nível superior em IIFEs (Immediately Invoked Function Expressions) para que possam ser ofuscados por VM.
O que ela faz: Sem esta opção, constantes e variáveis de nível superior permanecem visíveis na saída:
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
Com esta opção ativada, o inicializador é envolvido em uma IIFE que é ofuscada por VM:
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Nota: Esta opção só funciona quando vmTargetFunctionsMode é 'root' (o padrão).
Avisos: Sempre que um inicializador de nível superior acaba em JavaScript puro sob a ofuscação VM, um aviso VMTopLevelInitializerNotVirtualized listando os nomes das variáveis afetadas é reportado. Isso abrange: esta opção estar desativada, inicializadores que esta opção teve que ignorar (cada um com o motivo — por exemplo, o inicializador referencia um declarador irmão ou contém um await de nível superior) e o modo vmAsyncExecutor, no qual os wrappers síncronos não podem ser virtualizados de forma alguma.
vmDynamicOpcodes
Type: boolean Default: false
Torna o interpretador da VM menor e único para cada build.
O que ela faz:
- Filtra instruções não utilizadas - Se o seu código não usa classes, as instruções relacionadas a classes são removidas por completo
- Aleatoriza a estrutura - A ordem dos handlers de instrução é embaralhada a cada build
Como resultado - saída menor e cada build com aparência diferente.
vmBytecodeEncoding
Type: boolean Default: false
Codifica cada instrução de bytecode. As instruções são decodificadas uma de cada vez durante a execução.
vmBytecodeArrayEncoding
Type: boolean Default: false
Codifica o array de bytecode inteiro como um único bloco. O array é decodificado uma única vez na inicialização, antes de a execução começar. Use em conjunto com vmBytecodeEncoding para duas camadas de proteção.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Chave de criptografia personalizada para a codificação do array de bytecode. Quando definida, esta chave é usada em vez da chave padrão derivada do ambiente. A chave deve ser fornecida em tempo de execução por meio de vmBytecodeArrayEncodingKeyGetter.
Esta opção externaliza a chave de criptografia - ela não fica embutida no próprio código ofuscado. Embora a chave ainda seja acessível em tempo de execução (e, portanto, não seja verdadeiramente secreta), essa separação impede que ferramentas de análise estática encontrem a chave apenas examinando o código.
Importante: A chave deve estar disponível de forma síncrona quando o código ofuscado é carregado. Use armazenamento síncrono, como cookies, localStorage, sessionStorage, variáveis globais ou elementos do DOM (por exemplo, meta tags injetadas pelo servidor). Métodos assíncronos como fetch() não podem ser usados diretamente na expressão do getter da chave.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Expressão JavaScript síncrona que retorna a chave de criptografia em tempo de execução. Esta expressão é avaliada quando o código ofuscado é carregado e deve retornar a mesma chave que foi fornecida em vmBytecodeArrayEncodingKey. Para resolver a chave de forma assíncrona (uma Promise), ative vmAsyncExecutor.
Nota: um getter que retorna uma Promise requer vmAsyncExecutor. Isso não pode ser verificado em tempo de build, então um getter que retorna uma Promise com vmAsyncExecutor desativado falha em tempo de execução — o decodificador recebe a Promise em vez da chave.
O código ofuscado só funcionará quando o getter da chave retornar exatamente a mesma chave que foi usada durante a ofuscação. Se as chaves não corresponderem, a descriptografia falhará e o código produzirá lixo ou erros. Se o getter da chave retornar undefined, null ou uma string vazia, o código lançará um erro: "VM decryption key not available".
Importante: Mantenha a chave fora do mesmo arquivo/script do código ofuscado — colocá-la inline ali permite que até mesmo uma varredura puramente estática do bundle a recupere. Em vez disso, armazene-a em uma fonte separada: cookies definidos pelo servidor, localStorage populado por outro script, uma meta tag HTML injetada pelo servidor, um global definido por outro script ou (com vmAsyncExecutor) buscada no seu backend em tempo de execução.
Quando a chave é buscada no seu backend (via vmAsyncExecutor), adicione verificações baseadas em sessão ou origem nesse endpoint: retorne a chave correta para usuários reais (sessão válida, Origin/Referer esperados) e uma chave inválida para requisições suspeitas (por exemplo, uma origem localhost/inesperada, sem sessão). Usuários reais rodam normalmente; uma cópia rodando fora do seu ambiente recebe uma chave que descriptografa para nada. A lógica exata depende do seu site.
Exemplos:
// 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())'
Exemplo de uso:
// 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
Ativa o executor assíncrono da VM, que permite que vmBytecodeArrayEncodingKeyGetter retorne uma Promise (um getter de chave assíncrono) — assim, a chave de descriptografia pode ser buscada em tempo de execução (requisição de rede, IndexedDB, etc.) em vez de precisar estar disponível de forma síncrona quando o código é carregado.
Fortemente recomendado para bases de código totalmente assíncronas. Neste modo, apenas funções async são virtualizadas — uma função síncrona não pode ser transformada em assíncrona sem transformar seu valor de retorno em uma Promise e quebrar quem a chama — então código que é async de ponta a ponta obtém a maior cobertura. Ainda funciona quando a raiz é síncrona (por exemplo, uma IIFE síncrona / wrapper UMD): as funções async mais externas de dentro são protegidas, e as partes síncronas são deixadas como estão.
O que é transformado: cada função async mais externa, onde quer que apareça (inclusive aninhada dentro de wrappers síncronos). A função async mais externa de cada cadeia é a unidade protegida — tudo dentro dela, síncrono e assíncrono, é compilado junto. Funções síncronas e geradores comuns são deixados sem ofuscação.
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
}
}
Exclusões e avisos. Geradores assíncronos também são deixados sem ofuscação quando um getter de chave assíncrono está ativo (um gerador assíncrono deve retornar seu iterador de forma síncrona e não pode esperar pela chave). No modo padrão vmTargetFunctionsMode: 'root', as exclusões são silenciosas (a seleção é automática); no modo comment, um aviso é emitido por meio de ObfuscationResult.getWarnings() sempre que uma função que você marcou explicitamente não pode ser virtualizada — ela se mostrou síncrona ou é um gerador assíncrono sob um getter de chave assíncrono.
O getter de chave assíncrono requer adicionalmente vmBytecodeArrayEncoding com um vmBytecodeArrayEncodingKeyGetter.
Exemplo de uso:
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
Codifica os alvos de salto no bytecode. Os offsets de salto são calculados em tempo de execução, ocultando a estrutura do fluxo de controle (if/else, loops, etc.) da análise estática.
vmMacroOps
Type: boolean Default: false
Combina sequências comuns de instruções em opcodes "macro" únicos. Por exemplo, LOAD + ADD + STORE pode se tornar uma única instrução MACRO_ADD_TO_VAR. Isso quebra o reconhecimento de padrões e pode melhorar o desempenho.
vmDebugProtection
Type: boolean Default: false
Adiciona defesas antidepuração, antianálise e anti-LLM em múltiplas camadas ao runtime da VM. Funciona melhor com os alvos browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Adiciona proteção em múltiplas camadas contra adulteração, contra hooks e contra engenharia reversa ao runtime da VM.
⚠️ Esta opção ativa forçadamente vmBytecodeArrayEncoding.
⚠️ Detecção de ambiente sensível. Esta opção vincula o código ofuscado ao seu ambiente de execução de destino e usa fingerprinting avançado de navegador para detectar ferramentas de automação. O código protegido com esta opção vai quebrar intencionalmente quando executado em:
- Navegadores headless (Chrome/Chromium headless, PhantomJS)
- Ferramentas de automação de navegador (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (quando
targetestá definido comobrowser) - jsdom ou emulações de DOM do lado do servidor semelhantes
- Ambientes em que os builtins nativos do navegador foram interceptados por hooks ou substituídos
O código funcionará corretamente em navegadores comuns (Chrome, Firefox, Safari, Edge), inclusive quando carregado dentro de iframes, extensões de navegador (content scripts) e Web Workers. Se você precisar executar testes automatizados contra código protegido, desative vmSelfDefending para os builds de teste — esta opção foi projetada para impedir a análise automatizada e não pode ser usada com segurança com nenhum framework de automação.
Fortemente recomendado usar em conjunto com vmDebugProtection, vmBytecodeArrayEncodingKey e vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook recebe um objeto com duas chaves: name (obrigatória) e aliases (opcional).
name é uma função global definida pela sua página host que uma defesa da VM (vmDebugProtection / vmSelfDefending) chama com um objeto de sinal quando detecta um sinal hostil — um depurador ou inspetor, um navegador headless / de automação, um processo de agente de codificação de IA, um domínio não permitido e assim por diante. Use-a para reportar o evento ao seu backend (por exemplo, navigator.sendBeacon). O hook é um coletor de telemetria puro: seu valor de retorno é ignorado, e um hook ausente ou que lança erro é um no-op silencioso que nunca pode desativar uma defesa. Para mudar o que uma defesa faz na detecção, use vmDefenseReaction.
aliases opcionalmente renomeia os campos desse objeto de sinal — abordado em Renomeando os campos do sinal abaixo.
O objeto de sinal. O hook recebe um único signal:
source— o detector específico que disparou (veja a tabela).category— o grupo sob o qual ele reporta:automation(navegadores não humanos),debugger(um depurador/inspetor está ativo),sandbox(host instrumentado/falso),domain(violação de bloqueio de domínio),tamper(builtins alterados em tempo de execução) ouintegrity(o próprio código da VM foi alterado).score/threshold— a intensidade com que o detector disparou e o valor que ele precisava atingir; o hook dispara apenas quandoscore >= threshold. A maioria das verificações é tudo-ou-nada (um único sinal decisivo);headlesssoma vários sinais de forma do navegador, então seuscorecostuma ser maior que seuthreshold.
Registrando o hook. Defina-o como um global comum antes de o bundle ofuscado carregar — o runtime da VM e suas defesas rodam antes do seu programa (protegido), então muitas detecções disparam durante a inicialização:
// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }
Um hook definido dentro do código-fonte ofuscado é registrado tarde demais para capturar detecções em tempo de inicialização e, se for compilado pela VM, não pode ser alcançado até que seu programa rode. Ele é mantido seguro de qualquer forma (um hook ausente é um no-op, e um guard de reentrância impede qualquer descontrole), mas, para cobertura completa, registre-o antecipadamente. Para ainda proteger sua lógica de reporte, mantenha o hook registrado como um buffer de uma linha ((window.__vmDet = window.__vmDet || []).push(signal)) e leia/envie esse buffer a partir do seu código ofuscado.
Renomeando os campos do sinal (aliases). Os valores padrão de source/category são nomes descritivos, então qualquer um que instrumente o callback (ou leia a saída) pode reconhecer a proteção e qual detector disparou. aliases renomeia os campos do sinal para tokens opacos de sua escolha, aplicados dentro da VM antes de o sinal ser emitido, então esses nomes nunca aparecem na saída nem chegam ao callback. Sua aplicação conhece seu próprio mapeamento e encaminha os tokens ao seu backend.
Os aliases são por campo, mantendo separadas as renomeações de chave e de valor: cada campo recebe uma key (o nome da propriedade que o callback recebe); os campos de nome do tipo string source e category também recebem um mapa values, enquanto score/threshold são números e recebem apenas uma key. Os nomes que você pode mapear (qualquer outro é rejeitado em tempo de build):
- chaves de campo —
source,category,score,threshold - valores de
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - valores de
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> }
}
Isto é evasão de fingerprint, não segredo — o mapeamento ainda pode ser inferido por testes repetidos — então seu único benefício é não expor nomes estáveis e autoexplicativos. Entradas não definidas mantêm seus nomes padrão.
Uma string simples (vmDefenseHook: '__vmDetection') é aceita como forma abreviada de { name: '__vmDetection' }, mas está obsoleta — prefira a forma de objeto.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Configura como cada categoria de detecção reage. Ela não ativa nada — as próprias defesas são ligadas por vmSelfDefending, vmDebugProtection e vmDomainLock; esta opção apenas seleciona como uma defesa já ativada reage. A categoria é a unidade de controle — cada detector de uma categoria executa a reação daquela categoria.
Cada categoria agrupa os detectores que observam um tipo de condição hostil. Uma categoria só reage quando a opção que emite seus detectores está ativada:
Cada categoria mapeia para uma ou mais das opções vmSelfDefending, vmDebugProtection e vmDomainLock; não existe categoria fora dessas três opções, e uma reação definida para uma categoria cuja opção está desativada simplesmente não tem efeito.
As chaves são esses seis nomes de categoria, ou default (um fallback para categorias não especificadas). Os valores são:
break— quebra imediatamentedecoy— continua rodando em estado envenenado, produzindo silenciosamente resultados erradosnone— não faz nada localmente (apenas telemetria)
Os padrões por categoria são mostrados acima; uma categoria que você não define (ou define com seu valor padrão) usa esse padrão. default alcança todas as categorias, inclusive as corretas por construção (integrity, tamper), então { default: 'none' } é um build genuinamente não destrutivo, apenas de telemetria:
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
Faz o significado dos opcodes depender da posição no bytecode. Cada posição tem um mapeamento de opcode para handler diferente, derivado de uma semente, então o mesmo número de opcode realiza operações diferentes em posições diferentes.
vmCallContextOpcodes
Type: boolean Default: false
Faz uma função protegida depender de onde ela é chamada, de modo que não possa ser extraída do código e executada ou analisada isoladamente — ela só se comporta corretamente quando invocada por meio de seus locais de chamada reais no programa. Esta opção afeta o desempenho em tempo de execução.
Atualmente, apenas as seguintes construções têm suporte:
- declarações de função (
function f() {}); - expressões de função e arrow functions atribuídas a uma variável (
const f = () => {}); - métodos privados de instância (
this.#m()).
Em todos os casos, a função deve sempre ser alcançada por uma chamada direta (f(), this.#m()). Se ela for armazenada em outra variável, passada como argumento ou usada de outra forma como valor, fica sem proteção. Funções assíncronas têm suporte; geradores não.
Esta opção é experimental e pode quebrar seu código, então teste a saída minuciosamente antes de usá-la.
vmStackEncoding
Type: boolean Default: false
Criptografa os valores na pilha da VM durante a execução. Os valores são codificados ao serem empilhados e decodificados ao serem desempilhados, então a inspeção de memória mostra dados criptografados em vez dos valores reais.
Esta opção afeta fortemente o desempenho.
vmCompactDispatcher
Type: boolean Default: false
Usa um único executor de VM em vez de executores duais (síncrono + gerador). Reduz o tamanho do código ofuscado, mas adiciona cerca de 20% de sobrecarga de desempenho em código com muita recursão.
false(padrão): executores duais — desempenho ótimo, saída maiortrue: executor único — saída menor, ligeiramente mais lento
vmStringArrayBytecodeOnly
Type: boolean Default: false
Quando ativada, o array de strings apenas extrairá strings dos dados de bytecode — nenhuma outra string no código é transformada. Isso ativa forçadamente stringArray mesmo que não esteja explicitamente definido.
Por que usar isto: Extrair todas as strings de runtime da VM para um array de strings é lento. Esta opção mira apenas o conteúdo de bytecode para a extração do array de strings, melhorando o desempenho enquanto ainda protege as constantes do bytecode.
- Quando
vmBytecodeArrayEncoding: false— strings dentro dos pools de constantes do bytecode (arraysc) são extraídas - Quando
vmBytecodeArrayEncoding: true— strings de bytecode de nível superior codificadas em base64 são extraídas stringArrayThresholdainda controla qual porcentagem dessas strings de bytecode é extraída
vmDomainLock
Type: string[] Default: []
⚠️ Esta opção não funciona com target: 'node', target: 'service-worker' ou target: 'bytenode'
Restringe o código ofuscado a domínios e/ou subdomínios específicos, e é muito mais difícil de localizar e remover do que domainLock.
Se o código-fonte não for executado nos domínios especificados por esta opção, o navegador será redirecionado para a URL passada a vmDomainLockRedirectUrl, e as demais chamadas protegidas retornarão resultados incorretos mesmo que o redirecionamento seja suprimido.
Múltiplos domínios e subdomínios
É possível restringir seu código a mais de um domínio ou subdomínio. Por exemplo, para restringi-lo de modo que o código só rode em www.example.com, adicione www.example.com. Para que funcione no domínio raiz incluindo quaisquer subdomínios (example.com, sub.example.com), use .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Esta opção não funciona com target: 'node', target: 'service-worker' ou target: 'bytenode'
Permite que o navegador seja redirecionado para uma URL passada caso o código-fonte não seja executado nos domínios especificados por vmDomainLock.
Preset Options
Ofuscação alta, baixo desempenho
O desempenho será muito mais lento do que sem ofuscação
{
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
}
Ofuscação média, desempenho ótimo
O desempenho será mais lento do que sem ofuscação
{
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
}
Ofuscação baixa, alto desempenho
O desempenho ficará em um nível relativamente normal
{
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
}
Predefinição padrão, alto desempenho
{
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
}
Ofuscação VM Ultra High (Segurança Máxima)
Esta predefinição ativa a ofuscação por bytecode baseada em VM com todos os recursos de blindagem, incluindo dispatch indireto. Oferece a proteção mais forte, mas com tamanho de saída maior e execução muito mais lenta.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Ou configure individualmente:
{
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 (Proteção contra Agentes de IA)
Esta predefinição foi projetada especificamente para impedir que agentes de IA e LLMs façam engenharia reversa de código convertido em bytecode de VM. Baseada em vm-default com self-defending e proteção contra depuração ativados. Mais leve que vm-high-obfuscation, mas especificamente blindada contra análise automatizada.
{
optionsPreset: 'vm-anti-llm'
}
Inclui:
- Ofuscação por bytecode da VM com array de strings (de
vm-default) vmSelfDefending— detecção anti-hook, hash de integridade, fingerprint do código-fonte, verificação de realm limpo por iframe, derivação de chave com cifra ARXvmDebugProtection— verificações antidepuração no loop de dispatch da VMdebugProtection: false— sem a proteção contra depuração legada (a proteção contra depuração da VM é superior)
Ofuscação VM High (Segurança Mais Alta)
Esta predefinição ativa a ofuscação por bytecode baseada em VM com a maioria dos recursos de blindagem. Oferece proteção forte com melhor desempenho do que a predefinição ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Ou configure individualmente:
{
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
}
Ofuscação VM Medium (Segurança Equilibrada)
Esta predefinição ativa a ofuscação por bytecode baseada em VM com um conjunto equilibrado de recursos de blindagem. Bom compromisso entre segurança e desempenho.
{
optionsPreset: 'vm-medium-obfuscation'
}
Ou configure individualmente:
{
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
}
Ofuscação VM Low (Segurança Básica, Melhor Desempenho)
Esta predefinição ativa a ofuscação básica por bytecode baseada em VM sem recursos adicionais de blindagem. Bom equilíbrio entre segurança e tamanho de saída.
{
optionsPreset: 'vm-low-obfuscation'
}
Ou configure individualmente:
{
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 + Proteção de Array de Strings)
Esta predefinição combina a ofuscação básica por bytecode baseada em VM com a proteção de array de strings. Bom ponto de partida para a ofuscação VM com proteção de strings.
{
optionsPreset: 'vm-default'
}
Ou configure individualmente:
{
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
Compacta a saída do código em uma única linha.
config
Type: string Default: ``
Nome do arquivo de configuração JS/JSON que contém as opções do ofuscador. Elas serão sobrescritas pelas opções passadas diretamente pela CLI
controlFlowFlattening
Type: boolean Default: false
⚠️ Esta opção afeta muito o desempenho, tornando a execução até 1,5x mais lenta. Use controlFlowFlatteningThreshold para definir a porcentagem de nós que serão afetados pelo achatamento do fluxo de controle.
Ativa o achatamento do fluxo de controle do código. O achatamento do fluxo de controle é uma transformação da estrutura do código-fonte que dificulta a compreensão do programa.
Exemplo:
// 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
A probabilidade de que a transformação controlFlowFlattening seja aplicada a um determinado nó.
Esta configuração é especialmente útil para códigos grandes, pois grandes quantidades de transformações de fluxo de controle podem deixar seu código mais lento e aumentar seu tamanho.
controlFlowFlatteningThreshold: 0 equivale a controlFlowFlattening: false.
deadCodeInjection
Type: boolean Default: false
⚠️ Aumenta drasticamente o tamanho do código ofuscado (até 200%); use apenas se o tamanho do código ofuscado não importar. Use deadCodeInjectionThreshold para definir a porcentagem de nós que serão afetados pela injeção de código morto.
⚠️ Esta opção ativa forçadamente a opção stringArray.
⚠️ Esta opção é silenciosamente desativada quando vmObfuscation está ativado.
Com esta opção, blocos aleatórios de código morto serão adicionados ao código ofuscado.
Exemplo:
// 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
Permite definir a porcentagem de nós que serão afetados por deadCodeInjection.
debugProtection
Type: boolean Default: false
⚠️ Pode travar seu navegador se você abrir as Ferramentas de Desenvolvedor.
⚠️ Esta opção é silenciosamente desativada quando vmObfuscation está ativado. Use vmDebugProtection em seu lugar.
Esta opção torna praticamente impossível usar a função debugger das Ferramentas de Desenvolvedor (tanto em navegadores baseados em WebKit quanto no Mozilla Firefox).
debugProtectionInterval
Type: number Default: 0
⚠️ Pode travar seu navegador! Use por sua conta e risco.
⚠️ Esta opção é silenciosamente desativada quando vmObfuscation está ativado. Use vmDebugProtection em seu lugar.
Se definido, um intervalo em milissegundos é usado para forçar o modo de depuração na aba Console, dificultando o uso de outros recursos das Ferramentas de Desenvolvedor. Funciona se debugProtection estiver ativado. O valor recomendado fica entre 2000 e 4000 milissegundos.
disableConsoleOutput
Type: boolean Default: false
⚠️ Esta opção desativa as chamadas de console globalmente para todos os scripts
Desativa o uso de console.log, console.info, console.error, console.warn, console.debug, console.exception e console.trace substituindo-os por funções vazias. Isso dificulta o uso do depurador.
domainLock
Type: string[] Default: []
⚠️ Esta opção não funciona com target: 'node', target: 'service-worker' ou target: 'bytenode'
Permite executar o código-fonte ofuscado apenas em domínios e/ou subdomínios específicos. Isso torna realmente difícil que alguém simplesmente copie e cole seu código-fonte e o execute em outro lugar.
Se o código-fonte não for executado nos domínios especificados por esta opção, o navegador será redirecionado para a URL passada à opção domainLockRedirectUrl.
Múltiplos domínios e subdomínios
É possível restringir seu código a mais de um domínio ou subdomínio. Por exemplo, para restringi-lo de modo que o código só rode em www.example.com, adicione www.example.com. Para que funcione no domínio raiz incluindo quaisquer subdomínios (example.com, sub.example.com), use .example.com.
domainLockRedirectUrl
Type: string Default: about:blank
⚠️ Esta opção não funciona com target: 'node', target: 'service-worker' ou target: 'bytenode'
Permite que o navegador seja redirecionado para uma URL passada caso o código-fonte não seja executado nos domínios especificados por domainLock.
exclude
Type: string[] Default: []
Nomes de arquivos ou globs que indicam os arquivos a serem excluídos da ofuscação.
forceTransformStrings
Type: string[] Default: []
Ativa a transformação forçada dos literais de string que correspondam aos padrões RegExp passados.
⚠️ Esta opção afeta apenas as strings que não deveriam ser transformadas por stringArrayThreshold (ou possivelmente outros thresholds no futuro)
A opção tem prioridade sobre a opção reservedStrings, mas não tem prioridade sobre os conditional comments.
Exemplo:
{
forceTransformStrings: [
'some-important-value',
'some-string_\d'
]
}
identifierNamesCache
Type: Object | null Default: null
O principal objetivo desta opção é a capacidade de usar os mesmos nomes de identificadores durante a ofuscação de múltiplos códigos-fonte/arquivos.
Atualmente, há suporte para dois tipos de identificadores:
- Identificadores globais:
- Todos os identificadores globais serão escritos no cache;
- Todos os identificadores globais não declarados que corresponderem serão substituídos pelos valores do cache.
- Identificadores de propriedades, apenas quando a opção
renamePropertiesestá ativada:- Todos os identificadores de propriedades serão escritos no cache;
- Todos os identificadores de propriedades que corresponderem serão substituídos pelos valores do cache.
API do Node.js
Se um valor null for passado, o cache é completamente desativado.
Se um objeto vazio ({}) for passado, ativa a escrita dos nomes de identificadores no objeto de cache (tipo TIdentifierNamesCache). Esse objeto de cache será acessado por meio da chamada do método getIdentifierNamesCache do objeto ObfuscationResult.
O objeto de cache resultante pode ser usado em seguida como valor da opção identifierNamesGenerator para usar esses nomes durante a ofuscação de todos os nomes de identificadores correspondentes dos próximos códigos-fonte.
Exemplo:
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
A CLI tem uma opção diferente, --identifier-names-cache-path, que permite definir um caminho para o arquivo .json existente que será usado para ler e escrever o cache de nomes de identificadores.
Se um caminho para um arquivo vazio for passado, o cache de nomes de identificadores será escrito nesse arquivo.
Esse arquivo com o cache existente pode ser reutilizado como valor da opção --identifier-names-cache-path para usar esses nomes durante a ofuscação de todos os nomes de identificadores correspondentes dos próximos arquivos.
identifierNamesGenerator
Type: string Default: hexadecimal
Define o gerador de nomes de identificadores.
Valores disponíveis:
dictionary: nomes de identificadores da listaidentifiersDictionaryhexadecimal: nomes de identificadores como_0xabc123mangled: nomes de identificadores curtos comoa,b,cmangled-shuffled: igual amangled, mas com o alfabeto embaralhado
identifiersDictionary
Type: string[] Default: []
Define o dicionário de identificadores para identifierNamesGenerator: opção dictionary. Cada identificador do dicionário será usado em algumas variações com diferentes combinações de maiúsculas e minúsculas de cada caractere. Assim, a quantidade de identificadores no dicionário deve depender da quantidade de identificadores no código-fonte original.
identifiersPrefix
Type: string Default: ''
Define um prefixo para todos os identificadores globais.
Use esta opção quando quiser ofuscar múltiplos arquivos. Ela ajuda a evitar conflitos entre os identificadores globais desses arquivos. O prefixo deve ser diferente para cada arquivo.
randomIdentifiersPrefix
Type: boolean Default: false
Acrescenta um prefixo aleatório com semente (6 caracteres alfanuméricos) a todos os identificadores globais. Use esta opção para evitar colisões entre bundles ofuscados separadamente que são carregados no mesmo escopo global — ela elimina a necessidade de escolher manualmente um identifiersPrefix único para cada bundle.
- O valor aleatório é derivado da opção
seede do hash do código-fonte, então builds reproduzíveis com a mesma semente produzem o mesmo prefixo. - Quando combinado com
identifiersPrefix, os caracteres aleatórios são acrescentados ao prefixo fornecido pelo usuário (por exemplo,myApp+ aleatórioaBc123→myAppaBc123). - Quando combinado com
vmObfuscation, o valor aleatório substitui o prefixo padrãovm— a aleatoriedade já garante a unicidade.
ignoreImports
Type: boolean Default: false
Impede a ofuscação de imports require. Pode ser útil em alguns casos quando, por algum motivo, o ambiente de execução exige esses imports apenas com strings estáticas.
inputFileName
Type: string Default: ''
Permite definir o nome do arquivo de entrada com o código-fonte. Esse nome será usado internamente para a geração do source map.
Obrigatório ao usar a API do NodeJS e quando a opção sourceMapSourcesMode tem o valor sources.
log
Type: boolean Default: false
Ativa o registro de informações no console.
numbersToExpressions
Type: boolean Default: false
Ativa a conversão de números em expressões
Exemplo:
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
optionsPreset
Type: string Default: default
Permite definir uma predefinição de opções.
Valores disponíveis:
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.
Todas as opções adicionais serão mescladas com a predefinição de opções selecionada.
parseHtml
Type: boolean Default: false
Ativa a ofuscação de JavaScript dentro de tags <script> de HTML.
Quando ativada, o ofuscador irá:
- Detectar automaticamente se a entrada é HTML (verificando as tags
<!DOCTYPE,<html>,<head>,<body>ou<script>) - Extrair o JavaScript das tags
<script>marcadas com o atributodata-javascript-obfuscator - Ofuscar cada script marcado individualmente, preservando a estrutura do HTML
- Injetar o código ofuscado de volta nas posições originais
Importante: Apenas os scripts com o atributo data-javascript-obfuscator são ofuscados. Cada script marcado é ofuscado de forma individual e independente. Isso significa que:
- O código dentro das tags de script marcadas deve estar isolado - ele NÃO pode referenciar variáveis, funções ou classes definidas em outras tags de script marcadas
- Scripts não marcados ainda podem acessar globais definidos por scripts marcados (por meio de declarações
varou atribuições explícitas aglobalThis) - Isso dá a você controle explícito sobre quais scripts proteger
Ofuscados (devem ter o atributo data-javascript-obfuscator):
<script data-javascript-obfuscator>- scripts comuns<script type="text/javascript" data-javascript-obfuscator>- scripts com tipo explícito- Scripts com quaisquer atributos adicionais (
id,class, outrosdata-*, etc.)
Ignorados (mantidos inalterados):
- Scripts sem o atributo
data-javascript-obfuscator <script type="module">- módulos ES (mesmo com o atributo)<script src="...">- scripts externos (mesmo com o atributo)- Tags de script vazias
Nota: Os source maps não são gerados quando parseHtml está ativado, pois não mapeariam corretamente para a saída em HTML.
Exemplo:
// 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
⚠️ esta opção pode quebrar seu código. Ative-a apenas se você souber o que ela faz!
Ativa a ofuscação de nomes de variáveis e funções globais com declaração.
Quando esta opção está desativada e o código de entrada declara funções ou classes no escopo global (ou seja, o código não está envolvido em uma IIFE), seus nomes são mantidos como estão na saída ofuscada — outros scripts podem referenciá-los pelo nome. Sob vmObfuscation, um aviso VMGlobalFunctionNamesNotRenamed listando esses nomes é reportado, já que o corpo da função fica oculto como bytecode, mas o nome legível de nível superior ainda revela o que o código faz (por exemplo, para uma LLM). Para evitar essa exposição, envolva o código em uma IIFE ou ative esta opção.
renameProperties
Type: boolean Default: false
⚠️ esta opção PODE quebrar seu código. Ative-a apenas se você souber o que ela faz!
Ativa a renomeação de nomes de propriedades. Todas as propriedades DOM nativas e as propriedades das classes principais do JavaScript serão ignoradas.
Para alternar entre os modos safe e unsafe desta opção, use a opção renamePropertiesMode.
Para definir o formato dos nomes de propriedades renomeados, use a opção identifierNamesGenerator.
Para controlar quais propriedades serão renomeadas, use a opção reservedNames.
Exemplo:
// 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
⚠️ Mesmo no modo safe, a opção renameProperties PODE quebrar seu código.
Especifica o modo da opção renameProperties:
safe- comportamento padrão após a versão2.11.0. Tenta renomear propriedades de forma mais segura para evitar erros em tempo de execução. Com este modo, algumas propriedades serão excluídas da renomeação.unsafe- comportamento padrão antes da versão2.11.0. Renomeia as propriedades de forma insegura, sem quaisquer restrições.
Se um arquivo estiver usando propriedades de outro arquivo, use a opção identifierNamesCache para manter os mesmos nomes de propriedades entre esses arquivos.
reservedNames
Type: string[] Default: []
Desativa a ofuscação e a geração de identificadores que correspondam aos padrões RegExp passados.
Exemplo:
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
reservedStrings
Type: string[] Default: []
Desativa a transformação dos literais de string que correspondam aos padrões RegExp passados. As strings correspondentes permanecerão visíveis na saída ofuscada.
Ao usar a ofuscação VM, as strings reservadas são armazenadas em um array separado e não criptografado para mantê-las visíveis. Isso é útil para strings que precisam permanecer legíveis, como endpoints de API para monitoramento ou identificadores de bibliotecas.
Exemplo:
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
seed
Type: string|number Default: 0
Esta opção define a semente (seed) do gerador aleatório. Isso é útil para criar resultados reproduzíveis.
Se a semente for 0, o gerador aleatório funcionará sem semente.
selfDefending
Type: boolean Default: false
⚠️ Não altere o código ofuscado de forma alguma após a ofuscação com esta opção, pois qualquer alteração, como a minificação do código, pode acionar a autodefesa e o código deixará de funcionar!
⚠️ Esta opção define forçadamente o valor de compact como true
⚠️ Esta opção é silenciosamente desativada quando vmObfuscation está ativado. Use vmSelfDefending em seu lugar.
Esta opção torna o código de saída resistente à formatação e à renomeação de variáveis. Se alguém tentar usar um beautifier de JavaScript no código ofuscado, o código deixará de funcionar, tornando-o mais difícil de entender e modificar.
simplify
Type: boolean Default: true
Ativa ofuscação adicional do código por meio de simplificação.
⚠️ em versões futuras, a ofuscação de literais boolean (true => !![]) será movida para esta opção.
Exemplo:
// 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
Ativa a geração de source map para o código ofuscado.
Os source maps podem ser úteis para ajudar você a depurar seu código-fonte JavaScript ofuscado. Se você quiser ou precisar depurar em produção, pode enviar o arquivo separado de source map para um local secreto e apontar seu navegador para lá.
sourceMapBaseUrl
Type: string Default: ``
Define a URL base da URL de import do source map quando sourceMapMode: 'separate'.
Exemplo de CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
Resultado:
//# sourceMappingURL=http://localhost:9000/out.js.map
sourceMapFileName
Type: string Default: ``
Define o nome do arquivo do source map de saída quando sourceMapMode: 'separate'.
Exemplo de CLI:
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000' --source-map-file-name example
Resultado:
//# sourceMappingURL=http://localhost:9000/example.js.map
sourceMapMode
Type: string Default: separate
Especifica o modo de geração do source map:
inline- adiciona o source map ao final de cada arquivo .js;separate- gera o arquivo '.map' correspondente com o source map. Caso você execute o ofuscador pela CLI, adiciona ao final do arquivo com o código ofuscado o link para o arquivo de source map//# sourceMappingUrl=file.js.map.
sourceMapSourcesMode
Type: string Default: sources-content
Permite controlar os campos sources e sourcesContent do source map:
sources-content- adiciona um camposourcesfictício e adiciona o camposourcesContentcom o código-fonte original;sources- adiciona o camposourcescom uma descrição de fonte válida e não adiciona o camposourcesContent. Ao usar a API do NodeJS, é necessário definir a opçãoinputFileName, que será usada como valor do camposources.
splitStrings
Type: boolean Default: false
Divide os literais de string em partes com o comprimento definido pelo valor da opção splitStringsChunkLength.
Exemplo:
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
splitStringsChunkLength
Type: number Default: 10
Define o comprimento das partes da opção splitStrings.
stringArray
Type: boolean Default: true
Remove os literais de string e os coloca em um array especial. Por exemplo, a string "Hello World" em var m = "Hello World"; será substituída por algo como var m = _0x12c456[0x1];
stringArrayCallsTransform
Type: boolean Default: false
⚠️ a opção stringArray deve estar ativada
Ativa a transformação das chamadas ao stringArray. Todos os argumentos dessas chamadas podem ser extraídos para um objeto diferente dependendo do valor de stringArrayCallsTransformThreshold.
Assim, fica ainda mais difícil encontrar automaticamente as chamadas ao array de strings.
Exemplo:
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
⚠️ as opções stringArray e stringArrayCallsTransformThreshold devem estar ativadas
Você pode usar esta configuração para ajustar a probabilidade (de 0 a 1) de que as chamadas ao array de strings sejam transformadas.
stringArrayEncoding
Type: string[] Default: []
⚠️ a opção stringArray deve estar ativada
Esta opção pode deixar seu script mais lento.
Codifica todos os literais de string do stringArray usando base64 ou rc4 e insere um código especial usado para decodificá-los de volta em tempo de execução.
Cada valor do stringArray será codificado pela codificação escolhida aleatoriamente na lista passada. Isso possibilita usar múltiplas codificações.
Valores disponíveis:
'none'(boolean): não codifica o valor dostringArray'base64'(string): codifica o valor dostringArrayusandobase64'rc4'(string): codifica o valor dostringArrayusandorc4. Cerca de 30-50% mais lento quebase64, mas dificulta mais a obtenção dos valores iniciais.
Por exemplo, com os seguintes valores de opção, alguns valores do stringArray não serão codificados, e outros valores serão codificados com as codificações base64 e rc4:
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
stringArrayIndexesType
Type: string[] Default: ['hexadecimal-number']
⚠️ a opção stringArray deve estar ativada
Permite controlar o tipo dos índices de chamada ao array de strings.
Cada índice de chamada ao stringArray será transformado pelo tipo escolhido aleatoriamente na lista passada. Isso possibilita usar múltiplos tipos.
Valores disponíveis:
'hexadecimal-number'(default): transforma os índices de chamada ao array de strings como números hexadecimais'hexadecimal-numeric-string': transforma os índices de chamada ao array de strings como strings numéricas hexadecimais
Antes da versão 2.9.0, o javascript-obfuscator transformava todos os índices de chamada ao array de strings com o tipo hexadecimal-numeric-string. Isso torna alguma desofuscação manual um pouco mais difícil, mas permite a fácil detecção dessas chamadas por desofuscadores automáticos.
O novo tipo hexadecimal-number busca dificultar a autodetecção de padrões de chamada ao array de strings no código.
Mais tipos serão adicionados no futuro.
stringArrayIndexShift
Type: boolean Default: true
⚠️ a opção stringArray deve estar ativada
Ativa o deslocamento adicional de índice para todas as chamadas ao array de strings
stringArrayRotate
Type: boolean Default: true
⚠️ stringArray deve estar ativado
Desloca o array stringArray por um número de posições fixo e aleatório (gerado na ofuscação do código). Isso dificulta associar a ordem das strings removidas ao seu local original.
stringArrayShuffle
Type: boolean Default: true
⚠️ stringArray deve estar ativado
Embaralha aleatoriamente os itens do array stringArray.
stringArrayWrappersCount
Type: number Default: 1
⚠️ a opção stringArray deve estar ativada
Define a quantidade de wrappers para o string array dentro de cada escopo raiz ou de função.
A quantidade real de wrappers dentro de cada escopo é limitada pela quantidade de nós literal dentro desse escopo.
Exemplo:
// 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
⚠️ as opções stringArray e stringArrayWrappersCount devem estar ativadas
Ativa as chamadas encadeadas entre os wrappers do string array.
Exemplo:
// 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
⚠️ a opção stringArray deve estar ativada
⚠️ Atualmente esta opção afeta apenas os wrappers adicionados pelo valor function da opção stringArrayWrappersType
Permite controlar o número máximo de parâmetros dos wrappers do array de strings.
O valor padrão e mínimo é 2. Valor recomendado entre 2 e 5.
stringArrayWrappersType
Type: string Default: variable
⚠️ as opções stringArray e stringArrayWrappersCount devem estar ativadas
Permite selecionar o tipo dos wrappers que são adicionados pela opção stringArrayWrappersCount.
Valores disponíveis:
'variable': adiciona wrappers de variável no topo de cada escopo. Desempenho rápido.'function': adiciona wrappers de função em posições aleatórias dentro de cada escopo. Desempenho mais lento que comvariable, mas oferece uma ofuscação mais rigorosa.
Altamente recomendável usar wrappers function para uma ofuscação maior quando a perda de desempenho não tem grande impacto em uma aplicação ofuscada.
Exemplo do valor de opção '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
⚠️ a opção stringArray deve estar ativada
Você pode usar esta configuração para ajustar a probabilidade (de 0 a 1) de que um literal de string seja inserido no stringArray.
Esta configuração é especialmente útil para códigos grandes, pois ela chama o string array repetidamente e pode deixar seu código mais lento.
stringArrayThreshold: 0 equivale a stringArray: false.
strictMode
Type: boolean | null Default: null
Permite especificar como o ofuscador deve tratar o código em relação ao modo estrito (strict mode) do JavaScript.
Valores disponíveis:
null(padrão) - detecta automaticamente o modo estrito a partir do código. Se o código tiver uma diretiva'use strict'explícita, sintaxe de módulo ES ou métodos de classe, ele é tratado como modo estrito. Caso contrário, presume-se o modo não estrito (sloppy).true- força o tratamento em modo estrito para todo o código, mesmo sem uma diretiva'use strict'explícita. Use isto quando seu código for executar em um contexto de modo estrito (por exemplo, em módulos ES, bundlers ou frameworks modernos).false- apenas indicadores explícitos de modo estrito ('use strict', módulos ES, métodos de classe) são tratados como estritos. A herança do escopo pai ainda se aplica conforme a especificação do JS.
target
Type: string Default: browser
Permite definir o ambiente de destino para o código ofuscado.
Valores disponíveis:
browser(padrão) — ambiente padrão de página web. O código de saída é idêntico ao denode, mas algumas opções específicas de navegador não podem ser usadas com o alvonodebrowser-no-eval— igual abrowser, mas a saída não usaeval(). Use quando a página de destino tiver uma Content Security Policy que proíbeeval/unsafe-eval.node— ambiente Node.js. As opções específicas de navegador são desativadas (elas exigemwindow/documente não teriam efeito ou lançariam erro no Node). Algumas defesas devmSelfDefendingque dependem de APIs exclusivas de navegador — detecção de navegador headless, recuperação de realm limpo baseada em iframe, verificações anti-inspetor/DOM — não são emitidas para este alvo.service-worker— contexto de Service Worker. Semwindow, semdocument, com um globalselfdiferente.userscript— sandbox de gerenciador de userscripts (por exemplo, Tampermonkey). As defesas devmSelfDefendingsão ajustadas de acordo.bytenode— código Node.js que será compilado com o loader bytenode (bytecode em cache do V8,.jsc) após a ofuscação. O próprio ofuscador não invoca obytenode; ele emite JavaScript ofuscado por VM cujo runtime é estruturado para sobreviver à etapa de compilação do bytenode, e as defesas devmSelfDefendingsão ajustadas de acordo. Execute obytenodena saída ofuscada você mesmo para produzir o.jscfinal.
transformObjectKeys
Type: boolean Default: false
Ativa a transformação das chaves de objetos.
Exemplo:
// 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
Controla quais avisos de ofuscação não fatais são emitidos pelo método ObfuscationResult.getWarnings().
Valores disponíveis:
'all'(padrão) — todos os avisos são emitidos.'none'— todos os avisos são suprimidos.- um objeto que mapeia tipos de aviso para booleanos — um tipo mapeado para
falseé suprimido; todo tipo não presente (ou mapeado paratrue) permanece ativado. Por exemplo,{ "VMGlobalFunctionNamesNotRenamed": false }mantém todos os avisos, exceto esse.
Tipos de aviso:
VMGlobalFunctionNamesNotRenamed— sobvmObfuscation, os nomes de declarações de função de nível superior, declarações de classe e variáveis às quais é atribuída uma expressão de função/arrow/classe foram mantidos como estão (a opçãorenameGlobalsestá desativada e o código não está envolvido em uma IIFE), então eles permanecem legíveis na saída mesmo que os corpos estejam ocultos como bytecode. Nomes exportados não são reportados.VMTopLevelInitializerNotVirtualized— os inicializadores de variáveis de nível superior permaneceram em JavaScript puro sob a ofuscação VM porquevmWrapTopLevelInitializersestá desativado ou não conseguiu virtualizá-los.DynamicCodeRenameRisk— o código constrói uma função a partir de uma string em tempo de execução (evaldireto, o construtorFunctionoufn.toString()injetado em um<script>/Worker), o que pode referenciar identificadores que o ofuscador renomeou.VMDynamicCodeSkipped— uma função foi ignorada na conversão para bytecode da VM porque contémevaldireto /new Functiondinâmico /Function(vejavmForceCompileDynamicCode).VMSyncFunctionSkippedInAsyncMode— comvmAsyncExecutorativado, uma função que você marcou explicitamente no modocommentmostrou-se síncrona e foi ignorada (apenas funções assíncronas são virtualizadas nesse modo).VMAsyncGeneratorSkippedInAsyncMode— comvmAsyncExecutore um getter de chave assíncrono ativo, um gerador assíncrono marcado não pôde ser virtualizado (ele deve retornar seu iterador de forma síncrona).BrowserTargetWithNodeStyleCode— o código aparenta ter o Node.js como alvo (por exemplo,require('fs'),__dirname,process.argv) enquanto a opçãotargetestá definida como um ambiente semelhante a navegador.
vmObfuscation
Type: boolean Default: false
Ativa a ofuscação por bytecode baseada em VM. Quando ativada, as funções JavaScript são compiladas em bytecode personalizado que roda em uma máquina virtual embutida. Isso oferece o nível mais alto de proteção, pois a lógica original do código é completamente transformada.
Exemplo:
Seu código legível, como return qty * price, torna-se uma lista de números como [0x15,0x03,0x17,...] que apenas o interpretador da VM embutida consegue executar. A lógica original deixa de ser visível como JavaScript.
vmTargetFunctions
Type: string[] Default: []
Especifica exatamente quais funções de nível raiz devem receber proteção de VM, por nome.
Exemplo:
{
vmObfuscation: true,
vmTargetFunctions: ['someFunctionName']
}
Resultado: Apenas essas três funções recebem proteção de VM. Todo o restante permanece como JavaScript comum (mas ainda ofuscado). Perfeito para proteger verificações sensíveis de licença ou lógica de autenticação, mantendo o restante do seu código enxuto.
vmExcludeFunctions
Type: string[] Default: []
Especifica funções de nível raiz que nunca devem receber proteção de VM. Tem precedência sobre outras configurações.
Exemplo:
{
vmObfuscation: true,
vmExcludeFunctions: ['someFunctionName']
}
Quando usar: Funções de nível raiz críticas para o desempenho (loops de animação, processamento de dados em tempo real) podem ser excluídas para evitar a sobrecarga da VM, ainda protegendo todo o restante.
vmTargetFunctionsMode
Type: string Default: root
Controla como as funções/métodos são selecionados para a ofuscação VM.
Exemplo - modo 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'
}
Quando usar: Quando você precisa de controle cirúrgico sobre exatamente quais funções recebem proteção de VM, especialmente funções aninhadas que contêm lógica sensível. Ao contrário de vmTargetFunctions, que só funciona com funções nomeadas de nível raiz, o modo comment permite proteger qualquer função em qualquer lugar do seu código.
vmForceCompileDynamicCode
Type: boolean Default: false
Controla o que a ofuscação VM faz com uma função que contém uma chamada direta a eval, new Function(...) ou Function(...).
Por padrão, essa função (e toda função definida dentro dela) é ignorada na conversão para bytecode da VM e um aviso VMDynamicCodeSkipped é reportado em result.getWarnings(). Isso ocorre porque o código-fonte construído em tempo de execução pode referenciar identificadores da cadeia de escopos ao redor — identificadores que o ofuscador renomeou.
Quando definido como true, a função é convertida em bytecode de qualquer forma e o aviso VMDynamicCodeSkipped deixa de ser emitido.
O aviso separado DynamicCodeRenameRisk continua sendo disparado independentemente desta opção, porque o risco de renomeação que ele descreve é independente da exclusão da VM — ativar esta opção não torna o padrão subjacente mais seguro.
// Source code
function loadConfig(src) {
return eval(src);
}
loadConfig('1 + 2');
// Options
{
vmObfuscation: true,
vmForceCompileDynamicCode: true
}
Com a opção desativada (padrão), loadConfig é deixada como JavaScript puro. Com a opção ativada, loadConfig é compilada em bytecode da VM como qualquer outra função. Use isto quando você tiver auditado o local da chamada e souber que o código construído em tempo de execução não depende de identificadores renomeados por closure.
vmWrapTopLevelInitializers
Type: boolean Default: false
Envolve alguns inicializadores de variáveis de nível superior em IIFEs (Immediately Invoked Function Expressions) para que possam ser ofuscados por VM.
O que ela faz: Sem esta opção, constantes e variáveis de nível superior permanecem visíveis na saída:
// Input
const MY_STRING = "my-string";
// Output (without vmWrapTopLevelInitializers)
const MY_STRING = "my-string"; // String is visible!
Com esta opção ativada, o inicializador é envolvido em uma IIFE que é ofuscada por VM:
// Input
const MY_STRING = "my-string";
// Output (with vmWrapTopLevelInitializers: true)
const MY_STRING = (() => { return /* VM bytecode call */ })(); // String hidden in bytecode
Nota: Esta opção só funciona quando vmTargetFunctionsMode é 'root' (o padrão).
Avisos: Sempre que um inicializador de nível superior acaba em JavaScript puro sob a ofuscação VM, um aviso VMTopLevelInitializerNotVirtualized listando os nomes das variáveis afetadas é reportado. Isso abrange: esta opção estar desativada, inicializadores que esta opção teve que ignorar (cada um com o motivo — por exemplo, o inicializador referencia um declarador irmão ou contém um await de nível superior) e o modo vmAsyncExecutor, no qual os wrappers síncronos não podem ser virtualizados de forma alguma.
vmDynamicOpcodes
Type: boolean Default: false
Torna o interpretador da VM menor e único para cada build.
O que ela faz:
- Filtra instruções não utilizadas - Se o seu código não usa classes, as instruções relacionadas a classes são removidas por completo
- Aleatoriza a estrutura - A ordem dos handlers de instrução é embaralhada a cada build
Como resultado - saída menor e cada build com aparência diferente.
vmBytecodeEncoding
Type: boolean Default: false
Codifica cada instrução de bytecode. As instruções são decodificadas uma de cada vez durante a execução.
vmBytecodeArrayEncoding
Type: boolean Default: false
Codifica o array de bytecode inteiro como um único bloco. O array é decodificado uma única vez na inicialização, antes de a execução começar. Use em conjunto com vmBytecodeEncoding para duas camadas de proteção.
vmBytecodeArrayEncodingKey
Type: string Default: ''
Chave de criptografia personalizada para a codificação do array de bytecode. Quando definida, esta chave é usada em vez da chave padrão derivada do ambiente. A chave deve ser fornecida em tempo de execução por meio de vmBytecodeArrayEncodingKeyGetter.
Esta opção externaliza a chave de criptografia - ela não fica embutida no próprio código ofuscado. Embora a chave ainda seja acessível em tempo de execução (e, portanto, não seja verdadeiramente secreta), essa separação impede que ferramentas de análise estática encontrem a chave apenas examinando o código.
Importante: A chave deve estar disponível de forma síncrona quando o código ofuscado é carregado. Use armazenamento síncrono, como cookies, localStorage, sessionStorage, variáveis globais ou elementos do DOM (por exemplo, meta tags injetadas pelo servidor). Métodos assíncronos como fetch() não podem ser usados diretamente na expressão do getter da chave.
vmBytecodeArrayEncodingKeyGetter
Type: string Default: ''
Expressão JavaScript síncrona que retorna a chave de criptografia em tempo de execução. Esta expressão é avaliada quando o código ofuscado é carregado e deve retornar a mesma chave que foi fornecida em vmBytecodeArrayEncodingKey. Para resolver a chave de forma assíncrona (uma Promise), ative vmAsyncExecutor.
Nota: um getter que retorna uma Promise requer vmAsyncExecutor. Isso não pode ser verificado em tempo de build, então um getter que retorna uma Promise com vmAsyncExecutor desativado falha em tempo de execução — o decodificador recebe a Promise em vez da chave.
O código ofuscado só funcionará quando o getter da chave retornar exatamente a mesma chave que foi usada durante a ofuscação. Se as chaves não corresponderem, a descriptografia falhará e o código produzirá lixo ou erros. Se o getter da chave retornar undefined, null ou uma string vazia, o código lançará um erro: "VM decryption key not available".
Importante: Mantenha a chave fora do mesmo arquivo/script do código ofuscado — colocá-la inline ali permite que até mesmo uma varredura puramente estática do bundle a recupere. Em vez disso, armazene-a em uma fonte separada: cookies definidos pelo servidor, localStorage populado por outro script, uma meta tag HTML injetada pelo servidor, um global definido por outro script ou (com vmAsyncExecutor) buscada no seu backend em tempo de execução.
Quando a chave é buscada no seu backend (via vmAsyncExecutor), adicione verificações baseadas em sessão ou origem nesse endpoint: retorne a chave correta para usuários reais (sessão válida, Origin/Referer esperados) e uma chave inválida para requisições suspeitas (por exemplo, uma origem localhost/inesperada, sem sessão). Usuários reais rodam normalmente; uma cópia rodando fora do seu ambiente recebe uma chave que descriptografa para nada. A lógica exata depende do seu site.
Exemplos:
// 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())'
Exemplo de uso:
// 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
Ativa o executor assíncrono da VM, que permite que vmBytecodeArrayEncodingKeyGetter retorne uma Promise (um getter de chave assíncrono) — assim, a chave de descriptografia pode ser buscada em tempo de execução (requisição de rede, IndexedDB, etc.) em vez de precisar estar disponível de forma síncrona quando o código é carregado.
Fortemente recomendado para bases de código totalmente assíncronas. Neste modo, apenas funções async são virtualizadas — uma função síncrona não pode ser transformada em assíncrona sem transformar seu valor de retorno em uma Promise e quebrar quem a chama — então código que é async de ponta a ponta obtém a maior cobertura. Ainda funciona quando a raiz é síncrona (por exemplo, uma IIFE síncrona / wrapper UMD): as funções async mais externas de dentro são protegidas, e as partes síncronas são deixadas como estão.
O que é transformado: cada função async mais externa, onde quer que apareça (inclusive aninhada dentro de wrappers síncronos). A função async mais externa de cada cadeia é a unidade protegida — tudo dentro dela, síncrono e assíncrono, é compilado junto. Funções síncronas e geradores comuns são deixados sem ofuscação.
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
}
}
Exclusões e avisos. Geradores assíncronos também são deixados sem ofuscação quando um getter de chave assíncrono está ativo (um gerador assíncrono deve retornar seu iterador de forma síncrona e não pode esperar pela chave). No modo padrão vmTargetFunctionsMode: 'root', as exclusões são silenciosas (a seleção é automática); no modo comment, um aviso é emitido por meio de ObfuscationResult.getWarnings() sempre que uma função que você marcou explicitamente não pode ser virtualizada — ela se mostrou síncrona ou é um gerador assíncrono sob um getter de chave assíncrono.
O getter de chave assíncrono requer adicionalmente vmBytecodeArrayEncoding com um vmBytecodeArrayEncodingKeyGetter.
Exemplo de uso:
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
Codifica os alvos de salto no bytecode. Os offsets de salto são calculados em tempo de execução, ocultando a estrutura do fluxo de controle (if/else, loops, etc.) da análise estática.
vmMacroOps
Type: boolean Default: false
Combina sequências comuns de instruções em opcodes "macro" únicos. Por exemplo, LOAD + ADD + STORE pode se tornar uma única instrução MACRO_ADD_TO_VAR. Isso quebra o reconhecimento de padrões e pode melhorar o desempenho.
vmDebugProtection
Type: boolean Default: false
Adiciona defesas antidepuração, antianálise e anti-LLM em múltiplas camadas ao runtime da VM. Funciona melhor com os alvos browser/browser-no-eval.
vmSelfDefending
Type: boolean Default: false
Adiciona proteção em múltiplas camadas contra adulteração, contra hooks e contra engenharia reversa ao runtime da VM.
⚠️ Esta opção ativa forçadamente vmBytecodeArrayEncoding.
⚠️ Detecção de ambiente sensível. Esta opção vincula o código ofuscado ao seu ambiente de execução de destino e usa fingerprinting avançado de navegador para detectar ferramentas de automação. O código protegido com esta opção vai quebrar intencionalmente quando executado em:
- Navegadores headless (Chrome/Chromium headless, PhantomJS)
- Ferramentas de automação de navegador (Puppeteer, Playwright, Cypress, Selenium/ChromeDriver, Nightmare)
- Node.js (quando
targetestá definido comobrowser) - jsdom ou emulações de DOM do lado do servidor semelhantes
- Ambientes em que os builtins nativos do navegador foram interceptados por hooks ou substituídos
O código funcionará corretamente em navegadores comuns (Chrome, Firefox, Safari, Edge), inclusive quando carregado dentro de iframes, extensões de navegador (content scripts) e Web Workers. Se você precisar executar testes automatizados contra código protegido, desative vmSelfDefending para os builds de teste — esta opção foi projetada para impedir a análise automatizada e não pode ser usada com segurança com nenhum framework de automação.
Fortemente recomendado usar em conjunto com vmDebugProtection, vmBytecodeArrayEncodingKey e vmBytecodeArrayEncodingKeyGetter.
vmDefenseHook
Type: { name: string, aliases?: object } Default: ''
vmDefenseHook recebe um objeto com duas chaves: name (obrigatória) e aliases (opcional).
name é uma função global definida pela sua página host que uma defesa da VM (vmDebugProtection / vmSelfDefending) chama com um objeto de sinal quando detecta um sinal hostil — um depurador ou inspetor, um navegador headless / de automação, um processo de agente de codificação de IA, um domínio não permitido e assim por diante. Use-a para reportar o evento ao seu backend (por exemplo, navigator.sendBeacon). O hook é um coletor de telemetria puro: seu valor de retorno é ignorado, e um hook ausente ou que lança erro é um no-op silencioso que nunca pode desativar uma defesa. Para mudar o que uma defesa faz na detecção, use vmDefenseReaction.
aliases opcionalmente renomeia os campos desse objeto de sinal — abordado em Renomeando os campos do sinal abaixo.
O objeto de sinal. O hook recebe um único signal:
source— o detector específico que disparou (veja a tabela).category— o grupo sob o qual ele reporta:automation(navegadores não humanos),debugger(um depurador/inspetor está ativo),sandbox(host instrumentado/falso),domain(violação de bloqueio de domínio),tamper(builtins alterados em tempo de execução) ouintegrity(o próprio código da VM foi alterado).score/threshold— a intensidade com que o detector disparou e o valor que ele precisava atingir; o hook dispara apenas quandoscore >= threshold. A maioria das verificações é tudo-ou-nada (um único sinal decisivo);headlesssoma vários sinais de forma do navegador, então seuscorecostuma ser maior que seuthreshold.
Registrando o hook. Defina-o como um global comum antes de o bundle ofuscado carregar — o runtime da VM e suas defesas rodam antes do seu programa (protegido), então muitas detecções disparam durante a inicialização:
// in your page, before the obfuscated script:
window.__vmDetection = function (signal) { navigator.sendBeacon('/vm-defense', JSON.stringify(signal)); };
// obfuscation option:
vmDefenseHook: { name: '__vmDetection' }
Um hook definido dentro do código-fonte ofuscado é registrado tarde demais para capturar detecções em tempo de inicialização e, se for compilado pela VM, não pode ser alcançado até que seu programa rode. Ele é mantido seguro de qualquer forma (um hook ausente é um no-op, e um guard de reentrância impede qualquer descontrole), mas, para cobertura completa, registre-o antecipadamente. Para ainda proteger sua lógica de reporte, mantenha o hook registrado como um buffer de uma linha ((window.__vmDet = window.__vmDet || []).push(signal)) e leia/envie esse buffer a partir do seu código ofuscado.
Renomeando os campos do sinal (aliases). Os valores padrão de source/category são nomes descritivos, então qualquer um que instrumente o callback (ou leia a saída) pode reconhecer a proteção e qual detector disparou. aliases renomeia os campos do sinal para tokens opacos de sua escolha, aplicados dentro da VM antes de o sinal ser emitido, então esses nomes nunca aparecem na saída nem chegam ao callback. Sua aplicação conhece seu próprio mapeamento e encaminha os tokens ao seu backend.
Os aliases são por campo, mantendo separadas as renomeações de chave e de valor: cada campo recebe uma key (o nome da propriedade que o callback recebe); os campos de nome do tipo string source e category também recebem um mapa values, enquanto score/threshold são números e recebem apenas uma key. Os nomes que você pode mapear (qualquer outro é rejeitado em tempo de build):
- chaves de campo —
source,category,score,threshold - valores de
source—headless,agent,node,debugger,timing,sandbox,domain,nativeHook,integrity - valores de
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> }
}
Isto é evasão de fingerprint, não segredo — o mapeamento ainda pode ser inferido por testes repetidos — então seu único benefício é não expor nomes estáveis e autoexplicativos. Entradas não definidas mantêm seus nomes padrão.
Uma string simples (vmDefenseHook: '__vmDetection') é aceita como forma abreviada de { name: '__vmDetection' }, mas está obsoleta — prefira a forma de objeto.
vmDefenseReaction
Type: object Default: { automation: 'break', debugger: 'decoy', sandbox: 'decoy', domain: 'break', tamper: 'break', integrity: 'break' }
Configura como cada categoria de detecção reage. Ela não ativa nada — as próprias defesas são ligadas por vmSelfDefending, vmDebugProtection e vmDomainLock; esta opção apenas seleciona como uma defesa já ativada reage. A categoria é a unidade de controle — cada detector de uma categoria executa a reação daquela categoria.
Cada categoria agrupa os detectores que observam um tipo de condição hostil. Uma categoria só reage quando a opção que emite seus detectores está ativada:
Cada categoria mapeia para uma ou mais das opções vmSelfDefending, vmDebugProtection e vmDomainLock; não existe categoria fora dessas três opções, e uma reação definida para uma categoria cuja opção está desativada simplesmente não tem efeito.
As chaves são esses seis nomes de categoria, ou default (um fallback para categorias não especificadas). Os valores são:
break— quebra imediatamentedecoy— continua rodando em estado envenenado, produzindo silenciosamente resultados erradosnone— não faz nada localmente (apenas telemetria)
Os padrões por categoria são mostrados acima; uma categoria que você não define (ou define com seu valor padrão) usa esse padrão. default alcança todas as categorias, inclusive as corretas por construção (integrity, tamper), então { default: 'none' } é um build genuinamente não destrutivo, apenas de telemetria:
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
Faz o significado dos opcodes depender da posição no bytecode. Cada posição tem um mapeamento de opcode para handler diferente, derivado de uma semente, então o mesmo número de opcode realiza operações diferentes em posições diferentes.
vmCallContextOpcodes
Type: boolean Default: false
Faz uma função protegida depender de onde ela é chamada, de modo que não possa ser extraída do código e executada ou analisada isoladamente — ela só se comporta corretamente quando invocada por meio de seus locais de chamada reais no programa. Esta opção afeta o desempenho em tempo de execução.
Atualmente, apenas as seguintes construções têm suporte:
- declarações de função (
function f() {}); - expressões de função e arrow functions atribuídas a uma variável (
const f = () => {}); - métodos privados de instância (
this.#m()).
Em todos os casos, a função deve sempre ser alcançada por uma chamada direta (f(), this.#m()). Se ela for armazenada em outra variável, passada como argumento ou usada de outra forma como valor, fica sem proteção. Funções assíncronas têm suporte; geradores não.
Esta opção é experimental e pode quebrar seu código, então teste a saída minuciosamente antes de usá-la.
vmStackEncoding
Type: boolean Default: false
Criptografa os valores na pilha da VM durante a execução. Os valores são codificados ao serem empilhados e decodificados ao serem desempilhados, então a inspeção de memória mostra dados criptografados em vez dos valores reais.
Esta opção afeta fortemente o desempenho.
vmCompactDispatcher
Type: boolean Default: false
Usa um único executor de VM em vez de executores duais (síncrono + gerador). Reduz o tamanho do código ofuscado, mas adiciona cerca de 20% de sobrecarga de desempenho em código com muita recursão.
false(padrão): executores duais — desempenho ótimo, saída maiortrue: executor único — saída menor, ligeiramente mais lento
vmStringArrayBytecodeOnly
Type: boolean Default: false
Quando ativada, o array de strings apenas extrairá strings dos dados de bytecode — nenhuma outra string no código é transformada. Isso ativa forçadamente stringArray mesmo que não esteja explicitamente definido.
Por que usar isto: Extrair todas as strings de runtime da VM para um array de strings é lento. Esta opção mira apenas o conteúdo de bytecode para a extração do array de strings, melhorando o desempenho enquanto ainda protege as constantes do bytecode.
- Quando
vmBytecodeArrayEncoding: false— strings dentro dos pools de constantes do bytecode (arraysc) são extraídas - Quando
vmBytecodeArrayEncoding: true— strings de bytecode de nível superior codificadas em base64 são extraídas stringArrayThresholdainda controla qual porcentagem dessas strings de bytecode é extraída
vmDomainLock
Type: string[] Default: []
⚠️ Esta opção não funciona com target: 'node', target: 'service-worker' ou target: 'bytenode'
Restringe o código ofuscado a domínios e/ou subdomínios específicos, e é muito mais difícil de localizar e remover do que domainLock.
Se o código-fonte não for executado nos domínios especificados por esta opção, o navegador será redirecionado para a URL passada a vmDomainLockRedirectUrl, e as demais chamadas protegidas retornarão resultados incorretos mesmo que o redirecionamento seja suprimido.
Múltiplos domínios e subdomínios
É possível restringir seu código a mais de um domínio ou subdomínio. Por exemplo, para restringi-lo de modo que o código só rode em www.example.com, adicione www.example.com. Para que funcione no domínio raiz incluindo quaisquer subdomínios (example.com, sub.example.com), use .example.com.
vmDomainLockRedirectUrl
Type: string Default: about:blank
⚠️ Esta opção não funciona com target: 'node', target: 'service-worker' ou target: 'bytenode'
Permite que o navegador seja redirecionado para uma URL passada caso o código-fonte não seja executado nos domínios especificados por vmDomainLock.
Preset Options
Ofuscação alta, baixo desempenho
O desempenho será muito mais lento do que sem ofuscação
{
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
}
Ofuscação média, desempenho ótimo
O desempenho será mais lento do que sem ofuscação
{
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
}
Ofuscação baixa, alto desempenho
O desempenho ficará em um nível relativamente normal
{
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
}
Predefinição padrão, alto desempenho
{
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
}
Ofuscação VM Ultra High (Segurança Máxima)
Esta predefinição ativa a ofuscação por bytecode baseada em VM com todos os recursos de blindagem, incluindo dispatch indireto. Oferece a proteção mais forte, mas com tamanho de saída maior e execução muito mais lenta.
{
optionsPreset: 'vm-ultra-high-obfuscation'
}
Ou configure individualmente:
{
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 (Proteção contra Agentes de IA)
Esta predefinição foi projetada especificamente para impedir que agentes de IA e LLMs façam engenharia reversa de código convertido em bytecode de VM. Baseada em vm-default com self-defending e proteção contra depuração ativados. Mais leve que vm-high-obfuscation, mas especificamente blindada contra análise automatizada.
{
optionsPreset: 'vm-anti-llm'
}
Inclui:
- Ofuscação por bytecode da VM com array de strings (de
vm-default) vmSelfDefending— detecção anti-hook, hash de integridade, fingerprint do código-fonte, verificação de realm limpo por iframe, derivação de chave com cifra ARXvmDebugProtection— verificações antidepuração no loop de dispatch da VMdebugProtection: false— sem a proteção contra depuração legada (a proteção contra depuração da VM é superior)
Ofuscação VM High (Segurança Mais Alta)
Esta predefinição ativa a ofuscação por bytecode baseada em VM com a maioria dos recursos de blindagem. Oferece proteção forte com melhor desempenho do que a predefinição ultra-high.
{
optionsPreset: 'vm-high-obfuscation'
}
Ou configure individualmente:
{
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
}
Ofuscação VM Medium (Segurança Equilibrada)
Esta predefinição ativa a ofuscação por bytecode baseada em VM com um conjunto equilibrado de recursos de blindagem. Bom compromisso entre segurança e desempenho.
{
optionsPreset: 'vm-medium-obfuscation'
}
Ou configure individualmente:
{
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
}
Ofuscação VM Low (Segurança Básica, Melhor Desempenho)
Esta predefinição ativa a ofuscação básica por bytecode baseada em VM sem recursos adicionais de blindagem. Bom equilíbrio entre segurança e tamanho de saída.
{
optionsPreset: 'vm-low-obfuscation'
}
Ou configure individualmente:
{
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 + Proteção de Array de Strings)
Esta predefinição combina a ofuscação básica por bytecode baseada em VM com a proteção de array de strings. Bom ponto de partida para a ofuscação VM com proteção de strings.
{
optionsPreset: 'vm-default'
}
Ou configure individualmente:
{
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
}
