解释并且部分附上代码例子
介绍
代码混淆(Code Obfuscation)是一种软件安全技术,通常应用于软件、应用程序、库或者其他可执行文件的源代码中。
代码混淆旨在增加源代码的复杂性和难以理解性,以防止恶意用户或逆向工程师分析和理解代码的逻辑、算法和结构。
它的主要目标是使得源代码难以理解和阅读,从而增加攻击者进行逆向工程的难度。
它通过一系列技术来改变源代码的结构和语义,但不改变其功能。
然而,需要注意的是,代码混淆并不能完全阻止逆向工程,只能增加攻击者的成本和难度。
建议
仅仅混淆属于您的代码
不建议混淆第三方库文件,因为混淆后的代码要慢 15-80%(取决于怎么配置),而且文件要大得多。
注意
加密后的字符串有时候不能运行,不知道为啥,薛定谔,多试几次。不知道是不是因为用了汉字。
找到原因了,因为输出了加密代码又复制粘贴进文件的时候概率出错。直接写进新文件就不会有问题了
代码混淆
代码压缩(Code Compression)
对源代码进行压缩,移除注释、空白字符等,减少代码的可读性。
反调试(Anti-Debugging)
插入反调试代码,使得调试器无法正常工作,防止攻击者对程序进行调试以了解其内部逻辑。
基于调试器特性,对当前运行环境进行检验,加入一些强制调试 debugger 语句,使其在调试模式下难以顺利执行 JavaScript 代码。
ruby
const options = {
compact: false,
debugProtection: true,
}
动态代码生成(Dynamic Code Generation)
在运行时动态生成代码,增加代码的动态性,使得静态分析更加困难。
ruby
function generateDynamicCode(number) {
// 动态生成代码字符串
const code = `
function dynamicFunction() {
return ${number} * 2;
}
const result = dynamicFunction();
console.log('Result:', result);
`;
// 使用eval执行动态生成的代码
eval(code);
}
// 调用函数并传入参数
generateDynamicCode(5);
僵尸代码注入
随机在代码中插入无用的僵尸代码、僵尸函数,进一步使代码混乱。
混淆视听,不会被执行的代码
ruby
"deadCodeInjection": true,
"deadCodeInjectionThreshold": 0.4,
ruby
console.log('hello Python斗罗')
ruby
var _0x627880 = _0x530e;
function _0x53b5() {
var _0x49cae1 = [
'hello\x20Python斗罗',
'232952cucknd',
'46qspGQv',
'144ffirDv',
'6097835KlwAnE',
'111381YpFCDx',
'506CYIurY',
'1625540xbxbKf',
'18ZvgMrV',
'log',
'4655216CDqvAd',
'162290uBGloN',
'1118745VAdAoy'
];
_0x53b5 = function () {
return _0x49cae1;
};
return _0x53b5();
}
function _0x530e(_0x4201b8, _0xb736df) {
var _0x53b504 = _0x53b5();
return _0x530e = function (_0x530e96, _0x4158ba) {
_0x530e96 = _0x530e96 - 0x1d8;
var _0x1a9bdd = _0x53b504[_0x530e96];
return _0x1a9bdd;
}, _0x530e(_0x4201b8, _0xb736df);
}
(function (_0x266cfd, _0x39d5a3) {
var _0x5ebd5a = _0x530e, _0x14a707 = _0x266cfd();
while (!![]) {
try {
var _0x1a0f5e = -parseInt(_0x5ebd5a(0x1da)) / 0x1 + parseInt(_0x5ebd5a(0x1dd)) / 0x2 * (-parseInt(_0x5ebd5a(0x1e0)) / 0x3) + parseInt(_0x5ebd5a(0x1d8)) / 0x4 + parseInt(_0x5ebd5a(0x1df)) / 0x5 + -parseInt(_0x5ebd5a(0x1e3)) / 0x6 * (-parseInt(_0x5ebd5a(0x1e2)) / 0x7) + -parseInt(_0x5ebd5a(0x1dc)) / 0x8 * (-parseInt(_0x5ebd5a(0x1de)) / 0x9) + parseInt(_0x5ebd5a(0x1d9)) / 0xa * (-parseInt(_0x5ebd5a(0x1e1)) / 0xb);
if (_0x1a0f5e === _0x39d5a3)
break;
else
_0x14a707['push'](_0x14a707['shift']());
} catch (_0x441392) {
_0x14a707['push'](_0x14a707['shift']());
}
}
}(_0x53b5, 0xc9d6f), console[_0x627880(0x1e4)](_0x627880(0x1db)));
变量混淆
十六进制字符串编码
短变量名
将带有含意的变量名、方法名、常量名随机变为无意义的类乱码字符串,降低代码可读性,如转成单个字符或十六进制字符串。
重命名变量、函数、类等标识符,使得代码中的标识符难以理解和辨识。
- hexadecimal:将变量名替换为 16 进制形式的字符串,如 0xabc123。
- mangled:将变量名替换为普通的简写字符,如 a、b、c 等。
ruby
const code = `
let x = 'Python斗罗'
console.log('x', x)
`
const options = {
compact: false,
identifierNamesGenerator: 'mangled'
}
const obfuscator = require('javascript-obfuscator')
function obfuscate(code, options) {
return obfuscator.obfuscate(code, options).getObfuscatedCode()
}
var ob_str=obfuscate(code, options)
console.log(ob_str)
const path = require('path');
// 获取当前文件的完整路径
const fullPath = __filename;
// 使用path模块获取文件名
const fileName = path.basename(fullPath);
console.log('当前文件名:', fileName);
const fs = require('fs');
// 新文件名
const newFileName = fileName.replace(/(\.js)$/, '_ob$1');
// 将内容写入文件
fs.writeFile(newFileName, ob_str, (err) => {
if (err) {
console.error('写入文件时出错:', err);
return;
}
console.log('内容已成功写入到文件:', newFileName);
});
ruby
function b(c, d) {
const e = a();
return b = function (f, g) {
f = f - 0x13a;
let h = e[f];
return h;
}, b(c, d);
}
function a() {
const j = [
'55506hSBZUT',
'14050uoDFOO',
'1405768UwRzZg',
'248534SCLiAU',
'7VvHWlI',
'log',
'5185251lKZzCb',
'426222vVYBeb',
'33623YbimIL',
'44bwFtBd'
];
a = function () {
return j;
};
return a();
}
const i = b;
(function (c, d) {
const h = b, e = c();
while (!![]) {
try {
const f = -parseInt(h(0x143)) / 0x1 + -parseInt(h(0x13e)) / 0x2 + parseInt(h(0x13b)) / 0x3 * (-parseInt(h(0x13a)) / 0x4) + -parseInt(h(0x13c)) / 0x5 + -parseInt(h(0x142)) / 0x6 * (-parseInt(h(0x13f)) / 0x7) + -parseInt(h(0x13d)) / 0x8 + parseInt(h(0x141)) / 0x9;
if (f === d)
break;
else
e['push'](e['shift']());
} catch (g) {
e['push'](e['shift']());
}
}
}(a, 0x1a2e1));
let x = 'Python斗罗';
console[i(0x140)]('x', x);
字符串混淆
将字符串阵列化集中放置、并可进行 MD5 或 Base64 加密存储,使代码中不出现明文字符串,这样可以避免使用全局搜索字符串的方式定位到入口点。
对于源代码中的字符串进行加密处理,运行时再解密以恢复原始字符串,防止攻击者通过字符串来理解代码的逻辑。
ruby
var x = 'hello Python斗罗'
console.log('x', x)
ruby
const options = {
compact: false,
stringArray: true,
rotateStringArray: true,
stringArrayEncoding: ['base64'], // 'base64' or 'rc4' or false
stringArrayThreshold: 1,
}
ruby
var _0x1a66a6 = _0xdc05;
(function (_0x1b8967, _0x4d6c78) {
var _0x5f2632 = _0xdc05, _0x1ef07d = _0x1b8967();
while (!![]) {
try {
var _0x4dccc3 = -parseInt(_0x5f2632(0x8d)) / 0x1 * (parseInt(_0x5f2632(0x97)) / 0x2) + parseInt(_0x5f2632(0x90)) / 0x3 + -parseInt(_0x5f2632(0x94)) / 0x4 * (parseInt(_0x5f2632(0x8c)) / 0x5) + -parseInt(_0x5f2632(0x91)) / 0x6 + -parseInt(_0x5f2632(0x92)) / 0x7 * (parseInt(_0x5f2632(0x8b)) / 0x8) + -parseInt(_0x5f2632(0x95)) / 0x9 * (parseInt(_0x5f2632(0x8f)) / 0xa) + -parseInt(_0x5f2632(0x96)) / 0xb * (-parseInt(_0x5f2632(0x8e)) / 0xc);
if (_0x4dccc3 === _0x4d6c78)
break;
else
_0x1ef07d['push'](_0x1ef07d['shift']());
} catch (_0x2d53a4) {
_0x1ef07d['push'](_0x1ef07d['shift']());
}
}
}(_0x5330, 0x6bbc9));
function _0xdc05(_0x21aff8, _0x558f9a) {
var _0x5330de = _0x5330();
return _0xdc05 = function (_0xdc05ee, _0x5a1185) {
_0xdc05ee = _0xdc05ee - 0x8a;
var _0x105bed = _0x5330de[_0xdc05ee];
if (_0xdc05['ikASGW'] === undefined) {
var _0x2e9ea2 = function (_0x242b92) {
var _0x919537 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';
var _0x5baf07 = '', _0x246647 = '';
for (var _0x15f687 = 0x0, _0x836945, _0x2c1321, _0x41597f = 0x0; _0x2c1321 = _0x242b92['charAt'](_0x41597f++); ~_0x2c1321 && (_0x836945 = _0x15f687 % 0x4 ? _0x836945 * 0x40 + _0x2c1321 : _0x2c1321, _0x15f687++ % 0x4) ? _0x5baf07 += String['fromCharCode'](0xff & _0x836945 >> (-0x2 * _0x15f687 & 0x6)) : 0x0) {
_0x2c1321 = _0x919537['indexOf'](_0x2c1321);
}
for (var _0x1de2b6 = 0x0, _0x17f92d = _0x5baf07['length']; _0x1de2b6 < _0x17f92d; _0x1de2b6++) {
_0x246647 += '%' + ('00' + _0x5baf07['charCodeAt'](_0x1de2b6)['toString'](0x10))['slice'](-0x2);
}
return decodeURIComponent(_0x246647);
};
_0xdc05['XnCJdp'] = _0x2e9ea2, _0x21aff8 = arguments, _0xdc05['ikASGW'] = !![];
}
var _0xbb5328 = _0x5330de[0x0], _0x467f6f = _0xdc05ee + _0xbb5328, _0x1b734e = _0x21aff8[_0x467f6f];
return !_0x1b734e ? (_0x105bed = _0xdc05['XnCJdp'](_0x105bed), _0x21aff8[_0x467f6f] = _0x105bed) : _0x105bed = _0x1b734e, _0x105bed;
}, _0xdc05(_0x21aff8, _0x558f9a);
}
var x = _0x1a66a6(0x93);
console[_0x1a66a6(0x8a)]('x', x);
function _0x5330() {
var _0x4ed8a9 = [
'mJq3nNLYuxrNtG',
'Bg9N',
'mJKYmJG4ofLlCvvWzW',
'mJyXmJeWu3rcDgXX',
'ntC3teLRCLLi',
'mJq0ntztB1zcy3q',
'mteXndKWsKvssgTo',
'mJq0mZe3mhjpBNfszW',
'mJG1nZiWnKjoEKTjCG',
'mtrIr0jKs1u',
'AgvSBg8GuhL0Ag9U5PAx572x',
'mtzUrMfWuwu',
'ntr5tfrKru8',
'otG0nvbLDxPrrW'
];
_0x5330 = function () {
return _0x4ed8a9;
};
return _0x5330();
}
数字混淆
将数字转换为表达式
ruby
var a=666;
ruby
var a = 0x2072 * -0x1 + 0x3fd * 0x4 + 0x1318;
属性加密
针对 JavaScript 对象的属性进行加密转化,隐藏代码之间的调用关系。
ruby
// 创建一个对象
const encryptedObject = {
// 原始属性值
_encryptedValue: '',
// 定义加密方法
set encryptedValue(value) {
// 在这里进行加密操作,这里仅作示例,实际加密方法可以更复杂
this._encryptedValue = value * 2;
},
// 定义解密方法
get decryptedValue() {
// 在这里进行解密操作,这里仅作示例,实际解密方法应与加密方法对应
return this._encryptedValue / 2;
}
};
// 使用加密方法设置属性值
encryptedObject.encryptedValue = 10;
// 使用解密方法获取属性值
console.log(encryptedObject.decryptedValue); // 输出: 10
控制流平坦化
改变数据的处理方式,例如加入虚假的数据流,增加无用的赋值操作等,以增加代码的混淆度。
打乱函数原有代码执行流程及函数调用关系,使代码逻变得混乱无序。
控制流扁平化的目标是通过将代码中所有功能基本块放在同一级别上,进行隐藏功能的原始控制流,以达到对代码逻辑顺序进行混淆的效果。
还有一种处理后是大量的switch
ruby
const code = `
let x = '1' + 1
console.log('x', x)
`
const options = {
compact: false,
controlFlowFlattening: true
}
const obfuscator = require('javascript-obfuscator')
function obfuscate(code, options) {
return obfuscator.obfuscate(code, options).getObfuscatedCode()
}
console.log(obfuscate(code, options))
ruby
const _0x288a15 = _0x135a;
function _0x11f3() {
const _0x4903e3 = [
'222DuZKcV',
'log',
'63WtEZqm',
'586079gPyfnl',
'221225eYDQrR',
'1445128YlbBol',
'6604772EjdQii',
'3OPtUUo',
'13401288YbfzBU',
'62116730UfAgDG',
'3052084qkYEZH'
];
_0x11f3 = function () {
return _0x4903e3;
};
return _0x11f3();
}
function _0x135a(_0xbedc73, _0x8c434d) {
const _0x11f33d = _0x11f3();
return _0x135a = function (_0x135af9, _0xef154) {
_0x135af9 = _0x135af9 - 0xf3;
let _0x5863e5 = _0x11f33d[_0x135af9];
return _0x5863e5;
}, _0x135a(_0xbedc73, _0x8c434d);
}
(function (_0x2287b0, _0x714256) {
const _0x2639d0 = _0x135a, _0x38e588 = _0x2287b0();
while (!![]) {
try {
const _0x109287 = -parseInt(_0x2639d0(0xf4)) / 0x1 + parseInt(_0x2639d0(0xfb)) / 0x2 * (-parseInt(_0x2639d0(0xf8)) / 0x3) + -parseInt(_0x2639d0(0xf7)) / 0x4 + parseInt(_0x2639d0(0xf5)) / 0x5 * (parseInt(_0x2639d0(0xfc)) / 0x6) + parseInt(_0x2639d0(0xf3)) / 0x7 * (-parseInt(_0x2639d0(0xf6)) / 0x8) + -parseInt(_0x2639d0(0xf9)) / 0x9 + parseInt(_0x2639d0(0xfa)) / 0xa;
if (_0x109287 === _0x714256)
break;
else
_0x38e588['push'](_0x38e588['shift']());
} catch (_0x549996) {
_0x38e588['push'](_0x38e588['shift']());
}
}
}(_0x11f3, 0xecf7f));
let x = '1' + 0x1;
console[_0x288a15(0xfd)]('x', x);
锁定域名
使 JavaScript 代码只能在指定域名下执行。
ruby
const currentHostname = window.location.hostname;
if (currentHostname === 'aa.com') {
console.log('当前页面的域名是 aa.com');
} else {
console.log('当前页面的域名不是 aa.com');
}
反格式化
禁止美化代码
如果对 JavaScript 代码进行格式化,则无法执行,导致浏览器假死。
在浏览器中源代码只有一行,格式化后分析会被检测出来。
简单代码
ruby
function a() {return 'hahaha';}
if(a.toString().indexOf('\n') == -1){
console.log('代码未被格式化')
}else{console.log('代码已经被格式化')}
代码会卡死
ruby
console.log("start");
function t(){
return t.toString().search('(((.+)+)+)+$').toString();
}
a=t();
console.log("end");
代码运行正常
ruby
console.log("start");
function t(){ return t.toString().search('(((.+)+)+)+$').toString();}
a=t();
console.log("end");
特殊编码
将 JavaScript 完全编码为人不可读的代码,如表情符号、特殊表示内容等等。
AAencode
可加密可解密
https://www.toolkk.com/tools/aaencode-encode-decode
ruby
# console.log('aaencode')
゚ω゚ノ= /`m´)ノ ~┻━┻ //*´∇`*/ ['_']; o=(゚ー゚) =_=3; c=(゚Θ゚) =(゚ー゚)-(゚ー゚); (゚Д゚) =(゚Θ゚)= (o^_^o)/ (o^_^o);(゚Д゚)={゚Θ゚: '_' ,゚ω゚ノ : ((゚ω゚ノ==3) +'_') [゚Θ゚] ,゚ー゚ノ :(゚ω゚ノ+ '_')[o^_^o -(゚Θ゚)] ,゚Д゚ノ:((゚ー゚==3) +'_')[゚ー゚] }; (゚Д゚) [゚Θ゚] =((゚ω゚ノ==3) +'_') [c^_^o];(゚Д゚) ['c'] = ((゚Д゚)+'_') [ (゚ー゚)+(゚ー゚)-(゚Θ゚) ];(゚Д゚) ['o'] = ((゚Д゚)+'_') [゚Θ゚];(゚o゚)=(゚Д゚) ['c']+(゚Д゚) ['o']+(゚ω゚ノ +'_')[゚Θ゚]+ ((゚ω゚ノ==3) +'_') [゚ー゚] + ((゚Д゚) +'_') [(゚ー゚)+(゚ー゚)]+ ((゚ー゚==3) +'_') [゚Θ゚]+((゚ー゚==3) +'_') [(゚ー゚) - (゚Θ゚)]+(゚Д゚) ['c']+((゚Д゚)+'_') [(゚ー゚)+(゚ー゚)]+ (゚Д゚) ['o']+((゚ー゚==3) +'_') [゚Θ゚];(゚Д゚) ['_'] =(o^_^o) [゚o゚] [゚o゚];(゚ε゚)=((゚ー゚==3) +'_') [゚Θ゚]+ (゚Д゚) .゚Д゚ノ+((゚Д゚)+'_') [(゚ー゚) + (゚ー゚)]+((゚ー゚==3) +'_') [o^_^o -゚Θ゚]+((゚ー゚==3) +'_') [゚Θ゚]+ (゚ω゚ノ +'_') [゚Θ゚]; (゚ー゚)+=(゚Θ゚); (゚Д゚)[゚ε゚]='\\'; (゚Д゚).゚Θ゚ノ=(゚Д゚+ ゚ー゚)[o^_^o -(゚Θ゚)];(o゚ー゚o)=(゚ω゚ノ +'_')[c^_^o];(゚Д゚) [゚o゚]='\"';(゚Д゚) ['_'] ( (゚Д゚) ['_'] (゚ε゚+/*´∇`*/(゚Д゚)[゚o゚]+ (゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+(o^_^o)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚) + (゚Θ゚))+((゚ー゚) + (o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚) + (゚Θ゚))+((o^_^o) +(o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((o^_^o) +(o^_^o))+(o^_^o)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚) + (゚Θ゚))+((゚ー゚) + (o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚) + (゚Θ゚))+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+((゚ー゚) + (゚Θ゚))+(゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+((o^_^o) +(o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚) + (゚Θ゚))+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚) + (゚Θ゚))+((゚ー゚) + (o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+((゚ー゚) + (o^_^o))+(゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+(c^_^o)+(゚Д゚)[゚ε゚]+(゚ー゚)+((゚ー゚) + (o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+(゚Θ゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+(゚Θ゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+((゚ー゚) + (゚Θ゚))+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚) + (゚Θ゚))+((o^_^o) +(o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+(o^_^o)+(゚Д゚)[゚ε゚]+(゚Θ゚)+((゚ー゚) + (゚Θ゚))+((゚ー゚) + (o^_^o))+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+(゚ー゚)+(゚Д゚)[゚ε゚]+(゚Θ゚)+(゚ー゚)+((゚ー゚) + (゚Θ゚))+(゚Д゚)[゚ε゚]+(゚ー゚)+((゚ー゚) + (o^_^o))+(゚Д゚)[゚ε゚]+((゚ー゚) + (゚Θ゚))+(゚Θ゚)+(゚Д゚)[゚o゚]) (゚Θ゚)) ('_');
JJencode
可加密可解密
https://www.toolkk.com/tools/jjencode-encode-decode
ruby
# console.log('jjencode')
$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$$__+$._$+"\\"+$.__$+$.$_$+$.$$_+"\\"+$.__$+$.$$_+$._$$+$._$+(![]+"")[$._$_]+$.$$$_+"."+(![]+"")[$._$_]+$._$+"\\"+$.__$+$.$__+$.$$$+"('\\"+$.__$+$.$_$+$._$_+"\\"+$.__$+$.$_$+$._$_+$.$$$_+"\\"+$.__$+$.$_$+$.$$_+$.$$__+$._$+$.$$_$+$.$$$_+"')"+"\"")())();
jsfuck
手动解密
ruby
# console.log('jsfuck')
[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(+[![]]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+!+[]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[!+[]+!+[]])+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]])()([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]]+((!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(+(+!+[]+[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+[!+[]+!+[]]+[+[]])+[])[+!+[]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]+!+[]+!+[]]+(!![]+[])[+[]]+[!+[]+!+[]+!+[]+!+[]+!+[]]+[+!+[]])[(![]+[])[!+[]+!+[]+!+[]]+(+(!+[]+!+[]+[+!+[]]+[+!+[]]))[(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([]+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]][([][[]]+[])[+!+[]]+(![]+[])[+!+[]]+((+[])[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+(!![]+[])[!+[]+!+[]+!+[]]]](!+[]+!+[]+!+[]+[+!+[]])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]]((!![]+[])[+[]])[([][(!![]+[])[!+[]+!+[]+!+[]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]](([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]][([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((!![]+[])[+!+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+([][[]]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+!+[]]+(![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]]+![]+(![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]])()[([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]((![]+[+[]])[([![]]+[][[]])[+!+[]+[+[]]]+(!![]+[])[+[]]+(![]+[])[+!+[]]+(![]+[])[!+[]+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(![]+[])[!+[]+!+[]+!+[]]]()[+!+[]+[+[]]])+[])[+!+[]])+([]+[])[(![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(!![]+[])[+[]]+([][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+(![]+[])[!+[]+!+[]]+(![]+[])[+!+[]]+(!![]+[])[+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]()[+!+[]+[!+[]+!+[]]])())
JS加密
不同于 JavaScript 混淆技术,JavaScript 加密技术可以说是对 JavaScript 混淆技术防护的进一步升级,其基本思路是将一些核心逻辑使用诸如 C/C++ 语言来编写,并通过 JavaScript 调用执行,从而起到二进制级别的防护作用。
其加密的方式现在有 Emscripten 和 WebAssembly 等,其中后者越来越成为主流。下面我们分别来介绍下。
Emscripten
现在,许多 3D 游戏都是用 C/C++ 语言写的,如果能将 C / C++ 语言编译成 JavaScript 代码,它们不就能在浏览器里运行了吗?众所周知,JavaScript 的基本语法与 C 语言高度相似。于是,有人开始研究怎么才能实现这个目标,为此专门做了一个编译器项目 Emscripten。这个编译器可以将 C / C++ 代码编译成 JavaScript 代码,但不是普通的 JavaScript,而是一种叫作 asm.js 的 JavaScript 变体。
因此说,某些 JavaScript 的核心功能可以使用 C/C++ 语言实现,然后通过 Emscripten 编译成 asm.js,再由 JavaScript 调用执行,这可以算是一种前端加密技术。
WebAssembly(wasm)
5分钟了解wasm:https://www.jesuisundev.com/en/understand-webassembly-in-5-minutes/
在线生成wasm:https://mbebenita.github.io/WasmExplorer/
如果你对 JavaScript 比较了解,可能知道还有一种叫作 WebAssembly 的技术,也能将 C/C++ 转成 JavaScript 引擎可以运行的代码。那么它与 asm.js 有何区别呢?
其实两者的功能基本一致,就是转出来的代码不一样:asm.js 是文本,WebAssembly 是二进制字节码,因此运行速度更快、体积更小。从长远来看,WebAssembly 的前景更光明。
WebAssembly 是经过编译器编译之后的字节码,可以从 C/C++ 编译而来,得到的字节码具有和 JavaScript 相同的功能,但它体积更小,而且在语法上完全脱离 JavaScript,同时具有沙盒化的执行环境。
利用 WebAssembly 技术,我们可以将一些核心的功能利用 C/C++ 语言实现,形成浏览器字节码的形式。然后在 JavaScript 中通过类似如下的方式调用:
python
WebAssembly.compile(new Uint8Array(`
00 61 73 6d 01 00 00 00 01 0c 02 60 02 7f 7f 01
7f 60 01 7f 01 7f 03 03 02 00 01 07 10 02 03 61
64 64 00 00 06 73 71 75 61 72 65 00 01 0a 13 02
08 00 20 00 20 01 6a 0f 0b 08 00 20 00 20 00 6c
0f 0b`.trim().split(/[\s\r\n]+/g).map(str => parseInt(str, 16))
)).then(module => {
const instance = new WebAssembly.Instance(module)
const { add, square } = instance.exports
console.log('2 + 4 =', add(2, 4))
console.log('3^2 =', square(3))
console.log('(2 + 5)^2 =', square(add(2 + 5)))
})
工具
JavaScript Obfuscator Tool 【js混淆器工具】
官网
代码仓库
https://github.com/javascript-obfuscator/javascript-obfuscator
安装
ruby
npm install javascript-obfuscator -g
使用
混淆单个文件
ruby
javascript-obfuscator input_file.js
批量混淆
ruby
# 采用递归的方式混淆当前目录下的所有js文件(包括子文件),对原文件进行修改,不会生成新的js文件
javascript-obfuscator ./ --output ./
采用递归的方式混淆当前目录下的所有js文件(包括子文件),对原文件进行拷贝,会生成新的js文件,在新的js文件中进行修改。
javascript-obfuscator ./
--ouput a.js:指定输出文件名
--ouput ./output:指定输出目录
可选参数
JavaScript Obfuscator Options【混淆配置选项】
ruby
{
# 类型:boolean默认值:true,压缩代码输出在一行。
compact: true,
# 启用代码控制流展平。控制流扁平化是源代码的一种结构转换,它阻碍了程序的理解。
# 控制流,此选项极大地影响性能,运行时速度降低1.5倍
# controlFlowFlatteningThreshold将受控制流展平影响的节点的百分比
controlFlowFlattening: false,
# controlFlowFlattening转换将应用于任何给定节点的概率。
# 此设置对于较大的代码量特别有用,因为大量的控制流转换会降低代码速度并增加代码大小。
controlFlowFlatteningThreshold: 0.75,
# 大大增加了模糊代码的大小(最多200%),只有在混淆代码的大小无关紧要时才使用。
# 使用deadCodeInjectionThreshold设置将受死代码注入影响的节点的百分比。
# 此选项强制启用stringArray选项。
# 使用这个选项,随机的僵尸代码块将被添加到模糊代码中。
deadCodeInjection: false,
# 允许设置受deadCodeInjection影响的节点的百分比。
deadCodeInjectionThreshold: 0.4,
# 如果打开开发人员工具,可以冻结浏览器
# 这个选项使得几乎不可能使用开发人员工具的debugger函数
debugProtection: false,
# 可以冻结你的浏览器!使用风险自负。
# 如果选中,则使用一个间隔来强制Console选项卡上的debug模式,
# 这使得使用开发人员工具的其他功能更加困难。如果启用debugProtection,则有效。
debugProtectionInterval: 0,
# 通过将console.log、console.info、console.error、console.warn、console.debug、
# console.exception和console.trace替换为空函数来禁用它们。这使得调试器的使用更加困难。
disableConsoleOutput: false,
# 此选项不适用于target: 'node'
# 只允许在特定域和/或sub-domains上运行模糊处理的源代码。
# 这使得人们很难复制并粘贴源代码并在别处运行。
# 多域和sub-domains
# 可以将代码锁定到多个域或sub-domain。
# 例如,要锁定它,使代码只在www.example.comaddwww.example.com上运行。
# 要使它在根域上工作,包括sub-domain(example.com,sub.example.com),
# 请使用.example.com。
domainLock: [],
# 重定向的新url
domainLockRedirectUrl: 'about:blank',
# 表示要从模糊处理中排除的文件的文件名或全局名
exclude:[],
forceTransformStrings: [],
identifierNamesCache: null,
# 设置标识符名称生成器
# Available values:
# dictionary:来自identifiersDictionary列表的标识符名称
# hexadecimal:标识符名称,如_0xabc123
# mangled:短标识符名称,如a、b、c
# mangled-shuffled:与mangled相同,但字母表混乱
identifierNamesGenerator: 'hexadecimal',
为identifierNamesGenerator:dictionary选项设置标识符字典。
# 字典中的每个标识符将用于几个变体中,每个字符的大小写都不同。
# 因此,字典中标识符的数量应该取决于原始源代码的标识符数量。
identifiersDictionary: [],
# 为所有全局标识符设置前缀。
# 如果要模糊处理多个文件,请使用此选项。
# 此选项有助于避免这些文件的全局标识符之间的冲突。每个文件的前缀应该不同。
identifiersPrefix: '',
ignoreImports: false,
# 许使用源代码设置输入文件的名称。此名称将在内部用于源映射生成。
inputFileName: '',
# 允许将信息记录到控制台。
log: false,
# 启用数字转换为表达式:数字等于一大串字符相加
numbersToExpressions: false,
# 允许设置预设选项。可选选项:
# default;
# low-obfuscation;
# medium-obfuscation;
# high-obfuscation.
optionsPreset: 'default',
# 使用声明启用全局变量和函数名的模糊处理。
renameGlobals: false,
# 启用属性名称的重命名。所有built-inDOM属性和核心JavaScript类中的属性都将被忽略。
# 要设置重命名属性名的格式,请使用identifierNamesGenerator选项。
# 要控制将重命名哪些属性,请使用reservedNames选项。
renameProperties: false,
renamePropertiesMode: 'safe',
# 禁用由传递的RegExp模式匹配的混淆和标识符生成。
reservedNames: [],
# 禁用由传递的RegExp模式匹配的字符串文本的转换。
reservedStrings: [],
# 此选项为随机生成器设置种子。这对于创建可重复的结果非常有用。
# 如果种子是0-随机生成器将在没有种子的情况下工作。
seed: 0,
# 使用此选项进行模糊处理后,请不要以任何方式更改混淆的代码,
# 因为任何类似代码丑陋的更改都会触发自我保护,代码将不再工作!
# 此选项使输出代码对格式化和变量重命名具有弹性。
# 如果一个人试图在模糊的代码上使用JavaScript美化器,
# 此选项强制将compact值设置为true
# 代码将不再工作,这使得理解和修改它变得更加困难。
# 防止格式化
selfDefending: false,
simplify: true,
# 启用模糊代码的源映射生成。
# 源代码映射可以帮助您调试模糊的JavaScript源代码。如果希望或需要在生产环境中调试,
# 可以将单独的源映射文件上载到一个秘密位置,然后将浏览器指向该位置。
sourceMap: false,
# 当sourceMapMode: 'separate'时,将基url设置为源映射导入url。
sourceMapBaseUrl: '',
# 设置sourceMapMode: 'separate'时输出源映射的文件名。
sourceMapFileName: '',
sourceMapMode: 'separate',
sourceMapSourcesMode: 'sources-content',
# {strings}长度为48的字符串,拆分成文本长度为970的文本块
splitStrings: false,
# 设置splitStrings选项的块长度。
splitStringsChunkLength: 10,
# 移除字符串文字并将其放入特殊数组中。
# 例如,var m = "Hello World";
# 中的字符串"Hello World"将替换为var m = _0x12c456[0x1];
stringArray: true,
stringArrayCallsTransform: true,
stringArrayCallsTransformThreshold: 0.5,
# stringArray选项必须启用
# 此选项会减慢脚本的速度。
# 使用base64或rc4对stringArray的所有字符串文本进行编码,
# 并插入一个在运行时用于解码的特殊代码。
# 每个stringArray值将由从传递的列表中随机选取的编码进行编码。
# 这使得使用多个编码成为可能。
stringArrayEncoding: [],
stringArrayIndexesType: [
'hexadecimal-number'
],
stringArrayIndexShift: true,
stringArrayRotate: true,
stringArrayShuffle: true,
stringArrayWrappersCount: 1,
stringArrayWrappersChainedCalls: true,
stringArrayWrappersParametersMaxCount: 2,
stringArrayWrappersType: 'variable',
stringArrayThreshold: 0.75,
# 允许为模糊代码设置目标环境
target: 'browser',
# 启用对象键的转换。
transformObjectKeys: false,
# 允许启用/禁用字符串转换为unicode转义序列。
# Unicode转义序列大大增加了代码的大小,
# 字符串可以很容易地恢复到其原始视图。建议仅对小源代码启用此选项。
unicodeEscapeSequence: false
}
文案
你能看出来这段代码什么意思吗?
你能看出来这段代码其实是计算一加一并输出吗?
后续我会将代码放在简介,需要直取