對應加密選項:
此選項主要的作用就是"刪除字符串文字並將其放置在特殊數組中。例如,在var m =“ Hello World”中的字符串“ Hello World”;將替換爲對將在運行時檢索其值的函數的調用,例如:var m = _0xb0c3('0x1');".
下邊我們來一一進行測試。
使用源碼:
// Paste your JavaScript code here
function hi() {
console.log("Hello World!");
document.write("Hello World!")
console.log("test1111");
document.write("<h1>xxxx</h1>")
console.log("test33333");
console.log("111test");
console.log("22test11");
document.write("Hello 22test11")
}
hi();
1.使用選項[String Array]
混淆後代碼爲:
var _0x21af = [
'write',
'<h1>xxxx</h1>',
'test1111',
'Hello\x20World!',
'22test11',
'test33333',
'111test',
'Hello\x2022test11',
'log'
];
var _0x13c7 = function (_0x21af39, _0x13c7e6) {
_0x21af39 = _0x21af39 - 0x0;
var _0x1d5715 = _0x21af[_0x21af39];
return _0x1d5715;
};
function hi() {
console[_0x13c7('0x8')](_0x13c7('0x3'));
document[_0x13c7('0x0')](_0x13c7('0x3'));
console[_0x13c7('0x8')](_0x13c7('0x2'));
document[_0x13c7('0x0')](_0x13c7('0x1'));
console[_0x13c7('0x8')](_0x13c7('0x5'));
console[_0x13c7('0x8')](_0x13c7('0x6'));
console[_0x13c7('0x8')](_0x13c7('0x4'));
document[_0x13c7('0x0')](_0x13c7('0x7'));
}
hi();
這個是最簡單的情況,就是把源碼中的字符串和一些函數名抽取出來,放在一個字符串數組(_0x21af )中,然後通過函數_0x13c7來獲取具體的字符串,調用函數時傳入的參數就是原字符串在數組中的下標。
此時_0x13c7('0x8')等價於_0x21af[8]
2.使用選項[String Array][Rotate String Array]
混淆後代碼爲:
var _0x3ae6 = [
'111test',
'22test11',
'Hello\x2022test11',
'log',
'Hello\x20World!',
'write',
'test1111',
'<h1>xxxx</h1>',
'test33333'
];
(function (_0x4ee67b, _0x3ae658) {
var _0x127781 = function (_0x42f296) {
while (--_0x42f296) {
_0x4ee67b['push'](_0x4ee67b['shift']());
}
};
_0x127781(++_0x3ae658);
}(_0x3ae6, 0x78));
var _0x1277 = function (_0x4ee67b, _0x3ae658) {
_0x4ee67b = _0x4ee67b - 0x0;
var _0x127781 = _0x3ae6[_0x4ee67b];
return _0x127781;
};
function hi() {
console[_0x1277('0x0')](_0x1277('0x1'));
document[_0x1277('0x2')](_0x1277('0x1'));
console[_0x1277('0x0')](_0x1277('0x3'));
document[_0x1277('0x2')](_0x1277('0x4'));
console[_0x1277('0x0')](_0x1277('0x5'));
console[_0x1277('0x0')](_0x1277('0x6'));
console[_0x1277('0x0')](_0x1277('0x7'));
document[_0x1277('0x2')](_0x1277('0x8'));
}
hi();
相比較上一個選項,[1]數組中字符串的順序變了,另外就是多了一個[2]自執行函數:
(function (_0x4ee67b, _0x3ae658) {
var _0x127781 = function (_0x42f296) {
while (--_0x42f296) {
_0x4ee67b['push'](_0x4ee67b['shift']());
}
};
_0x127781(++_0x3ae658);
}(_0x3ae6, 0x78));
此函數相當於:
fuction rotate_string_array(stringArray,nCount){
while(--nCount){
//JavaScript Array對象 shift() 方法用於把數組的第一個元素從其中刪除,並返回第一個元素的值。
//JavaScript Array對象 push() 方法可向數組的末尾添加一個或多個元素,並返回新的長度。
stringArray.push(stringArray.shift()));
}
}
rotate_string_array(_0x3ae6,0x78+1);
有了上邊的兩點改變([1][2]),此時_0x1277('0x0') 不等於 _0x3ae6[0]
兩者下標的轉化:
_0x1277('0x0') 相當於_0x3ae6[(('0x0')-0)+(0x78)%(_0x3ae6.length)))%(_0x3ae6.length))]:
'0x0' 即函數_0x1277的參數
(0x78) 即上邊自執行函數的參數
_0x3ae6.length 即數組的長度
帶入以上數據:
((('0x0')-0)+((0x78)%9))%9=3
即_0x1277('0x0') 等於 _0x3ae6[3]
有了這個下標換算關係,還原代碼就不難了。
3.使用選項[String Array][Rotate String Array][shuffle string array]
混淆後代碼爲:
var _0x634e = [
'test33333',
'22test11',
'Hello\x2022test11',
'111test',
'Hello\x20World!',
'write',
'<h1>xxxx</h1>',
'test1111',
'log'
];
(function (_0x433e72, _0x634ef5) {
var _0x152507 = function (_0x544bf0) {
while (--_0x544bf0) {
_0x433e72['push'](_0x433e72['shift']());
}
};
_0x152507(++_0x634ef5);
}(_0x634e, 0x17e));
var _0x1525 = function (_0x433e72, _0x634ef5) {
_0x433e72 = _0x433e72 - 0x0;
var _0x152507 = _0x634e[_0x433e72];
return _0x152507;
};
function hi() {
console[_0x1525('0x4')](_0x1525('0x0'));
document[_0x1525('0x1')](_0x1525('0x0'));
console[_0x1525('0x4')](_0x1525('0x3'));
document[_0x1525('0x1')](_0x1525('0x2'));
console[_0x1525('0x4')](_0x1525('0x5'));
console[_0x1525('0x4')](_0x1525('0x8'));
console[_0x1525('0x4')](_0x1525('0x6'));
document[_0x1525('0x1')](_0x1525('0x7'));
}
hi();
這個選項相比較之前只是打亂了字符串數組中字符串的位置,下標換算關係跟之前還是一樣。
4.使用選項[String Array][Rotate String Array][shuffle string array][string array encoding:base64]
混淆後代碼爲:
var _0x5093 = [
'dGVzdDMzMzMz',
'MTExdGVzdA==',
'd3JpdGU=',
'SGVsbG8gMjJ0ZXN0MTE=',
'PGgxPnh4eHg8L2gxPg==',
'MjJ0ZXN0MTE=',
'SGVsbG8gV29ybGQh',
'dGVzdDExMTE=',
'bG9n'
];
(function (_0x557504, _0x509305) {
var _0x195119 = function (_0x2a222e) {
while (--_0x2a222e) {
_0x557504['push'](_0x557504['shift']());
}
};
_0x195119(++_0x509305);
}(_0x5093, 0x1cb));
var _0x1951 = function (_0x557504, _0x509305) {
_0x557504 = _0x557504 - 0x0;
var _0x195119 = _0x5093[_0x557504];
if (_0x1951['EeSWAF'] === undefined) {
(function () {
var _0x207782;
try {
var _0xd7f008 = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
_0x207782 = _0xd7f008();
} catch (_0x50ca91) {
_0x207782 = window;
}
var _0x36900f = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
_0x207782['atob'] || (_0x207782['atob'] = function (_0x364904) {
var _0x22a035 = String(_0x364904)['replace'](/=+$/, '');
var _0x43ab01 = '';
for (var _0x14a02b = 0x0, _0x39723d, _0x547739, _0x3ea29c = 0x0; _0x547739 = _0x22a035['charAt'](_0x3ea29c++); ~_0x547739 && (_0x39723d = _0x14a02b % 0x4 ? _0x39723d * 0x40 + _0x547739 : _0x547739, _0x14a02b++ % 0x4) ? _0x43ab01 += String['fromCharCode'](0xff & _0x39723d >> (-0x2 * _0x14a02b & 0x6)) : 0x0) {
_0x547739 = _0x36900f['indexOf'](_0x547739);
}
return _0x43ab01;
});
}());
_0x1951['yMWxia'] = function (_0x376d0d) {
var _0x62a356 = atob(_0x376d0d);
var _0x49d7e5 = [];
for (var _0x22b71c = 0x0, _0x15c3c = _0x62a356['length']; _0x22b71c < _0x15c3c; _0x22b71c++) {
_0x49d7e5 += '%' + ('00' + _0x62a356['charCodeAt'](_0x22b71c)['toString'](0x10))['slice'](-0x2);
}
return decodeURIComponent(_0x49d7e5);
};
_0x1951['YuGjOc'] = {};
_0x1951['EeSWAF'] = !![];
}
var _0x2a222e = _0x1951['YuGjOc'][_0x557504];
if (_0x2a222e === undefined) {
_0x195119 = _0x1951['yMWxia'](_0x195119);
_0x1951['YuGjOc'][_0x557504] = _0x195119;
} else {
_0x195119 = _0x2a222e;
}
return _0x195119;
};
function hi() {
console[_0x1951('0x8')](_0x1951('0x6'));
document[_0x1951('0x2')](_0x1951('0x6'));
console[_0x1951('0x8')](_0x1951('0x7'));
document[_0x1951('0x2')](_0x1951('0x4'));
console[_0x1951('0x8')](_0x1951('0x0'));
console[_0x1951('0x8')](_0x1951('0x1'));
console[_0x1951('0x8')](_0x1951('0x5'));
document[_0x1951('0x2')](_0x1951('0x3'));
}
hi();
與前一個選項相比:
1.字符串數組中的所有字符串全部變成base64加密後的字符串。
2.多了一個base64的類 _0x1951:
_0x1951['EeSWAF'] =true 是一個bool變量,主要控制類的初始化。
_0x1951['YuGjOc'] = {}; 是一個字典,裏邊的鍵是序號,值是解密後的數據
_0x1951['yMWxia'] 相當於base64.decode函數
此時的換算關係:
_0x1951(index)=base64.decode(_0x5093[(index+0x1cb%_0x5093.length)%_0x5093.length])
5.使用選項[String Array][Rotate String Array][shuffle string array][string array encoding:RC4]
混淆後代碼爲:
var _0x4ad7 = [
'wpvCq8OSwqXCiGM3Zg==',
'YcKFwpjDmk0Mwq7DhwfDlMOww4XCthE=',
'w6XDvcO5',
'wrvDkyg=',
'wrc9w6TDjhg=',
'MX84wozCmcKpw49zUMKMwrbDtQ==',
'ZMOWwqQ=',
'EMKdC3JZH8OXNnLDkTbDjV0=',
'w6fCjRXCicKTw5vDtMKywrY=',
'w5AAwoFKLsOxJQ==',
'wptvwpJtJw==',
'XsKSwp3Dgkc=',
'QMKaXQ==',
'F8K8ZcKnw6Bgw4QZwrcqwrTCow==',
'HMKVw7jCssOmw5/Co8KW',
'QMOWBA=='
];
(function (_0x3f83d1, _0x4ad746) {
var _0x394a0f = function (_0x2c6096) {
while (--_0x2c6096) {
_0x3f83d1['push'](_0x3f83d1['shift']());
}
};
_0x394a0f(++_0x4ad746);
}(_0x4ad7, 0x16f));
var _0x394a = function (_0x3f83d1, _0x4ad746) {
_0x3f83d1 = _0x3f83d1 - 0x0;
var _0x394a0f = _0x4ad7[_0x3f83d1];
if (_0x394a['FkjqSs'] === undefined) {
(function () {
var _0x76ef1c = function () {
var _0xae539f;
try {
_0xae539f = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');')();
} catch (_0x4d3156) {
_0xae539f = window;
}
return _0xae539f;
};
var _0x424f4c = _0x76ef1c();
var _0x5ccca1 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
_0x424f4c['atob'] || (_0x424f4c['atob'] = function (_0x5f1fa6) {
var _0x3bf491 = String(_0x5f1fa6)['replace'](/=+$/, '');
var _0x350fd8 = '';
for (var _0xc02741 = 0x0, _0x253fdf, _0x322cae, _0xc1ae51 = 0x0; _0x322cae = _0x3bf491['charAt'](_0xc1ae51++); ~_0x322cae && (_0x253fdf = _0xc02741 % 0x4 ? _0x253fdf * 0x40 + _0x322cae : _0x322cae, _0xc02741++ % 0x4) ? _0x350fd8 += String['fromCharCode'](0xff & _0x253fdf >> (-0x2 * _0xc02741 & 0x6)) : 0x0) {
_0x322cae = _0x5ccca1['indexOf'](_0x322cae);
}
return _0x350fd8;
});
}());
var _0x56f8f9 = function (_0x493d85, _0x33f860) {
var _0x37e233 = [], _0x2e2f97 = 0x0, _0x5ce7e9, _0x29536e = '', _0xb9cb80 = '';
_0x493d85 = atob(_0x493d85);
for (var _0x26a45f = 0x0, _0x483193 = _0x493d85['length']; _0x26a45f < _0x483193; _0x26a45f++) {
_0xb9cb80 += '%' + ('00' + _0x493d85['charCodeAt'](_0x26a45f)['toString'](0x10))['slice'](-0x2);
}
_0x493d85 = decodeURIComponent(_0xb9cb80);
var _0x4f18e0;
for (_0x4f18e0 = 0x0; _0x4f18e0 < 0x100; _0x4f18e0++) {
_0x37e233[_0x4f18e0] = _0x4f18e0;
}
for (_0x4f18e0 = 0x0; _0x4f18e0 < 0x100; _0x4f18e0++) {
_0x2e2f97 = (_0x2e2f97 + _0x37e233[_0x4f18e0] + _0x33f860['charCodeAt'](_0x4f18e0 % _0x33f860['length'])) % 0x100;
_0x5ce7e9 = _0x37e233[_0x4f18e0];
_0x37e233[_0x4f18e0] = _0x37e233[_0x2e2f97];
_0x37e233[_0x2e2f97] = _0x5ce7e9;
}
_0x4f18e0 = 0x0;
_0x2e2f97 = 0x0;
for (var _0x3ffe3c = 0x0; _0x3ffe3c < _0x493d85['length']; _0x3ffe3c++) {
_0x4f18e0 = (_0x4f18e0 + 0x1) % 0x100;
_0x2e2f97 = (_0x2e2f97 + _0x37e233[_0x4f18e0]) % 0x100;
_0x5ce7e9 = _0x37e233[_0x4f18e0];
_0x37e233[_0x4f18e0] = _0x37e233[_0x2e2f97];
_0x37e233[_0x2e2f97] = _0x5ce7e9;
_0x29536e += String['fromCharCode'](_0x493d85['charCodeAt'](_0x3ffe3c) ^ _0x37e233[(_0x37e233[_0x4f18e0] + _0x37e233[_0x2e2f97]) % 0x100]);
}
return _0x29536e;
};
_0x394a['ZISiij'] = _0x56f8f9;
_0x394a['uXgOrO'] = {};
_0x394a['FkjqSs'] = !![];
}
var _0x2c6096 = _0x394a['uXgOrO'][_0x3f83d1];
if (_0x2c6096 === undefined) {
if (_0x394a['MJufIp'] === undefined) {
_0x394a['MJufIp'] = !![];
}
_0x394a0f = _0x394a['ZISiij'](_0x394a0f, _0x4ad746);
_0x394a['uXgOrO'][_0x3f83d1] = _0x394a0f;
} else {
_0x394a0f = _0x2c6096;
}
return _0x394a0f;
};
function hi() {
console[_0x394a('0x0', 'aimw')](_0x394a('0x6', '*DW8'));
document[_0x394a('0x5', 'L*Y]')](_0x394a('0xe', 'Z9#C'));
console[_0x394a('0xd', ']GOz')](_0x394a('0x1', 'KQ#T'));
document[_0x394a('0xb', 'a%Hx')](_0x394a('0x8', ']GOz'));
console[_0x394a('0x3', '@abs')](_0x394a('0x9', '!dX$'));
console[_0x394a('0x7', ')NGv')](_0x394a('0xa', 'z4uj'));
console[_0x394a('0x4', '4Ece')](_0x394a('0xf', '@he@'));
document[_0x394a('0xc', '2RVh')](_0x394a('0x2', '2RVh'));
}
hi();
與前一個選項相比:
1.字符串數組中的所有字符串全部變成先rc4加密然後base64加密的字符串。
2.多了一個base64_Rc4的類 _0x394a :
_0x394a ['FkjqSs'] =true 是一個bool變量,主要控制類的初始化。
_0x394a ['uXgOrO'] = {}; 是一個字典,裏邊的鍵是序號,值是解密後的數據
_0x394a ['ZISiij'] 相當於rc4.decode(base64.decode(index),key)函數
此時的換算關係:
0x16f:fun(_0x4ad7, 0x16f)); 某匿名函數的值
_0x394a(index='0x0', key'aimw')=rc4.decode(base64.decode(_0x4ad7[(index+0x16f%_0x4ad7.length)%_0x4ad7.length]),key)
多了個rc4,其他無變化。
另外,根據文檔介紹,RC4選項比Base64選項慢大約30-35%,因此使用這個加密的應該不多。特別是庫文件。
4.使用選項[String Array][Rotate String Array][shuffle string array][string array encoding:base64][Split Strings Chunk Length:3]
混淆後代碼爲:
var _0x10f8 = [
'MjJ0',
'SGVs',
'bGQh',
'V29y',
'eHg8',
'dGVz',
'd3Jp',
'L2gx',
'ZXN0',
'MzMz',
'dDEx',
'PGgx',
'bG8g',
'Pnh4',
'MTEx',
'dDMz',
'bG9n'
];
(function (_0x9f2e7f, _0x10f8ac) {
var _0x83553e = function (_0x499d45) {
while (--_0x499d45) {
_0x9f2e7f['push'](_0x9f2e7f['shift']());
}
};
_0x83553e(++_0x10f8ac);
}(_0x10f8, 0x8d));
var _0x8355 = function (_0x9f2e7f, _0x10f8ac) {
_0x9f2e7f = _0x9f2e7f - 0x0;
var _0x83553e = _0x10f8[_0x9f2e7f];
if (_0x8355['mAxMIN'] === undefined) {
(function () {
var _0x7e1e19;
try {
var _0x5864ff = Function('return\x20(function()\x20' + '{}.constructor(\x22return\x20this\x22)(\x20)' + ');');
_0x7e1e19 = _0x5864ff();
} catch (_0x56e058) {
_0x7e1e19 = window;
}
var _0x5bbe45 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
_0x7e1e19['atob'] || (_0x7e1e19['atob'] = function (_0x4cb980) {
var _0x4eb69e = String(_0x4cb980)['replace'](/=+$/, '');
var _0x351318 = '';
for (var _0x2e02e7 = 0x0, _0x14f3ca, _0x501ae4, _0x2ad81c = 0x0; _0x501ae4 = _0x4eb69e['charAt'](_0x2ad81c++); ~_0x501ae4 && (_0x14f3ca = _0x2e02e7 % 0x4 ? _0x14f3ca * 0x40 + _0x501ae4 : _0x501ae4, _0x2e02e7++ % 0x4) ? _0x351318 += String['fromCharCode'](0xff & _0x14f3ca >> (-0x2 * _0x2e02e7 & 0x6)) : 0x0) {
_0x501ae4 = _0x5bbe45['indexOf'](_0x501ae4);
}
return _0x351318;
});
}());
_0x8355['TivOUi'] = function (_0xb1759e) {
var _0x4a1351 = atob(_0xb1759e);
var _0x27b605 = [];
for (var _0x4053ee = 0x0, _0x148843 = _0x4a1351['length']; _0x4053ee < _0x148843; _0x4053ee++) {
_0x27b605 += '%' + ('00' + _0x4a1351['charCodeAt'](_0x4053ee)['toString'](0x10))['slice'](-0x2);
}
return decodeURIComponent(_0x27b605);
};
_0x8355['BxgXBm'] = {};
_0x8355['mAxMIN'] = !![];
}
var _0x499d45 = _0x8355['BxgXBm'][_0x9f2e7f];
if (_0x499d45 === undefined) {
_0x83553e = _0x8355['TivOUi'](_0x83553e);
_0x8355['BxgXBm'][_0x9f2e7f] = _0x83553e;
} else {
_0x83553e = _0x499d45;
}
return _0x83553e;
};
function hi() {
console[_0x8355('0xb')](_0x8355('0xd') + _0x8355('0x7') + _0x8355('0xf') + _0x8355('0xe'));
document[_0x8355('0x1') + 'te'](_0x8355('0xd') + _0x8355('0x7') + _0x8355('0xf') + _0x8355('0xe'));
console[_0x8355('0xb')](_0x8355('0x0') + _0x8355('0x5') + '11');
document[_0x8355('0x1') + 'te'](_0x8355('0x6') + _0x8355('0x8') + _0x8355('0x10') + _0x8355('0x2') + '>');
console[_0x8355('0xb')](_0x8355('0x0') + _0x8355('0xa') + _0x8355('0x4'));
console[_0x8355('0xb')](_0x8355('0x9') + _0x8355('0x0') + 't');
console[_0x8355('0xb')](_0x8355('0xc') + _0x8355('0x3') + '11');
document[_0x8355('0x1') + 'te'](_0x8355('0xd') + _0x8355('0x7') + _0x8355('0xc') + _0x8355('0x3') + '11');
}
hi();
這個就是先把字符串按照設置的值分割,然後再加密放入數組中。
比如write 3個字符分割,則分割爲兩部分 wri 和te
wri加密後放入數組。
還原方法還是一樣。
至於剩下的選項:
1.Transform Object Keys 轉換對象鍵
Transforms (obfuscates) object keys.轉換(混淆)對象鍵。
For instance, this code var a = {enabled: true}; when obfuscated with this option will hide the enabled object key: var a = {}; a[_0x2ae0[('0x0')] = true;.例如,這段代碼var a = {enabled:true}; 當對此選項進行混淆時,將隱藏啓用的對象鍵:var a = {}; a [_0x2ae0 [('0x0')] = true;。
See the official documentation of the JavaScript Obfuscator on GitHub for a full example.有關完整示例,請參見GitHub上的JavaScript Obfuscator的官方文檔。
2.Escape Unicode Sequence
轉義Unicode序列
Converts all the strings to their unicode representation. For instance, the string "Hello World!" will be converted to "'\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21".將所有字符串轉換爲它們的unicode表示形式。 例如,字符串“ Hello World!”。 將被轉換爲“'\ x48 \ x65 \ x6c \ x6c \ x6f \ x20 \ x57 \ x6f \ x72 \ x6c \ x64 \ x21”。
This convertion is pretty easy to revert, and will increase the obfuscated code size greatly. It's not recommended on larger code bases.此轉換非常容易還原,並且將大大增加混淆的代碼大小。 不建議在較大的代碼庫中使用。
只是起到輔助作用,不再一一測試。