JavaScript obfuscator
JavaScript Obfuscator是一个免费并且功能强大的JavaScript混淆器,其中包含多种功能,可为您的源代码提供保护。
主要特征
变量重命名
字符串提取和加密
废代码注入
平展控制流
各种代码转换
插件
- Webpack plugin: webpack-obfuscator
- Webpack loader: obfuscator-loader
- Gulp: gulp-javascript-obfuscator
- Grunt: grunt-contrib-obfuscator
- Rollup: rollup-plugin-javascript-obfuscator
- Weex: weex-devtool
- Malta: malta-js-obfuscator
- Netlify plugin: netlify-plugin-js-obfuscator
重要告知
尽量只混淆属于您的代码。
不建议对第三方脚本以及polyfill进行混淆处理,因为混淆后的代码要慢15-80%(取决于选项),并且文件要大得多。
安装
使用yarn或者npm
yarn add --dev javascript-obfuscator
或者
npm install --save-dev javascript-obfuscator
在浏览器中使用:
<script src="https://cdn.jsdelivr.net/npm/javascript-obfuscator/dist/index.browser.js"></script>
使用本地node_modules
<script src="./node_modules/javascript-obfuscator/dist/index.browser.js"></script>
使用方法
var JavaScriptObfuscator = require('javascript-obfuscator');
var obfuscationResult = JavaScriptObfuscator.obfuscate(
`
(function(){
var variable1 = '5' - 3;
var variable2 = '5' + 3;
var variable3 = '5' + - '2';
var variable4 = ['10','10','10','10','10'].map(parseInt);
var variable5 = 'foo ' + 1 + 1;
console.log(variable1);
console.log(variable2);
console.log(variable3);
console.log(variable4);
console.log(variable5);
})();
`,
{
compact: false,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
numbersToExpressions: true,
simplify: true,
shuffleStringArray: true,
splitStrings: true,
stringArrayThreshold: 1
}
);
console.log(obfuscationResult.getObfuscatedCode());
/*
var _0x1139 = [
'250745hAZAIu',
'qyvdX',
'359787rBCuAH',
'map',
'CAsQH',
'2yDlJiW',
'IzZqs',
'3|8|4|5|0|',
'975554pJYIxL',
'2sejBjT',
'258646CmEwYP',
'23651lJjzwJ',
'xqNJa',
'37rnYVXp',
'log',
'WudlX',
'cIfMd',
'foo\x20',
'2GUqEHE',
'2|6|7|9|1',
'238609DyHPrO',
'split',
'828371LpDRiJ'
];
function _0x1054 (_0x14a2a4, _0x5a6b22) {
_0x14a2a4 = _0x14a2a4 - (0x1c48 + -0x1dd + 0x38f * -0x7);
var _0x581b0b = _0x1139[_0x14a2a4];
return _0x581b0b;
}
(function (_0x190a1e, _0x14558c) {
var _0x59720b = _0x1054;
while (!![]) {
try {
var _0x3dab81 = parseInt(_0x59720b(0x196)) * parseInt(_0x59720b(0x191)) + parseInt(_0x59720b(0x193)) * parseInt(_0x59720b(0x184)) + parseInt(_0x59720b(0x198)) * parseInt(_0x59720b(0x188)) + parseInt(_0x59720b(0x18a)) * parseInt(_0x59720b(0x18c)) + -parseInt(_0x59720b(0x187)) + -parseInt(_0x59720b(0x189)) + -parseInt(_0x59720b(0x195));
if (_0x3dab81 === _0x14558c)
break;
else
_0x190a1e['push'](_0x190a1e['shift']());
} catch (_0x58f14d) {
_0x190a1e['push'](_0x190a1e['shift']());
}
}
}(_0x1139, 0x2c5c * -0x7 + -0xdfdc6 + 0x16ff98), function () {
var _0x9b877 = _0x1054, _0x4add6f = {
'WudlX': _0x9b877(0x186) + _0x9b877(0x192),
'qyvdX': function (_0x552261, _0x28d3ee) {
return _0x552261 + _0x28d3ee;
},
'xqNJa': function (_0x387474, _0x5602bf) {
return _0x387474 + _0x5602bf;
},
'CAsQH': _0x9b877(0x190),
'IzZqs': function (_0x5d9fd2, _0x9f4faa) {
return _0x5d9fd2 - _0x9f4faa;
},
'cIfMd': function (_0x5f18e0, _0x4c33c5) {
return _0x5f18e0 + _0x4c33c5;
}
}, _0x593549 = _0x4add6f[_0x9b877(0x18e)][_0x9b877(0x194)]('|'), _0x2acb4f = -0x94b + -0x2627 * -0x1 + 0xe6e * -0x2;
while (!![]) {
switch (_0x593549[_0x2acb4f++]) {
case '0':
var _0x10d015 = _0x4add6f[_0x9b877(0x197)](_0x4add6f[_0x9b877(0x18b)](_0x4add6f[_0x9b877(0x183)], -0x3d * -0xc + -0x6f1 * -0x1 + 0x42 * -0x26), 0x62f * 0x3 + 0x1046 * -0x1 + -0x246);
continue;
case '1':
console[_0x9b877(0x18d)](_0x10d015);
continue;
case '2':
console[_0x9b877(0x18d)](_0x4cd6e2);
continue;
case '3':
var _0x4cd6e2 = _0x4add6f[_0x9b877(0x185)]('5', -0x1bc + 0xf61 + 0x5 * -0x2ba);
continue;
case '4':
var _0x2c3053 = _0x4add6f[_0x9b877(0x18b)]('5', -'2');
continue;
case '5':
var _0x372d29 = [
'10',
'10',
'10',
'10',
'10'
][_0x9b877(0x182)](parseInt);
continue;
case '6':
console[_0x9b877(0x18d)](_0x109ffa);
continue;
case '7':
console[_0x9b877(0x18d)](_0x2c3053);
continue;
case '8':
var _0x109ffa = _0x4add6f[_0x9b877(0x18f)]('5', -0x1d70 + -0x1654 + -0xf1 * -0x37);
continue;
case '9':
console[_0x9b877(0x18d)](_0x372d29);
continue;
}
break;
}
}());
*/
-
obfuscate(sourceCode, options)
方法带有两个参数,sourceCode和options - 分别是源代码和选项:
sourceCode(字符串,默认值:null)–任何有效的源代码,以字符串形式传递;
options(对象,默认值:null)–带有选项的对象。
有关可用选项,请参阅选项。
返回ObfuscationResult对象,该对象包含两个方法getObfuscatedCode以及getSourceMap:
getObfuscatedCode() - 返回混淆后的代码字符串;
getSourceMap() - 如果启用了sourceMap选项-返回带有SourceMap的字符串,或者如果将sourceMapMode选项设置为inline,则返回一个空字符串。
ObfuscationResult对象调用toString() 将返回带有混淆代码的字符串。
-
obfuscateMultiple(sourceCodesObject, options)
可以处理多个源码,其中sourceCodesObject,其键是源代码的标识符,值是源代码:
{
foo: 'var foo = 1;',
bar: 'var bar = 2;'
}
返回一个映射对象,其键是源代码的标识符,值是ObfuscationResult对象。
-
getOptionsByPreset(optionsPreset)
输入选项预设名字,返回预设配置对象,预设名字包括:default、low-obfuscation、medium-obfuscation、high-obfuscation
命令行用法
压缩单个文件的用法:
javascript-obfuscator input_file_name.js [options]
javascript-obfuscator input_file_name.js --output output_file_name.js [options]
javascript-obfuscator input_file_name.js --output output_folder_name [options]
javascript-obfuscator input_folder_name --output output_folder_name [options]
带有.js扩展名的单个输入文件的混淆。
如果未使用--output选项指定目标路径,则混淆文件将以INPUT_FILE_NAME-obfuscated.js名称保存到输入文件目录中。
举个例子:
javascript-obfuscator samples/sample.js --compact true --self-defending false
// 创建新文件 samples/sample-obfuscated.js
javascript-obfuscator samples/sample.js --output output/output.js --compact true --self-defending false
// 创建新文件 output/output.js
整个目录递归混淆
用法:
javascript-obfuscator ./dist [options]
// 在./dist目录创建一个带有obfuscated后缀的js文件
javascript-obfuscator ./dist --output ./dist/obfuscated [options]
// 在./dist/obfuscated目录下创建同样目录结构
输入目录下所有.js文件的混淆。 如果此目录包含带有-obfuscated后缀的已混淆文件-这些文件将被忽略。
条件注释
您可以通过添加以下注释来禁用和启用代码片段的混淆:
- 禁用: //
javascript-obfuscator:disable
或者 /*javascript-obfuscator:disable */
- 启用: //
javascript-obfuscator:enable
或者 /*javascript-obfuscator:enable */
例子:
// 输入
var foo = 1;
// javascript-obfuscator:disable
var bar = 2;
// 输出
var _0xabc123 = 0x1;
var bar = 2;
JavaScript Obfuscator 选项
JavaScript Obfuscator提供以下选项
{
compact: true,
controlFlowFlattening: false,
controlFlowFlatteningThreshold: 0.75,
deadCodeInjection: false,
deadCodeInjectionThreshold: 0.4,
debugProtection: false,
debugProtectionInterval: false,
disableConsoleOutput: false,
domainLock: [],
forceTransformStrings: [],
identifierNamesGenerator: 'hexadecimal',
identifiersDictionary: [],
identifiersPrefix: '',
ignoreRequireImports: false,
inputFileName: '',
log: false,
numbersToExpressions: false,
optionsPreset: 'default',
renameGlobals: false,
renameProperties: false,
renamePropertiesMode: 'safe',
reservedNames: [],
reservedStrings: [],
rotateStringArray: true,
seed: 0,
selfDefending: false,
shuffleStringArray: true,
simplify: true,
sourceMap: false,
sourceMapBaseUrl: '',
sourceMapFileName: '',
sourceMapMode: 'separate',
splitStrings: false,
splitStringsChunkLength: 10,
stringArray: true,
stringArrayIndexesType: [
'hexadecimal-number'
],
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75,
target: 'browser',
transformObjectKeys: false,
unicodeEscapeSequence: false
}
命令行选项
-v, --version
-h, --help
-o, --output
--compact <boolean>
--config <string>
--control-flow-flattening <boolean>
--control-flow-flattening-threshold <number>
--dead-code-injection <boolean>
--dead-code-injection-threshold <number>
--debug-protection <boolean>
--debug-protection-interval <boolean>
--disable-console-output <boolean>
--domain-lock '<list>' (comma separated)
--exclude '<list>' (comma separated)
--force-transform-strings '<list>' (comma separated)
--identifier-names-generator <string> [dictionary, hexadecimal, mangled, mangled-shuffled]
--identifiers-dictionary '<list>' (comma separated)
--identifiers-prefix <string>
--ignore-require-imports <boolean>
--log <boolean>
--numbers-to-expressions <boolean>
--options-preset <string> [default, low-obfuscation, medium-obfuscation, high-obfuscation]
--rename-globals <boolean>
--rename-properties <boolean>
--rename-properties-mode <string> [safe, unsafe]
--reserved-names '<list>' (comma separated)
--reserved-strings '<list>' (comma separated)
--rotate-string-array <boolean>
--seed <string|number>
--self-defending <boolean>
--shuffle-string-array <boolean>
--simplify <boolean>
--source-map <boolean>
--source-map-base-url <string>
--source-map-file-name <string>
--source-map-mode <string> [inline, separate]
--split-strings <boolean>
--split-strings-chunk-length <number>
--string-array <boolean>
--string-array-indexes-type '<list>' (comma separated) [hexadecimal-number, hexadecimal-numeric-string]
--string-array-encoding '<list>' (comma separated) [none, base64, rc4]
--string-array-index-shift <boolean>
--string-array-wrappers-count <number>
--string-array-wrappers-chained-calls <boolean>
--string-array-wrappers-parameters-max-count <number>
--string-array-wrappers-type <string> [variable, function]
--string-array-threshold <number>
--target <string> [browser, browser-no-eval, node]
--transform-object-keys <boolean>
--unicode-escape-sequence <boolean>
-
compact
类型:boolean 默认值:true
压缩代码到一行
-
config
类型:string 默认值:''
包含混淆器选项的JS / JSON配置文件。 这些将被直接传递给CLI的选项覆盖。
-
controlFlowFlattening
类型:boolean 默认值:false
是否开启平展控制流。此选项对性能的影响最大为运行速度降低1.5倍。 使用controlFlowFlatteningThreshold设置将受控制流展平影响的节点的百分比。
平展控制流是源代码的结构转换,让代码变得难以阅读。
例子:
// input
(function(){
function foo () {
return function () {
var sum = 1 + 2;
console.log(1);
console.log(2);
console.log(3);
console.log(4);
console.log(5);
console.log(6);
}
}
foo()();
})();
// output
(function () {
function _0x3bfc5c() {
return function () {
var _0x3260a5 = {
'WtABe': '4|0|6|5|3|2|1',
'GokKo': function _0xf87260(_0x427a8e, _0x43354c) {
return _0x427a8e + _0x43354c;
}
};
var _0x1ad4d6 = _0x3260a5['WtABe']['split']('|'), _0x1a7b12 = 0x0;
while (!![]) {
switch (_0x1ad4d6[_0x1a7b12++]) {
case '0':
console['log'](0x1);
continue;
case '1':
console['log'](0x6);
continue;
case '2':
console['log'](0x5);
continue;
case '3':
console['log'](0x4);
continue;
case '4':
var _0x1f2f2f = _0x3260a5['GokKo'](0x1, 0x2);
continue;
case '5':
console['log'](0x3);
continue;
case '6':
console['log'](0x2);
continue;
}
break;
}
};
}
_0x3bfc5c()();
}());
-
controlFlowFlatteningThreshold
类型:boolean 默认值:false 最小:0 最大:1
每个节点采用平展控制流的概率,该参数主要用来优化大代码的性能和代码大小。大量的平展控制流会是代码运行效率变差而且代码增大。
设置为0表示关闭平展控制流
-
deadCodeInjection
类型:boolean 默认值:false
使用此选项,将随机废代码块添加到混淆代码中。
该选项显著增加混淆代码的大小(最大200%),如果对混淆代码大小不敏感的时候启用该选项。
开启该选项将强制启用stringArray选项
例子:
// input
(function(){
if (true) {
var foo = function () {
console.log('abc');
console.log('cde');
console.log('efg');
console.log('hij');
};
var bar = function () {
console.log('klm');
console.log('nop');
console.log('qrs');
};
var baz = function () {
console.log('tuv');
console.log('wxy');
console.log('z');
};
foo();
bar();
baz();
}
})();
// output
var _0x5024 = [
'zaU',
'log',
'tuv',
'wxy',
'abc',
'cde',
'efg',
'hij',
'QhG',
'TeI',
'klm',
'nop',
'qrs',
'bZd',
'HMx'
];
function _0x4502 (_0x1254b1, _0x583689) {
_0x1254b1 = _0x1254b1 - 0x0;
var _0x529b49 = _0x5024[_0x1254b1];
return _0x529b49;
}
(function () {
if (!![]) {
var _0x16c18d = function () {
if (_0x4502('0x0') !== _0x4502('0x0')) {
console[_0x4502('0x1')](_0x4502('0x2'));
console[_0x4502('0x1')](_0x4502('0x3'));
console[_0x4502('0x1')]('z');
} else {
console[_0x4502('0x1')](_0x4502('0x4'));
console[_0x4502('0x1')](_0x4502('0x5'));
console[_0x4502('0x1')](_0x4502('0x6'));
console[_0x4502('0x1')](_0x4502('0x7'));
}
};
var _0x1f7292 = function () {
if (_0x4502('0x8') === _0x4502('0x9')) {
console[_0x4502('0x1')](_0x4502('0xa'));
console[_0x4502('0x1')](_0x4502('0xb'));
console[_0x4502('0x1')](_0x4502('0xc'));
} else {
console[_0x4502('0x1')](_0x4502('0xa'));
console[_0x4502('0x1')](_0x4502('0xb'));
console[_0x4502('0x1')](_0x4502('0xc'));
}
};
var _0x33b212 = function () {
if (_0x4502('0xd') !== _0x4502('0xe')) {
console[_0x4502('0x1')](_0x4502('0x2'));
console[_0x4502('0x1')](_0x4502('0x3'));
console[_0x4502('0x1')]('z');
} else {
console[_0x4502('0x1')](_0x4502('0x4'));
console[_0x4502('0x1')](_0x4502('0x5'));
console[_0x4502('0x1')](_0x4502('0x6'));
console[_0x4502('0x1')](_0x4502('0x7'));
}
};
_0x16c18d();
_0x1f7292();
_0x33b212();
}
}());
-
deadCodeInjectionThreshold
类型:boolean 默认值:false 最小:0 最大:1
节点加入废代码的概率,值越大,混淆代码大小越大
-
debugProtection
类型:boolean 默认值:false
如果您打开开发人员工具,会冻结您的浏览器,不允许调试。
使用该选项,几乎不可能使用开发人员工具的调试器功能(基于WebKit和Mozilla Firefox的浏览器上)
-
debugProtectionInterval
类型:boolean 默认值:false
如果设置为true,则会在“控制台”选项卡上使用一个间隔来强制调试模式,这使得使用开发人员工具的其他功能更加困难。 启用了debugProtection,才可以使用。
-
disableConsoleOutput
类型:boolean 默认值:false
通过将它们替换为空函数,禁用console.log,console.info,console.error,console.warn,console.debug,console.exception和console.trace的使用。
-
domainLock
类型:string[] 默认值:[]
允许仅在特定域名或子域名上运行混淆的源代码。 这使他人很难复制和粘贴您的代码在其他地方运行。
多个域名和子域名
可以将代码锁定到多个域名或子域名。 例如,要对其进行锁定,以使代码仅在www.example.com上运行,请添加www.example.com。 要使其在包括任何子域名(example.com,sub.example.com)的根域上工作,请使用.example.com
-
exclude
类型:string[] 默认值:[]
排除混淆代码文件,指定文件名或者globs
-
identifierNamesGenerator
类型:string 默认值:hexadecimal
设置变量名称生成器,可以使用下面的值:
dictionary
: 变量名称来自identifiersDictionaryhexadecimal
:变量名称像_0xabc123
mangled
: 短变量名称如:a
,b
,c
mangled-shuffled
: 和mangled一样,但是变量是乱序的
-
identifiersDictionary
类型:string[] 默认值:[]
identifierNamesGenerator设置为dictionary下使用,字典内的元素可以通过变换字符大小写产生不同变量名字
-
identifiersPrefix
类型:string 默认值:''
为所有全局标识符设置前缀。
当您要混淆多个文件时,请使用此选项。 此选项有助于避免这些文件的全局标识符之间的冲突。 每个文件的前缀都应该不同。
-
ignoreRequireImports
类型:boolean 默认值:false
忽略混淆require和impoort,某些情况下需要静态引入,不能替换为变量
-
inputFileName
类型:string 默认值:''
允许使用源代码设置输入文件的名称。此名称将在内部用于源映射生成。
-
log
类型:boolean 默认值:false
启用将信息输出到控制台
numbersToExpressions
类型:boolean 默认值:false
允许将数字转换为表达式
例如:
// input
const foo = 1234;
// output
const foo=-0xd93+-0x10b4+0x41*0x67+0x84e*0x3+-0xff8;
-
optionsPreset
类型:string 默认值:'default'
可用参数:
default
low-obfuscation
medium-obfuscation
high-obfuscation
选项默认值名称,所有附加选项将与该名称对应的预设选项合并。
-
renameGlobals
类型:boolean 默认值:false
指定是否混淆全局变量和函数名称。
//input
var $ = function(id) {
return document.getElementById(id);
};
//output
var _0x4864b0=function(_0x5763be){return document['getElementById'](_0x5763be);};
-
renameProperties
类型:boolean 默认值:false
启用属性名称的重命名。 所有内置的DOM属性和核心JavaScript类中的属性都将被忽略。
要在此选项的安全和不安全模式之间切换,请使用renamePropertiesMode选项。
要设置重命名属性名称的格式,请使用identifierNamesGenerator选项。
若要控制将重命名的属性,请使用reservedNames选项。
例子:
// input
(function () {
const foo = {
prop1: 1,
prop2: 2,
calc: function () {
return this.prop1 + this.prop2;
}
};
console.log(foo.calc());
})();
// output
(function () {
const _0x46529b = {
'_0x10cec7': 0x1,
'_0xc1c0ca': 0x2,
'_0x4b961d': function () {
return this['_0x10cec7'] + this['_0xc1c0ca'];
}
};
console['log'](_0x46529b['_0x4b961d']());
}());
-
renamePropertiesMode
类型:string 默认值:'safe'
指定renameProperties选项模式:
safe - 2.11.0版本之后的默认值。 尝试以更安全的方式重命名属性,以防止运行时错误。 使用此模式时,某些属性将从重命名中排除。
unsafe - 2.11.0发行之前的默认值。 无限制地以不安全的方式重命名属性。
-
reservedNames
类型: string[]
默认值: []
使用正则过滤需要混淆的变量。
{
reservedNames: [
'^someVariable',
'functionParameter_\d'
]
}
-
reservedStrings
类型: string[]
默认值: []
使用正则过滤需要混淆的字符串
{
reservedStrings: [
'react-native',
'\.\/src\/test',
'some-string_\d'
]
}
-
rotateStringArray
类型:boolean 默认值:true
将stringArray移动固定和随机(在代码混淆处生成)位置。这使得将删除的字符串的顺序与其原始位置进行匹配变得更加困难。
-
seed
类型: string|number
默认值: 0
此选项为随机生成器设置种子。这对于创建可重复的结果很有用。
如果种子为0-随机生成器将在没有种子的情况下工作。
-
selfDefending
类型: boolean
默认值: false
此选项使输出代码可阻止格式设置和变量重命名。如果尝试在混淆后的代码上使用JavaScript美化器,则该代码将无法正常工作。
-
shuffleStringArray
类型: boolean
默认值: true
随机打乱stringArray数组元素,stringArray设置为true时启用
-
simplify
类型: boolean
默认值: true
简化多余的代码
例子:
// input
if (condition1) {
const foo = 1;
const bar = 2;
console.log(foo);
return bar;
} else if (condition2) {
console.log(1);
console.log(2);
console.log(3);
return 4;
} else {
return 5;
}
// output
if (condition1) {
const foo = 0x1, bar = 0x2;
return console['log'](foo), bar;
} else
return condition2 ? (console['log'](0x1), console['log'](0x2), console['log'](0x3), 0x4) : 0x5;
-
sourceMap
类型: boolean
默认值: false
启用混淆代码的Sourcemap生成
Sourcemap可以帮助您调试混淆后的JavaScript源代码。 如果要在生产中进行调试,可以将单独的Sourcemap文件上传到某个地方,然后将浏览器指向该位置。
-
sourceMapBaseUrl
类型: string
默认值: ''
当sourceMapMode设置为'separate'时,将URL设置为Sourcemap导入URL
javascript-obfuscator input.js --output out.js --source-map true --source-map-base-url 'http://localhost:9000'
结果:
//# sourceMappingURL=http://localhost:9000/example.js.map
-
sourceMapMode
类型: string
默认值: separate
指定源映射生成模式:
inline - 在每个.js文件的末尾添加源映射;
Sourcemap
separate - 生成与对应的.map文件。 如果您通过CLI运行混淆器-使用混淆的代码//#sourceMappingUrl = file.js.map将指向源映射文件的链接添加到文件的末尾。
-
splitStrings
类型: boolean
默认值: false
将字符串拆分字符串块。
// input
(function(){
var test = 'abcdefg';
})();
// output
(function(){
var _0x5a21 = 'ab' + 'cd' + 'ef' + 'g';
})();
-
splitStringsChunkLength
类型: number
默认值: 10
设置字符串拆分区块长度
-
stringArray
类型: boolean
默认值: true
删除字符串并将其放置在特殊的数组中。 例如,var m =“ Hello World”中的字符串“ Hello World”; 将被替换为var m = _0x12c456 [0x1];
-
stringArrayEncoding
类型: string[]
默认值: []
这个设置会让你的代码慢下来!
使用base64或rc4对stringArray的所有字符串文字进行编码,并插入一个特殊代码,用于在运行时将其解码回来。
每个stringArray值都将通过从传递列表中随机选取的编码进行编码。这使得使用多种编码成为可能。
可用的编码如下:
- 'none'(boolean):不编码stringArray值
- 'base64'(string):使用base64对stringArray值进行编码
- “rc4”(字符串):使用rc4对stringArray值进行编码。大约比base64慢30-50%,但更难获得初始值。建议在使用rc4编码时禁用UnicodeScapeSequence选项,以防止出现非常大的混淆代码。
例如,使用以下选项值时,某些stringArray值将不进行编码,而某些值将使用base64和rc4编码进行编码:
stringArrayEncoding: [
'none',
'base64',
'rc4'
]
-
transformObjectKeys
类型: boolean
默认值: false
启用Object键值的转换
// input
(function(){
var object = {
foo: 'test1',
bar: {
baz: 'test2'
}
};
})();
// output
var _0x2fae = [
'baz',
'test2',
'foo',
'test1',
'bar'
];
function _0x377c (_0x1fbd3f, _0x59c72f) {
_0x1fbd3f = _0x1fbd3f - 0x0;
var _0x14fada = _0x2fae[_0x1fbd3f];
return _0x14fada;
}
(function () {
var _0x8a12db = {};
_0x8a12db[_0x377c('0x0')] = _0x377c('0x1');
var _0xc75419 = {};
_0xc75419[_0x377c('0x2')] = _0x377c('0x3');
_0xc75419[_0x377c('0x4')] = _0x8a12db;
var _0x191393 = _0xc75419;
}());
预设值
重度混淆,性能低
性能下降50-100%
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 1,
deadCodeInjection: true,
deadCodeInjectionThreshold: 1,
debugProtection: true,
debugProtectionInterval: true,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
rotateStringArray: true,
selfDefending: true,
shuffleStringArray: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 5,
stringArray: true,
stringArrayEncoding: ['rc4'],
stringArrayIndexShift: true,
stringArrayWrappersCount: 5,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 5,
stringArrayWrappersType: 'function',
stringArrayThreshold: 1,
transformObjectKeys: true,
unicodeEscapeSequence: false
}
中度压缩,最佳性能
性能下降30-35%
{
compact: true,
controlFlowFlattening: true,
controlFlowFlatteningThreshold: 0.75,
deadCodeInjection: true,
deadCodeInjectionThreshold: 0.4,
debugProtection: false,
debugProtectionInterval: false,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: true,
renameGlobals: false,
rotateStringArray: true,
selfDefending: true,
shuffleStringArray: true,
simplify: true,
splitStrings: true,
splitStringsChunkLength: 10,
stringArray: true,
stringArrayEncoding: ['base64'],
stringArrayIndexShift: true,
stringArrayWrappersCount: 2,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 4,
stringArrayWrappersType: 'function',
stringArrayThreshold: 0.75,
transformObjectKeys: true,
unicodeEscapeSequence: false
}
轻度压缩,高性能
性能略低于压缩之前
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: false,
disableConsoleOutput: true,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
rotateStringArray: true,
selfDefending: true,
shuffleStringArray: true,
simplify: true,
splitStrings: false,
stringArray: true,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75,
unicodeEscapeSequence: false
}
默认值,高性能
{
compact: true,
controlFlowFlattening: false,
deadCodeInjection: false,
debugProtection: false,
debugProtectionInterval: false,
disableConsoleOutput: false,
identifierNamesGenerator: 'hexadecimal',
log: false,
numbersToExpressions: false,
renameGlobals: false,
rotateStringArray: true,
selfDefending: false,
shuffleStringArray: true,
simplify: true,
splitStrings: false,
stringArray: true,
stringArrayEncoding: [],
stringArrayIndexShift: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75,
unicodeEscapeSequence: false
}