Babel ob 混淆初体验
前言
看完前面 Babel AST 入门 相关文章,接下来我们就可以进行初步实战了。
本次使用的ob混淆加密工具为 https://obfuscator.io/
为避免混淆工具更新,导致解密代码失效,本次会将混淆后代码贴出来
混淆工具不更新的情况下,每次混淆只是变量名的不同,不影响还原逻辑
混淆工具选择的混淆选择应该是选择了,控制流平坦化、无限debugger、禁用控制台输出、字面量混淆这些…
( 当时没记录 (;´д`)ゞ )
混淆前代码
function hi() {
console.log("Hello World! -- 1");
console.log("Hello World! -- 3");
console.log("Hello World! -- 2");
console.log("Hello World! -- 7");
console.log("Hello World! -- 5");
}
hi();
混淆后代码
var _0x10aa = [
'lqbiq',
'ZRPcV',
'kThfF',
'yzwhA',
'tgeUk',
'rlZLk',
'SYcbT',
'WqBcw',
'CIduL',
'bfNAb',
'ydRMV',
'Hello\x20World!\x20--\x201',
'rHHqr',
'fGdeW',
'uxCcx',
'GTBJA',
'cgSJr',
'info',
'__proto__',
'WNtTb',
'debu',
'while\x20(true)\x20{}',
'rTsVe',
'UgimS',
'Hello\x20World!\x20--\x202',
'oCpcz',
'1241887KbwHqJ',
'JljdB',
'fzczY',
'IFbeF',
'mbKXe',
'dIHAr',
'ggGcu',
'FEvuL',
'PlBxC',
'IbQbN',
'WmeIV',
'VQTji',
'ZGhWM',
'IJOWz',
'RtMXE',
'WCQrQ',
'OmqvR',
'SBcEP',
'AzXvb',
'FVson',
'ebRIL',
'nEJsk',
'biEcf',
'UEzeA',
'vqfyK',
'sMmso',
'NmrXO',
'PPHti',
'Xnrdn',
'puvkf',
'4353103ULsZSv',
'SJdsb',
'Hello\x20World!\x20--\x207',
'console',
'Hckxx',
'chain',
'hwfYq',
'trace',
'aaoym',
'mXEjm',
'XEjQO',
'jHznp',
'eZxHn',
'bind',
'split',
'Hello\x20World!\x20--\x203',
'pZzcK',
'JaSZv',
'ZoVtY',
'VApmr',
'DvniI',
'YNcMS',
'string',
'1044319vCMUxz',
'length',
'Jypfh',
'VOfDu',
'TnUSx',
'mLnFq',
'init',
'TxDIh',
'kUFev',
'{}.constructor(\x22return\x20this\x22)(\x20)',
'FZKfz',
'WdQOP',
'fTNix',
'FRogI',
'TtPdw',
'xqoiL',
'ngrEl',
'LAABi',
'yKDoc',
'xgzNd',
'293SOKzVA',
'DHHoH',
'apply',
'LUNPS',
'ivlvH',
'test',
'gMwYt',
'table',
'MAGyJ',
'1SrUziC',
'HVPGn',
'LkRDN',
'qgzpI',
'EKMqr',
'287434QBHjSi',
'TSfpe',
'ZXuHB',
'aMxJk',
'uBGnv',
'ereFE',
'call',
'fCGZF',
'ZTXYR',
'OHvIw',
'JzLCq',
'input',
'dqyLq',
'5|4|3|0|2|1',
'hLnZh',
'1wuWDdK',
'Hello\x20World!\x20--\x205',
'PFjgK',
'138197KVnzmI',
'czvER',
'xVWCQ',
'wCKlx',
'LkPlz',
'KFFeo',
'nJBjp',
'constructor',
'action',
'MKDzx',
'aEdOf',
'prototype',
'xILnF',
'1266908BbEiwa',
'NAhKN',
'gnOAX',
'ZUepL',
'ZvttO',
'uaPor',
'WsKHN',
'log',
'bXyCm',
'UsXiD',
'nopYH',
'dIaGX',
'dVQde',
'sUaCg',
'toString',
'xgGyu',
'warn',
'oXSfB',
'kRYid',
'yXfpm',
'kSwZh',
'return\x20(function()\x20',
'eFDLX',
'function\x20*\x5c(\x20*\x5c)',
'lumKu',
'mKPoZ',
'HaTjs',
'85hPkpJj',
'QGAlh',
'DrfUQ',
'dnUmD',
'stateObject',
'bdBbR',
'pigLe'
];
(function (_0x5ee3a5, _0x4f8444) {
var _0x4b27eb = _0x5880;
while (!![]) {
try {
var _0x35f0f0 = -parseInt(_0x4b27eb(0x1e4)) * -parseInt(_0x4b27eb(0x17a)) + -parseInt(_0x4b27eb(0x211)) + -parseInt(_0x4b27eb(0x19b)) + parseInt(_0x4b27eb(0x204)) + parseInt(_0x4b27eb(0x1d0)) * -parseInt(_0x4b27eb(0x1ed)) + -parseInt(_0x4b27eb(0x1f2)) + -parseInt(_0x4b27eb(0x1b9)) * -parseInt(_0x4b27eb(0x201));
if (_0x35f0f0 === _0x4f8444) {
break;
} else {
_0x5ee3a5['push'](_0x5ee3a5['shift']());
}
} catch (_0x3ac058) {
_0x5ee3a5['push'](_0x5ee3a5['shift']());
}
}
}(_0x10aa, -0x13c3 * -0x97 + 0xd35b4 + -0xe8e70));
function _0x5880(_0x2e1a9e, _0x55b414) {
_0x5880 = function (_0x1917f0, _0x10aaec) {
_0x1917f0 = _0x1917f0 - (0x12b7 + 0x4 * 0x815 + -0x3192);
var _0x58807e = _0x10aa[_0x1917f0];
return _0x58807e;
};
return _0x5880(_0x2e1a9e, _0x55b414);
}
function hi() {
var _0x2bf47b = _0x5880;
var _0x2653e1 = {
'dqyLq': function (_0x2400b0, _0x1b7149) {
return _0x2400b0(_0x1b7149);
},
'dIHAr': '3|4|2|0|5|1',
'eFDLX': function (_0x3f8236, _0xd445c8) {
return _0x3f8236 === _0xd445c8;
},
'Dyvtx': _0x2bf47b(0x224),
'jHJtf': function (_0x57fc71, _0x2fde41) {
return _0x57fc71 !== _0x2fde41;
},
'nJBjp': _0x2bf47b(0x21b),
'rTsVe': function (_0x11cb5a) {
return _0x11cb5a();
},
'tVPhg': function (_0x9f5a8b, _0x3202f3) {
return _0x9f5a8b === _0x3202f3;
},
'FVson': _0x2bf47b(0x185),
'puvkf': function (_0xf1cbca, _0xff8cd5) {
return _0xf1cbca(_0xff8cd5);
},
'xgGyu': function (_0x86419a, _0x2f075e) {
return _0x86419a !== _0x2f075e;
},
'QMrBs': 'iwpDu',
'hwfYq': _0x2bf47b(0x228),
'yKDoc': '\x5c+\x5c+\x20*(?:[a-zA-Z_$][0-9a-zA-Z_$]*)',
'aEdOf': _0x2bf47b(0x1d6),
'CrHhv': function (_0x88fc29, _0x4455ea) {
return _0x88fc29 + _0x4455ea;
},
'WNtTb': _0x2bf47b(0x1be),
'aMxJk': _0x2bf47b(0x1fd),
'dVQde': function (_0x15bb4e, _0x51af70) {
return _0x15bb4e === _0x51af70;
},
'HqMRb': _0x2bf47b(0x1df),
'OHvIw': _0x2bf47b(0x222),
'eZxHn': function (_0x6ccace, _0xfab03, _0x4d3d1e) {
return _0x6ccace(_0xfab03, _0x4d3d1e);
},
'xVWCQ': function (_0x5b871c, _0x4c31d8) {
return _0x5b871c(_0x4c31d8);
},
'gnOAX': function (_0x34602e, _0x208c9b) {
return _0x34602e + _0x208c9b;
},
'UgimS': function (_0x51b4d4, _0x17c5f9) {
return _0x51b4d4(_0x17c5f9);
},
'bdBbR': function (_0x3e1898) {
return _0x3e1898();
},
'pZzcK': function (_0x538a76, _0x178dc3) {
return _0x538a76 === _0x178dc3;
},
'rHLMj': _0x2bf47b(0x18b),
'SJdsb': _0x2bf47b(0x1f3),
'czvER': _0x2bf47b(0x229),
'iUYes': 'YIbHI',
'fTNix': _0x2bf47b(0x209),
'aaoym': _0x2bf47b(0x1d4),
'ZGhWM': function (_0x5c85ac, _0x4d1292) {
return _0x5c85ac + _0x4d1292;
},
'IbQbN': function (_0x34337e, _0x4229a9) {
return _0x34337e + _0x4229a9;
},
'mbKXe': function (_0x596923) {
return _0x596923();
},
'MAGyJ': function (_0x3909d, _0x227726) {
return _0x3909d(_0x227726);
},
'JzLCq': _0x2bf47b(0x1e7),
'bfNAb': _0x2bf47b(0x1f1),
'cgSJr': _0x2bf47b(0x226),
'PmvEI': _0x2bf47b(0x1d9),
'ZRPcV': function (_0x4d5140) {
return _0x4d5140();
},
'rHHqr': _0x2bf47b(0x1ef),
'LkPlz': _0x2bf47b(0x1a1),
'YrDFt': _0x2bf47b(0x218),
'TLdpb': _0x2bf47b(0x221),
'JljdB': _0x2bf47b(0x192),
'uBGnv': 'error',
'ZvttO': 'exception',
'DrfUQ': _0x2bf47b(0x1eb),
'WCQrQ': _0x2bf47b(0x1c0),
'FRogI': function (_0xedc221, _0x22bcb6) {
return _0xedc221 < _0x22bcb6;
},
'upcQq': _0x2bf47b(0x1ff),
'WsKHN': function (_0x1f9a5f) {
return _0x1f9a5f();
},
'TtPdw': _0x2bf47b(0x18c),
'NAhKN': _0x2bf47b(0x1c8),
'MKDzx': _0x2bf47b(0x199),
'FEvuL': _0x2bf47b(0x1bb),
'FZKfz': _0x2bf47b(0x202)
};
var _0x1e3d10 = function () {
var _0x59a651 = _0x2bf47b;
var _0x4bab73 = {
'mLnFq': function (_0x1a9827, _0x4f74d1) {
var _0x33d7e8 = _0x5880;
return _0x2653e1[_0x33d7e8(0x1fe)](_0x1a9827, _0x4f74d1);
},
'hLnZh': _0x2653e1[_0x59a651(0x1a0)],
'jHznp': function (_0x375abc, _0x1f4aea) {
var _0x455d2d = _0x59a651;
return _0x2653e1[_0x455d2d(0x227)](_0x375abc, _0x1f4aea);
},
'AzXvb': _0x2653e1['Dyvtx'],
'fGdeW': function (_0x395852, _0x29ddbb) {
return _0x2653e1['jHJtf'](_0x395852, _0x29ddbb);
},
'HaTjs': _0x2653e1[_0x59a651(0x20a)],
'DvniI': function (_0x58c4af) {
var _0xf93bbe = _0x59a651;
return _0x2653e1[_0xf93bbe(0x197)](_0x58c4af);
}
};
if (_0x2653e1['tVPhg'](_0x2653e1[_0x59a651(0x1ae)], _0x2653e1['FVson'])) {
var _0x4f217d = !![];
return function (_0x5949e2, _0x553e4b) {
var _0xa0954f = _0x59a651;
var _0x56dfc = {
'biEcf': _0x4bab73[_0xa0954f(0x200)],
'Hckxx': function (_0x1c5a17, _0x35d790) {
var _0x5d9617 = _0xa0954f;
return _0x4bab73[_0x5d9617(0x1c4)](_0x1c5a17, _0x35d790);
},
'nEJsk': _0x4bab73[_0xa0954f(0x1ad)]
};
if (_0x4bab73[_0xa0954f(0x18e)](_0x4bab73['HaTjs'], _0x4bab73[_0xa0954f(0x179)])) {
if (_0x2a9303) {
return _0x5f4be2;
} else {
NZpiYF[_0xa0954f(0x1d5)](_0x2e15e9, 0x2e9 + -0x1ba4 + 0x18bb);
}
} else {
var _0x3bb8c0 = _0x4f217d ? function () {
var _0x6e7727 = _0xa0954f;
var _0xfa4af8 = { 'JaSZv': _0x56dfc[_0x6e7727(0x1b1)] };
if (_0x553e4b) {
if (_0x56dfc[_0x6e7727(0x1bd)](_0x56dfc['nEJsk'], _0x56dfc[_0x6e7727(0x1b0)])) {
var _0x1a3791 = _0x553e4b[_0x6e7727(0x1e6)](_0x5949e2, arguments);
_0x553e4b = null;
return _0x1a3791;
} else {
var _0x5560c5 = _0xfa4af8[_0x6e7727(0x1ca)][_0x6e7727(0x1c7)]('|');
var _0x388428 = -0x2696 + 0x1 * 0x100a + 0x168c;
while (!![]) {
switch (_0x5560c5[_0x388428++]) {
case '0':
_0x5493d0[_0x6e7727(0x193)] = _0x4d40c0['bind'](_0x506772);
continue;
case '1':
_0x14defd[_0x482953] = _0x5493d0;
continue;
case '2':
var _0x1b1508 = _0xc19ff1[_0x482953] || _0x5493d0;
continue;
case '3':
var _0x5493d0 = _0x3a1ef2[_0x6e7727(0x20b)][_0x6e7727(0x20f)][_0x6e7727(0x1c6)](_0x3465d5);
continue;
case '4':
var _0x482953 = _0x98bc1[_0x5a2f1f];
continue;
case '5':
_0x5493d0['toString'] = _0x1b1508[_0x6e7727(0x21f)][_0x6e7727(0x1c6)](_0x1b1508);
continue;
}
break;
}
}
}
} : function () {
};
_0x4f217d = ![];
return _0x3bb8c0;
}
};
} else {
NZpiYF[_0x59a651(0x1cd)](_0x2fdd74);
}
}();
(function () {
var _0x2042d2 = _0x2bf47b;
var _0x12f291 = {
'SYcbT': function (_0x356c90, _0x47f36f) {
var _0x1e3214 = _0x5880;
return _0x2653e1[_0x1e3214(0x1b8)](_0x356c90, _0x47f36f);
},
'mKPoZ': function (_0x216a31, _0x209c16) {
var _0x19a0c7 = _0x5880;
return _0x2653e1[_0x19a0c7(0x220)](_0x216a31, _0x209c16);
},
'ZTXYR': _0x2653e1['QMrBs'],
'rlZLk': _0x2653e1['hwfYq'],
'GTBJA': _0x2653e1['yKDoc'],
'bXyCm': _0x2653e1[_0x2042d2(0x20e)],
'ebRIL': function (_0x288527, _0x392634) {
return _0x2653e1['CrHhv'](_0x288527, _0x392634);
},
'qgzpI': _0x2653e1[_0x2042d2(0x194)],
'TxDIh': _0x2653e1[_0x2042d2(0x1f5)],
'DHHoH': function (_0x3b9736, _0x90433f) {
var _0x547505 = _0x2042d2;
return _0x2653e1[_0x547505(0x21d)](_0x3b9736, _0x90433f);
},
'RdaYk': _0x2653e1['HqMRb'],
'MgHKt': _0x2653e1[_0x2042d2(0x1fb)],
'DjtsW': function (_0x13c85b) {
var _0x174644 = _0x2042d2;
return _0x2653e1[_0x174644(0x197)](_0x13c85b);
}
};
_0x2653e1[_0x2042d2(0x1c5)](_0x1e3d10, this, function () {
var _0xd56f62 = _0x2042d2;
var _0x38ee17 = {
'pigLe': function (_0x3045af, _0x44ee29) {
return _0x12f291['SYcbT'](_0x3045af, _0x44ee29);
}
};
if (_0x12f291[_0xd56f62(0x22a)](_0x12f291[_0xd56f62(0x1fa)], _0x12f291['ZTXYR'])) {
XVXhjh[_0xd56f62(0x180)](_0x101705, -0xbc3 + 0x44 * -0x6d + 0x28b7);
} else {
var _0x285632 = new RegExp(_0x12f291[_0xd56f62(0x186)]);
var _0x218809 = new RegExp(_0x12f291[_0xd56f62(0x190)], 'i');
var _0x50438e = _0x12f291[_0xd56f62(0x187)](_0x55b414, _0x12f291[_0xd56f62(0x219)]);
if (!_0x285632[_0xd56f62(0x1e9)](_0x12f291[_0xd56f62(0x1af)](_0x50438e, _0x12f291[_0xd56f62(0x1f0)])) || !_0x218809[_0xd56f62(0x1e9)](_0x12f291[_0xd56f62(0x1af)](_0x50438e, _0x12f291[_0xd56f62(0x1d7)]))) {
if (_0x12f291[_0xd56f62(0x1e5)](_0x12f291['RdaYk'], _0x12f291['MgHKt'])) {
var _0x4e2427 = _0x3b71d9 ? function () {
var _0x4e675f = _0xd56f62;
if (_0x3a72cd) {
var _0x5b529d = _0x189728[_0x4e675f(0x1e6)](_0x46712f, arguments);
_0x5c4623 = null;
return _0x5b529d;
}
} : function () {
};
_0xb46c3b = ![];
return _0x4e2427;
} else {
_0x12f291[_0xd56f62(0x187)](_0x50438e, '0');
}
} else {
_0x12f291['DjtsW'](_0x55b414);
}
}
})();
}());
var _0x15a0ee = function () {
var _0x5f52b8 = _0x2bf47b;
var _0x59c539 = {
'uxCcx': _0x2653e1[_0x5f52b8(0x1bf)],
'VZNjd': _0x2653e1[_0x5f52b8(0x1e2)],
'IFbeF': function (_0x442d69, _0x28894d) {
var _0x3d3116 = _0x5f52b8;
return _0x2653e1[_0x3d3116(0x206)](_0x442d69, _0x28894d);
},
'kUFev': _0x2653e1[_0x5f52b8(0x20e)],
'UsXiD': function (_0x562756, _0x1d020a) {
var _0x1aa8f0 = _0x5f52b8;
return _0x2653e1[_0x1aa8f0(0x213)](_0x562756, _0x1d020a);
},
'kThfF': _0x2653e1[_0x5f52b8(0x194)],
'WdQOP': _0x2653e1[_0x5f52b8(0x1f5)],
'Idfra': function (_0x558ff9, _0x3248fc) {
var _0x3b2746 = _0x5f52b8;
return _0x2653e1[_0x3b2746(0x198)](_0x558ff9, _0x3248fc);
},
'ZXuHB': function (_0xfd919e) {
var _0x390941 = _0x5f52b8;
return _0x2653e1[_0x390941(0x17f)](_0xfd919e);
},
'oCpcz': function (_0x145e35, _0x525288) {
var _0x5560f5 = _0x5f52b8;
return _0x2653e1[_0x5560f5(0x1c9)](_0x145e35, _0x525288);
},
'QGAlh': _0x2653e1['rHLMj'],
'WmeIV': _0x2653e1[_0x5f52b8(0x1ba)],
'sMmso': _0x2653e1[_0x5f52b8(0x205)],
'VApmr': _0x2653e1['iUYes']
};
if (_0x2653e1[_0x5f52b8(0x220)](_0x2653e1[_0x5f52b8(0x1dc)], _0x2653e1[_0x5f52b8(0x1c1)])) {
var _0x49048e = !![];
return function (_0x41b2c9, _0x5f48c6) {
var _0x1ef0a9 = _0x5f52b8;
var _0x1ef4e5 = {
'VDWTm': function (_0x1c8eb5, _0x722185) {
var _0x4f9b48 = _0x5880;
return _0x59c539[_0x4f9b48(0x19a)](_0x1c8eb5, _0x722185);
},
'sUaCg': _0x59c539[_0x1ef0a9(0x17b)],
'RtMXE': _0x59c539[_0x1ef0a9(0x1a5)]
};
if (_0x59c539[_0x1ef0a9(0x19a)](_0x59c539[_0x1ef0a9(0x1b4)], _0x59c539[_0x1ef0a9(0x1cc)])) {
var _0x3a56d1 = new _0x4de45f(ZTiJLr[_0x1ef0a9(0x18f)]);
var _0x52e7f3 = new _0x43d16a(ZTiJLr['VZNjd'], 'i');
var _0x3b18fe = ZTiJLr[_0x1ef0a9(0x19e)](_0x2a5807, ZTiJLr[_0x1ef0a9(0x1d8)]);
if (!_0x3a56d1[_0x1ef0a9(0x1e9)](ZTiJLr[_0x1ef0a9(0x21a)](_0x3b18fe, ZTiJLr[_0x1ef0a9(0x183)])) || !_0x52e7f3[_0x1ef0a9(0x1e9)](ZTiJLr['UsXiD'](_0x3b18fe, ZTiJLr[_0x1ef0a9(0x1db)]))) {
ZTiJLr['Idfra'](_0x3b18fe, '0');
} else {
ZTiJLr[_0x1ef0a9(0x1f4)](_0x570243);
}
} else {
var _0x15ed94 = _0x49048e ? function () {
var _0x3549ce = _0x1ef0a9;
if (_0x5f48c6) {
if (_0x1ef4e5['VDWTm'](_0x1ef4e5[_0x3549ce(0x21e)], _0x1ef4e5[_0x3549ce(0x1a9)])) {
return !![];
} else {
var _0x4c14a5 = _0x5f48c6[_0x3549ce(0x1e6)](_0x41b2c9, arguments);
_0x5f48c6 = null;
return _0x4c14a5;
}
}
} : function () {
};
_0x49048e = ![];
return _0x15ed94;
}
};
} else {
var _0x4230f6 = _0x20ced5[_0x5f52b8(0x1e6)](_0x284165, arguments);
_0x5b5dee = null;
return _0x4230f6;
}
}();
var _0x35ef4b = _0x2653e1['eZxHn'](_0x15a0ee, this, function () {
var _0x4b5d21 = _0x2bf47b;
var _0x15a93a = {
'PFjgK': function (_0x2c9ae1, _0x123127) {
var _0xdbb888 = _0x5880;
return _0x2653e1[_0xdbb888(0x1ec)](_0x2c9ae1, _0x123127);
}
};
if (_0x2653e1[_0x4b5d21(0x220)](_0x2653e1[_0x4b5d21(0x1fc)], _0x2653e1[_0x4b5d21(0x18a)])) {
var _0x50c7f1;
try {
var _0x52108e = _0x2653e1[_0x4b5d21(0x1ec)](Function, _0x2653e1[_0x4b5d21(0x1a4)](_0x2653e1[_0x4b5d21(0x1a4)](_0x2653e1[_0x4b5d21(0x191)], _0x2653e1['PmvEI']), ');'));
_0x50c7f1 = _0x2653e1[_0x4b5d21(0x182)](_0x52108e);
} catch (_0x5de9d7) {
if (_0x2653e1['xgGyu'](_0x2653e1[_0x4b5d21(0x18d)], _0x2653e1[_0x4b5d21(0x208)])) {
_0x50c7f1 = window;
} else {
var _0x1ef527 = {
'LAABi': UoaPdB[_0x4b5d21(0x1bf)],
'AycqB': UoaPdB[_0x4b5d21(0x1e2)],
'IpguG': function (_0x31aff7, _0x36b582) {
var _0x3d5774 = _0x4b5d21;
return UoaPdB[_0x3d5774(0x198)](_0x31aff7, _0x36b582);
},
'OmqvR': UoaPdB[_0x4b5d21(0x20e)],
'VOfDu': function (_0x155039, _0x18d4c7) {
var _0x27df64 = _0x4b5d21;
return UoaPdB[_0x27df64(0x1a7)](_0x155039, _0x18d4c7);
},
'CIduL': UoaPdB[_0x4b5d21(0x194)],
'pwVGF': function (_0x44d7c0, _0x395206) {
return UoaPdB['IbQbN'](_0x44d7c0, _0x395206);
},
'dnUmD': UoaPdB[_0x4b5d21(0x1f5)],
'ZoVtY': function (_0x353fd8) {
var _0x1fd50c = _0x4b5d21;
return UoaPdB[_0x1fd50c(0x19f)](_0x353fd8);
}
};
UoaPdB[_0x4b5d21(0x1c5)](_0x4929df, this, function () {
var _0x10d15f = _0x4b5d21;
var _0xd53afd = new _0x4a74f7(_0x1ef527[_0x10d15f(0x1e1)]);
var _0x32a5fb = new _0x57ab31(_0x1ef527['AycqB'], 'i');
var _0x4afcad = _0x1ef527['IpguG'](_0x490461, _0x1ef527[_0x10d15f(0x1ab)]);
if (!_0xd53afd[_0x10d15f(0x1e9)](_0x1ef527[_0x10d15f(0x1d3)](_0x4afcad, _0x1ef527[_0x10d15f(0x189)])) || !_0x32a5fb[_0x10d15f(0x1e9)](_0x1ef527['pwVGF'](_0x4afcad, _0x1ef527[_0x10d15f(0x17d)]))) {
_0x1ef527['IpguG'](_0x4afcad, '0');
} else {
_0x1ef527[_0x10d15f(0x1cb)](_0x4c89cc);
}
})();
}
}
var _0x40cd31 = _0x50c7f1[_0x4b5d21(0x1bc)] = _0x50c7f1[_0x4b5d21(0x1bc)] || {};
var _0x9c92be = [
_0x2653e1['YrDFt'],
_0x2653e1['TLdpb'],
_0x2653e1[_0x4b5d21(0x19c)],
_0x2653e1[_0x4b5d21(0x1f6)],
_0x2653e1[_0x4b5d21(0x215)],
_0x2653e1[_0x4b5d21(0x17c)],
_0x2653e1[_0x4b5d21(0x1aa)]
];
for (var _0x5f444f = -0x3 * 0x9ce + -0x17b4 * 0x1 + 0xd * 0x416; _0x2653e1[_0x4b5d21(0x1dd)](_0x5f444f, _0x9c92be[_0x4b5d21(0x1d1)]); _0x5f444f++) {
var _0xd7039d = _0x2653e1['upcQq'][_0x4b5d21(0x1c7)]('|');
var _0x37b213 = 0x10 * 0x9e + -0x1887 + 0x79 * 0x1f;
while (!![]) {
switch (_0xd7039d[_0x37b213++]) {
case '0':
_0x35f8de[_0x4b5d21(0x193)] = _0x15a0ee['bind'](_0x15a0ee);
continue;
case '1':
_0x40cd31[_0x451242] = _0x35f8de;
continue;
case '2':
_0x35f8de[_0x4b5d21(0x21f)] = _0x1ddfd['toString'][_0x4b5d21(0x1c6)](_0x1ddfd);
continue;
case '3':
var _0x1ddfd = _0x40cd31[_0x451242] || _0x35f8de;
continue;
case '4':
var _0x451242 = _0x9c92be[_0x5f444f];
continue;
case '5':
var _0x35f8de = _0x15a0ee['constructor'][_0x4b5d21(0x20f)]['bind'](_0x15a0ee);
continue;
}
break;
}
}
} else {
IheZhp[_0x4b5d21(0x203)](_0x5f1db9, '0');
}
});
_0x2653e1[_0x2bf47b(0x217)](_0x35ef4b);
console[_0x2bf47b(0x218)](_0x2653e1[_0x2bf47b(0x1de)]);
console['log'](_0x2653e1[_0x2bf47b(0x212)]);
console[_0x2bf47b(0x218)](_0x2653e1[_0x2bf47b(0x20d)]);
console[_0x2bf47b(0x218)](_0x2653e1[_0x2bf47b(0x1a2)]);
console[_0x2bf47b(0x218)](_0x2653e1[_0x2bf47b(0x1da)]);
}
hi();
function _0x55b414(_0x13e05f) {
var _0x4d42d1 = _0x5880;
var _0x352c68 = {
'ERpro': function (_0x3dce39, _0x180672) {
return _0x3dce39 !== _0x180672;
},
'lqbiq': _0x4d42d1(0x1b6),
'ereFE': function (_0x3201df, _0x1d221a) {
return _0x3201df + _0x1d221a;
},
'UEzeA': _0x4d42d1(0x195),
'ivlvH': 'gger',
'NmrXO': _0x4d42d1(0x20c),
'XEjQO': function (_0x56236f, _0x564e7a) {
return _0x56236f === _0x564e7a;
},
'gnoFH': _0x4d42d1(0x1ea),
'PlBxC': _0x4d42d1(0x1b3),
'xgzNd': _0x4d42d1(0x1cf),
'yzwhA': function (_0x3f0b8f, _0x47b56e) {
return _0x3f0b8f === _0x47b56e;
},
'dIaGX': _0x4d42d1(0x1b7),
'WqBcw': _0x4d42d1(0x196),
'xILnF': 'counter',
'IJOWz': 'OIAkU',
'SBcEP': function (_0x3ad0c4, _0x5e6c44) {
return _0x3ad0c4 !== _0x5e6c44;
},
'kSwZh': function (_0x4853ff, _0x29b0a9) {
return _0x4853ff + _0x29b0a9;
},
'wCKlx': function (_0x5bb806, _0xe3e344) {
return _0x5bb806 / _0xe3e344;
},
'HVPGn': 'length',
'ehywZ': function (_0x1298fd, _0x4080ca) {
return _0x1298fd === _0x4080ca;
},
'fzczY': function (_0x554843, _0x4a8962) {
return _0x554843 % _0x4a8962;
},
'YNcMS': function (_0x3c79ab, _0x4c8608) {
return _0x3c79ab + _0x4c8608;
},
'ngrEl': _0x4d42d1(0x17e),
'uaPor': function (_0x414746, _0x452253) {
return _0x414746(_0x452253);
},
'Jypfh': _0x4d42d1(0x214)
};
function _0x15f2d0(_0x1263a7) {
var _0x2eec2d = _0x4d42d1;
var _0x454ed2 = {
'fCGZF': function (_0x2dac00, _0x55bdf2) {
var _0x1bf4f3 = _0x5880;
return _0x352c68[_0x1bf4f3(0x1f7)](_0x2dac00, _0x55bdf2);
},
'VQTji': _0x352c68[_0x2eec2d(0x1b2)],
'kRYid': _0x352c68[_0x2eec2d(0x1e8)],
'mXEjm': _0x352c68[_0x2eec2d(0x1b5)]
};
if (_0x352c68[_0x2eec2d(0x1c3)](_0x352c68['gnoFH'], _0x352c68[_0x2eec2d(0x1a3)])) {
(function () {
return !![];
}['constructor'](_0x454ed2[_0x2eec2d(0x1f9)](_0x454ed2[_0x2eec2d(0x1a6)], _0x454ed2[_0x2eec2d(0x223)]))[_0x2eec2d(0x1f8)](_0x454ed2[_0x2eec2d(0x1c2)]));
} else {
if (_0x352c68[_0x2eec2d(0x1c3)](typeof _0x1263a7, _0x352c68[_0x2eec2d(0x1e3)])) {
if (_0x352c68[_0x2eec2d(0x184)](_0x352c68[_0x2eec2d(0x21c)], _0x352c68[_0x2eec2d(0x21c)])) {
return function (_0xbf0be3) {
}[_0x2eec2d(0x20b)](_0x352c68[_0x2eec2d(0x188)])[_0x2eec2d(0x1e6)](_0x352c68[_0x2eec2d(0x210)]);
} else {
return ![];
}
} else {
if (_0x352c68[_0x2eec2d(0x184)](_0x352c68[_0x2eec2d(0x1a8)], _0x352c68[_0x2eec2d(0x1a8)])) {
if (_0x352c68[_0x2eec2d(0x1ac)](_0x352c68[_0x2eec2d(0x225)]('', _0x352c68[_0x2eec2d(0x207)](_0x1263a7, _0x1263a7))[_0x352c68[_0x2eec2d(0x1ee)]], 0x145e + -0x17da + -0x37d * -0x1) || _0x352c68['ehywZ'](_0x352c68[_0x2eec2d(0x19d)](_0x1263a7, -0x1dcf + -0xd02 + -0x4f * -0x8b), 0xb1a + 0x1a14 + -0x252e)) {
(function () {
var _0x193ea5 = _0x2eec2d;
if (_0x352c68['ERpro'](_0x352c68[_0x193ea5(0x181)], _0x352c68[_0x193ea5(0x181)])) {
if (_0x512e70) {
var _0x356bb6 = _0x1643d7[_0x193ea5(0x1e6)](_0x589055, arguments);
_0x2b3824 = null;
return _0x356bb6;
}
} else {
return !![];
}
}[_0x2eec2d(0x20b)](_0x352c68[_0x2eec2d(0x225)](_0x352c68[_0x2eec2d(0x1b2)], _0x352c68['ivlvH']))['call'](_0x352c68[_0x2eec2d(0x1b5)]));
} else {
(function () {
return ![];
}[_0x2eec2d(0x20b)](_0x352c68[_0x2eec2d(0x1ce)](_0x352c68[_0x2eec2d(0x1b2)], _0x352c68[_0x2eec2d(0x1e8)]))[_0x2eec2d(0x1e6)](_0x352c68[_0x2eec2d(0x1e0)]));
}
} else {
if (_0xd50adb) {
var _0x168097 = _0x595761[_0x2eec2d(0x1e6)](_0x53b8e6, arguments);
_0x145918 = null;
return _0x168097;
}
}
}
_0x352c68[_0x2eec2d(0x216)](_0x15f2d0, ++_0x1263a7);
}
}
try {
if (_0x13e05f) {
if (_0x352c68['ehywZ'](_0x352c68[_0x4d42d1(0x1d2)], _0x352c68[_0x4d42d1(0x1d2)])) {
return _0x15f2d0;
} else {
var _0x12cafa = _0x864650 ? function () {
if (_0x18a480) {
var _0xc67d94 = _0x41620b['apply'](_0x1193a6, arguments);
_0x297d84 = null;
return _0xc67d94;
}
} : function () {
};
_0xba908e = ![];
return _0x12cafa;
}
} else {
_0x352c68[_0x4d42d1(0x216)](_0x15f2d0, 0x756 + -0x9e9 + 0x293);
}
} catch (_0x128156) {
}
}
Babel AST 处理思路
- 还原不直观的编码字符串或数值;替换、还原由 var,let,const 定义的未变更的字面量
以方便观看代码 - 粗略过一遍
encode.js
最外层代码(自顶向下),发现代码大致执行逻辑如下- 定义了一个全为字面量的大数组
_0x10aa
- 使用了一个自执行函数对
_0x10aa
进行了更新 - 定义了一个函数
_0x5880
和hi
- 执行了函数
hi
- 定义了一个函数
_0x55b414
- 定义了一个全为字面量的大数组
_0x5880
为 ob 混淆中的解密函数,但在代码中被重复赋值给了其他变量 (如var _0x2bf47b = _0x5880;
)
故变量调用处进行替换还原,删除该无用变量- 还原
CallExpression
(此处为_0x5880
) - 删除无效代码、死代码 (如条件确定的
if
分支) - decrypt.js 为还原代码;common_plugins.js 为还原辅助代码;decode.js 为还原后代码
decrypt.js
// decrypt.js
const fs = require('fs');
var util = require('util');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const types = require('@babel/types');
const generator = require('@babel/generator').default;
const { is_literal, visual_literal, visual_var_literal, to_dot_form, rm_unused_code,
rm_unused_branch, simple_calc, multiple_define } = require('./common_plugins');
// 程序启动时间
var time_start = new Date().getTime()
// 读取文件
process.argv.length > 2 ? encode_file = process.argv[2] : encode_file = 'encode.js';
process.argv.length > 3 ? decode_file = process.argv[3] : decode_file = 'decode.js';
let jscode = fs.readFileSync(encode_file, { encoding: 'utf-8' });
console.log(util.format('Reading the file [%s] is complete.', encode_file))
// 转换为 ast 树
let ast = parser.parse(jscode);
//调用插件,处理待处理 js ast 树
traverse(ast, visual_literal);
traverse(ast, visual_var_literal);
traverse(ast, simple_calc);
traverse(ast, multiple_define);
const ob_replace_call_expression = {
VariableDeclarator(path) {
let { scope, node } = path;
let { id, init } = node;
// 解密函数名称
let decode_func_name;
if (!types.isArrayExpression(init)) {
return;
}
for (let element of init.elements) {
if (!is_literal(element)) {
return;
}
}
let binding = scope.getBinding(id.name);
if (binding.referencePaths.length < 2) {
return;
}
let eval_str = path.parentPath.toString();
// 解密函数位置
let func_start, func_end, tmp_array = [];
for (let refer_path of binding.referencePaths) {
let parent_path = refer_path.findParent(p => p.isCallExpression()) || refer_path.findParent(p => p.isFunctionDeclaration())
if (!parent_path) {
return;
}
if (parent_path.isFunctionDeclaration()) {
func_start = parent_path.node.start;
func_end = parent_path.node.end;
decode_func_name = parent_path.node.id.name;
}
else {
parent_path = parent_path.parentPath;
if (!types.isExpressionStatement(parent_path)) {
return;
}
}
eval_str += '\n' + parent_path.toString()
tmp_array.push(parent_path);
}
let eval_str_ast = parser.parse(eval_str);
// 防止检测代码格式化
eval_str = generator(eval_str_ast, { 'compact': true }).code;
// 执行自执行函数更新数组,将解密函数定义到本地环境
eval(eval_str);
let remove_flag = true;
_binding = scope.getBinding(decode_func_name);
for (let refer_path of _binding.referencePaths) {
let parent_path = refer_path.findParent(p => p.isCallExpression())
if (!parent_path) {
continue
}
if (decode_func_name !== parent_path.node.callee.name) {
continue;
}
let parent_start = parent_path.node.start;
let parent_end = parent_path.node.end;
if (parent_start >= func_start && parent_end <= func_end) {
continue;
}
try {
let call_return = eval(parent_path.toString());
console.log(parent_path.toString() + ' => ' + call_return);
parent_path.replaceWith(types.valueToNode(call_return));
} catch (e) {
remove_flag = false;
console.log(parent_path.toString() + ' => do nothing');
}
}
if (remove_flag) {
for (let tmp_path of tmp_array) {
tmp_path.remove();
}
}
path.remove();
scope.crawl();
}
}
traverse(ast, ob_replace_call_expression);
traverse(ast, simple_calc);
/* 还原 ob 混淆中的 ObjectExpression 节点 */
const ob_replace_obj_expression =
{
VariableDeclarator(path) {
let { id, init } = path.node;
if (!types.isObjectExpression(init)) {
return;
}
let { properties } = init;
if (properties.length <= 0) {
return;
}
let obj_map = {};
for (let property of properties) {
let { key, value } = property;
key = key.value;
if (types.isFunctionExpression(value)) {
let { body } = value;
if (body.body.length != 1 || !types.isReturnStatement(body.body[0])) {
return;
}
}
else if (types.isStringLiteral(value)) {
value = value.value;
}
else {
return;
}
obj_map[key] = value;
}
let binding = path.scope.getBinding(id.name);
let remove_flag = true;
for (let refer_path of binding.referencePaths.reverse()) {
let parent_path = refer_path.parentPath;
let key = parent_path.node.property.value;
let value = obj_map[key];
if (types.isFunctionExpression(value)) {
let grandparent_path = parent_path.parentPath;
if (!types.isCallExpression(grandparent_path)) {
continue;
}
let { arguments } = grandparent_path.node;
let { params } = value;
if (arguments.length != params.length) {
return;
}
var arguments_map = {};
let break_flag = false;
for (let i = 0; i < arguments.length; i++) {
arguments_map[params[i].name] = arguments[i];
// 防止实参数大于形参数
if (!arguments[i]) {
break_flag = true;
break;
}
}
if (break_flag) {
remove_flag = false;
continue;
}
let return_statement = JSON.parse(JSON.stringify(value.body.body[0].argument));
let new_jscode = generator(return_statement, { 'compact': true }).code;
let new_ast = parser.parse(new_jscode);
traverse(new_ast, {
Identifier(_path) {
let { name } = _path.node;
if (!arguments_map.hasOwnProperty(name)) {
return;
}
_path.replaceWith(arguments_map[name])
}
})
let old_code = grandparent_path.toString();
grandparent_path.replaceWithMultiple(new_ast.program.body);
console.log(old_code + ' => ' + grandparent_path.toString());
}
else {
console.log(parent_path.toString() + ' => ' + value);
parent_path.replaceWith(types.valueToNode(value));
}
}
if (remove_flag) {
path.remove();
}
// 手动更新 scope ,防止影响下个插件使用
path.scope.crawl();
}
}
traverse(ast, ob_replace_obj_expression);
const ob_replace_while_switch_control_flow =
{
WhileStatement(path) {
let { body } = path.node;
let switch_statement = body.body[0];
if (!types.isSwitchStatement(switch_statement)) {
return;
}
let { discriminant, cases } = switch_statement;
// 进一步进行特征判断
if (!types.isMemberExpression(discriminant) || !types.isUpdateExpression(discriminant.property)) {
return;
}
// 找到 array 是哪定义的,并且使用 path.evaluate() 方法获取其最终值
let { confident, value } = path.scope.getBinding(discriminant.object.name).path.get('init').evaluate();
if (!confident) {
return;
}
let array = value, case_map = {}, tmp_array = [];
for (let c of cases) {
let { consequent, test } = c;
let test_value;
if (test) {
test_value = test.value;
}
else {
test_value = 'default_case';
}
let statement_array = [];
for (let i of consequent) {
if (types.isContinueStatement(i)) {
continue;
}
statement_array.push(i);
}
case_map[test_value] = statement_array;
}
for (let i of array) {
tmp_array = tmp_array.concat(case_map[i])
}
if (case_map.hasOwnProperty('default_case')) {
tmp_array = tmp_array.concat(case_map['default_case'])
}
path.replaceWithMultiple(tmp_array);
path.scope.crawl();
}
}
traverse(ast, to_dot_form);
traverse(ast, ob_replace_while_switch_control_flow);
traverse(ast, simple_calc);
traverse(ast, rm_unused_branch);
console.log('AST traverse completed.')
// 生成处理后的 js
let { code } = generator(ast);
console.log('AST generator completed.')
fs.writeFile(decode_file, code, (err) => { });
console.log(util.format('The javascript code in [%s] has been processed.', encode_file))
console.log(util.format('The processing result has been saved to [%s].', decode_file))
// 程序结束时间
var time_end = new Date().getTime()
console.log(util.format('The program runs to completion, time-consuming: %s s', (time_end - time_start) / 1000))
common_plugins.js
/*
Babel AST 通用插件 (nodejs)
Author: maida
Github: https://github.com/LZC6244
Update Date: 2021.8.5
*/
const types = require('@babel/types');
/* 判断节点是否为字面量 */
function is_literal(node) {
if (types.isLiteral(node)) {
return true;
}
else if (types.isUnaryExpression(node, { 'operator': '+' }) || types.isUnaryExpression(node, { 'operator': '-' })) {
return is_literal(node.argument);
}
return false
}
/* 还原不直观的编码字符串或数值 */
const visual_literal =
{
NumericLiteral(path) {
let node = path.node;
if (node.extra && /^0[obx]/i.test(node.extra.raw)) {
node.extra = undefined;
}
},
StringLiteral(path) {
let node = path.node;
if (node.extra && /\\[ux]/gi.test(node.extra.raw)) {
try {
node_value = decodeURIComponent(escape(node.value));
} catch (error) {
node_value = node.value;
};
path.replaceWith(types.stringLiteral(node_value));
path.node.extra = { 'raw': JSON.stringify(node_value), 'rawValue': node_value };
}
}
}
/* 替换、还原由 var,let,const 定义的未变更的字面量 */
const visual_var_literal =
{
VariableDeclarator(path) {
const { id, init } = path.node;
let binding = path.scope.getBinding(id.name);
// 只处理字面量,且被修改则不作处理
if (!types.isLiteral(init) || !binding.constant) {
return;
}
for (let refer_path of binding.referencePaths) {
refer_path.replaceWith(init);
}
path.remove();
// 手动更新 scope ,防止影响下个插件使用
path.scope.crawl();
}
}
/*
计算![]、!![] 和 简单的字面量计算如 1+2+3
刚插件需使用 exit 方式遍历
*/
const simple_calc = {
UnaryExpression: {
exit(path) {
let old_code = path.toString();
let allow_array = ['!', 'typeof']
let { operator } = path.node;
if (!allow_array.includes(operator)) {
return;
}
let { confident, value } = path.evaluate();
if (!confident) {
return;
}
path.replaceWith(types.valueToNode(value));
console.log(old_code + ' => ' + path.toString());
path.scope.crawl();
}
},
BinaryExpression: {
exit(path) {
let old_code = path.toString();
let invalid_identifier_array = ['undefined', 'Infinity', 'NaN'];
let { left, right } = path.node;
if (!types.isLiteral(left) && !types.isUnaryExpression(left)) {
if (types.isIdentifier(left) || invalid_identifier_array.includes(left.name)) {
}
else if (types.isCallExpression(left) && global[left.callee.name]) {
}
else {
return;
}
}
if (!types.isLiteral(right) && !types.isUnaryExpression(right)) {
if (types.isIdentifier(right) || invalid_identifier_array.includes(right.name)) {
}
else if (types.isCallExpression(right) && global[right.callee.name]) {
}
else {
return;
}
}
let { confident, value } = path.evaluate();
if (!confident) {
return;
}
let invalid_value_array = [undefined, null, Infinity, -Infinity, NaN];
if (invalid_value_array.includes(value)) {
path.replaceWithSourceString(value);
console.log(old_code + ' => ' + path.toString());
}
else {
path.replaceWith(types.valueToNode(value));
if (path.isStringLiteral()){
path.node.extra = { 'raw': JSON.stringify(value), 'rawValue': value };
}
console.log(old_code + ' => ' + path.toString());
}
path.scope.crawl();
}
}
}
/* 处理套娃式声明语句,如 var a=b(function xxx);var c=b;... */
const multiple_define =
{
VariableDeclarator(path) {
let { id, init } = path.node;
if (!types.isIdentifier(id) || !types.isIdentifier(init)) {
return;
}
let init_identifier = path.scope.getBinding(init.name).identifier;
let id_refer_paths = path.scope.getBinding(id.name).referencePaths;
for (let refer_path of id_refer_paths) {
refer_path.replaceWith(init_identifier);
}
path.remove();
// 手动更新 scope ,防止影响下个插件使用
path.scope.crawl();
}
}
/* 将 a['bb'] 转换为 a.bb */
const to_dot_form = {
MemberExpression(path) {
let { computed } = path.node;
// 获取 path property 子路径
let property = path.get('property');
if (computed && types.isStringLiteral(property)) {
property.replaceWith(types.identifier(property.node.value));
path.node.computed = false;
}
path.scope.crawl();
}
}
/* 删除条件确定的 if 判断或条件表达式的未使用的分支代码 */
const rm_unused_branch =
{
IfStatement(path) {
let consequent_path = path.get('consequent');
let alternate_path = path.get('alternate');
let test_path = path.get('test');
if (!types.isBlockStatement(consequent_path)) {
consequent_path.replaceWith(types.blockStatement([consequent_path]));
}
if (alternate_path.toString() && !types.isBlockStatement(alternate_path)) {
alternate_path.replaceWith(types.blockStatement([alternate_path]));
}
let replace_path;
let { confident, value } = test_path.evaluate();
if (!confident) {
return;
}
if (value) {
replace_path = consequent_path;
}
else {
if (!alternate_path.toString()) {
path.remove();
path.scope.crawl();
return
}
replace_path = alternate_path;
}
for (let statement of replace_path.node.body) {
if (types.isVariableDeclaration(statement) && statement.kind !== 'var') {
return;
}
}
path.replaceWithMultiple(replace_path.node.body);
path.scope.crawl();
},
ConditionalExpression(path) {
let consequent_path = path.get('consequent');
let alternate_path = path.get('alternate');
let test_path = path.get('test');
let { confident, value } = test_path.evaluate();
if (!confident) {
return;
}
if (value) {
path.replaceWith(consequent_path);
}
else {
path.replaceWith(alternate_path);
}
path.scope.crawl();
}
}
/* 删除未被使用的 function 和由 var,let,const 定义的未使用变量、空语句 */
const rm_unused_code =
{
VariableDeclarator(path) {
const { id } = path.node;
let binding = path.scope.getBinding(id.name);
if (binding.referenced) {
return;
}
path.remove();
path.scope.crawl();
},
FunctionDeclaration(path) {
const { id } = path.node;
// 防止函数中存在变量与函数名相同,且该变量在函数中使用,导致未去除未使用函数
let binding = path.scope.parent.getBinding(id.name);
if (binding.referenced) {
return;
}
path.remove();
// 手动更新 scope ,防止影响下个插件使用
path.scope.crawl();
},
'EmptyStatement'(path) {
path.remove();
}
}
exports.is_literal = is_literal;
exports.visual_literal = visual_literal;
exports.visual_var_literal = visual_var_literal;
exports.to_dot_form = to_dot_form;
exports.rm_unused_branch = rm_unused_branch;
exports.rm_unused_code = rm_unused_code;
exports.simple_calc = simple_calc;
exports.multiple_define = multiple_define;
decode.js
function hi() {
var _0x1e3d10 = function () {
var _0x4f217d = true;
return function (_0x5949e2, _0x553e4b) {
var _0x3bb8c0 = _0x4f217d ? function () {
if (_0x553e4b) {
var _0x1a3791 = _0x553e4b.apply(_0x5949e2, arguments);
_0x553e4b = null;
return _0x1a3791;
}
} : function () {};
_0x4f217d = false;
return _0x3bb8c0;
};
}();
(function () {
_0x1e3d10(this, function () {
var _0x285632 = new RegExp("function *\\( *\\)");
var _0x218809 = new RegExp("\\+\\+ *(?:[a-zA-Z_$][0-9a-zA-Z_$]*)", 'i');
var _0x50438e = _0x55b414("init");
if (!_0x285632.test(_0x50438e + "chain") || !_0x218809.test(_0x50438e + "input")) {
_0x50438e('0');
} else {
_0x55b414();
}
})();
})();
var _0x15a0ee = function () {
var _0x49048e = true;
return function (_0x41b2c9, _0x5f48c6) {
var _0x15ed94 = _0x49048e ? function () {
if (_0x5f48c6) {
var _0x4c14a5 = _0x5f48c6.apply(_0x41b2c9, arguments);
_0x5f48c6 = null;
return _0x4c14a5;
}
} : function () {};
_0x49048e = false;
return _0x15ed94;
};
}();
var _0x35ef4b = _0x15a0ee(this, function () {
var _0x50c7f1;
try {
var _0x52108e = Function("return (function() {}.constructor(\"return this\")( ));");
_0x50c7f1 = _0x52108e();
} catch (_0x5de9d7) {
_0x50c7f1 = window;
}
var _0x40cd31 = _0x50c7f1.console = _0x50c7f1.console || {};
var _0x9c92be = ["log", "warn", "info", "error", "exception", "table", "trace"];
for (var _0x5f444f = 0; _0x5f444f < _0x9c92be.length; _0x5f444f++) {
var _0xd7039d = "5|4|3|0|2|1".split('|');
var _0x37b213 = 0;
var _0x35f8de = _0x15a0ee.constructor.prototype.bind(_0x15a0ee);
var _0x451242 = _0x9c92be[_0x5f444f];
var _0x1ddfd = _0x40cd31[_0x451242] || _0x35f8de;
_0x35f8de.__proto__ = _0x15a0ee.bind(_0x15a0ee);
_0x35f8de.toString = _0x1ddfd.toString.bind(_0x1ddfd);
_0x40cd31[_0x451242] = _0x35f8de;
}
});
_0x35ef4b();
console.log("Hello World! -- 1");
console.log("Hello World! -- 3");
console.log("Hello World! -- 2");
console.log("Hello World! -- 7");
console.log("Hello World! -- 5");
}
hi();
function _0x55b414(_0x13e05f) {
function _0x15f2d0(_0x1263a7) {
if (typeof _0x1263a7 === "string") {
return function (_0xbf0be3) {}.constructor("while (true) {}").apply("counter");
} else {
if (('' + _0x1263a7 / _0x1263a7).length !== 1 || _0x1263a7 % 20 === 0) {
(function () {
return true;
}).constructor("debugger").call("action");
} else {
(function () {
return false;
}).constructor("debugger").apply("stateObject");
}
}
_0x15f2d0(++_0x1263a7);
}
try {
if (_0x13e05f) {
return _0x15f2d0;
} else {
_0x15f2d0(0);
}
} catch (_0x128156) {}
}
还原工作 (decode.js) 扫尾
首先过一下整体逻辑
- 定义了 function hi 和 _0x55b414
- 执行 function hi
那么我们接下来过一下 function hi 内执行逻辑
先介绍要点,对于 function ,我们主要关注
- 有没有改变实参
- 有没有改变全局变量
- 有没有返回值
分析流程
- _0x1e3d10 是个条件确定的三元表达式定义的函数,可作简化
其下方是个调用了 0x1e3d10 的自执行函数
该自执行函数会导致无限 debugger ,所以可以删除 0x1e3d10 及其下方自执行函数 - _0x15a0ee 和 _0x35ef4b 分析后发现其为禁用控制台输出的代码,亦可删除
还原后代码 (decode.js 最终版)
只能说一模一样 ヽ(ー_ー)ノ
function hi() {
console.log("Hello World! -- 1");
console.log("Hello World! -- 3");
console.log("Hello World! -- 2");
console.log("Hello World! -- 7");
console.log("Hello World! -- 5");
}
hi();
参考链接
- https://mp.weixin.qq.com/s/dPKrONl685JQRb5U1Hmx7Q
- https://mp.weixin.qq.com/s/HV9BGi96QCOphts8wXI2TA