這一篇主要是研究一下這個混淆器的反調試功能,並找到對應的解決辦法。
源代碼:
// Paste your JavaScript code here
function hi() {
console.log("Hello World!");
}
hi();
反調試,這個跟源代碼沒什麼關係,就用自帶的代碼就行。
1.調試選項[Debug Protection]
混淆選項:
只選這一個,其他的都不選,生成的混淆代碼:
function hi() {
var _0xc89b72 = function () {
var _0x56f7f3 = !![];
return function (_0x506ee0, _0x2ca148) {
var _0x5d9580 = _0x56f7f3 ? function () {
if (_0x2ca148) {
var _0x47065a = _0x2ca148['apply'](_0x506ee0, arguments);
_0x2ca148 = null;
return _0x47065a;
}
} : function () {
};
_0x56f7f3 = ![];
return _0x5d9580;
};
}();
(function () {
_0xc89b72(this, function () {
var _0x1962eb = new RegExp('function\x20*\x5c(\x20*\x5c)');
var _0x5cff30 = new RegExp('\x5c+\x5c+\x20*(?:[a-zA-Z_$][0-9a-zA-Z_$]*)', 'i');
var _0x21c51c = SnktC('init');
if (!_0x1962eb['test'](_0x21c51c + 'chain') || !_0x5cff30['test'](_0x21c51c + 'input')) {
_0x21c51c('0');
} else {
SnktC();
}
})();
}());
console['log']('Hello\x20World!');
}
hi();
function SnktC(_0xb63949) {
function _0x22c4df(_0x537425) {
if (typeof _0x537425 === 'string') {
return function (_0x2c4754) {
}['constructor']('while\x20(true)\x20{}')['apply']('counter');
} else {
if (('' + _0x537425 / _0x537425)['length'] !== 0x1 || _0x537425 % 0x14 === 0x0) {
(function () {
return !![];
}['constructor']('debu' + 'gger')['call']('action'));
} else {
(function () {
return ![];
}['constructor']('debu' + 'gger')['apply']('stateObject'));
}
}
_0x22c4df(++_0x537425);
}
try {
if (_0xb63949) {
return _0x22c4df;
} else {
_0x22c4df(0x0);
}
} catch (_0x2aceb6) {
}
}
保存成網頁開始調試:
<html>
<head>
<script>
function hi() {
var _0xc89b72 = function () {
var _0x56f7f3 = !![];
return function (_0x506ee0, _0x2ca148) {
var _0x5d9580 = _0x56f7f3 ? function () {
if (_0x2ca148) {
var _0x47065a = _0x2ca148['apply'](_0x506ee0, arguments);
_0x2ca148 = null;
return _0x47065a;
}
} : function () {
};
_0x56f7f3 = ![];
return _0x5d9580;
};
}();
(function () {
_0xc89b72(this, function () {
var _0x1962eb = new RegExp('function\x20*\x5c(\x20*\x5c)');
var _0x5cff30 = new RegExp('\x5c+\x5c+\x20*(?:[a-zA-Z_$][0-9a-zA-Z_$]*)', 'i');
var _0x21c51c = SnktC('init');
if (!_0x1962eb['test'](_0x21c51c + 'chain') || !_0x5cff30['test'](_0x21c51c + 'input')) {
_0x21c51c('0');
} else {
SnktC();
}
})();
}());
console['log']('Hello\x20World!');
}
hi();
function SnktC(_0xb63949) {
function _0x22c4df(_0x537425) {
if (typeof _0x537425 === 'string') {
return function (_0x2c4754) {
}['constructor']('while\x20(true)\x20{}')['apply']('counter');
} else {
if (('' + _0x537425 / _0x537425)['length'] !== 0x1 || _0x537425 % 0x14 === 0x0) {
(function () {
return !![];
}['constructor']('debu' + 'gger')['call']('action'));
} else {
(function () {
return ![];
}['constructor']('debu' + 'gger')['apply']('stateObject'));
}
}
_0x22c4df(++_0x537425);
}
try {
if (_0xb63949) {
return _0x22c4df;
} else {
_0x22c4df(0x0);
}
} catch (_0x2aceb6) {
}
}
</script>
</head>
<body>
<p>test</p>
</body>
</html>
此時在代碼中設置斷點,單步的時候,就會不斷地進入下面這種代碼:
無限循環。
此方案的主要反調試代碼在SnktC中,而反調試手法主要有兩種:
1.無限循環
(function() {
while (true) {}
})
2.無限debug
(function() {
debugger
})
而此函數進入之後,則很難再跳出來了,這裏唯有禁用所有斷點才能短暫重新執行。
禁用所有斷點的方法:
點擊紅圈中的按鈕。
所以要跳過反調試的最好時機就是再此函數執行之前。
因此需要在控制檯修改代碼來擺脫這種死循環。
PS:讓控制檯出現在調試截面下方的方法:
1.點擊開發人員工具右上角的三個小點的位置:
2.選擇紅圈中的選項,這樣下方就會出現一個Console面板。
跳過此反調試的方法見下圖:
1。在31行函數SnktC處下斷;
2.在Console面板重寫此函數 SnktC=function test(){}
3.繼續執行,此時即可斷在我們想要的斷點處(35行)。
2.調試選項[Debug Protection Interval]
勾選選項:
生成的混淆代碼:
setInterval(function () {
DVtpz();
}, 0xfa0);
function hi() {
var _0x3c7609 = function () {
var _0x35755f = !![];
return function (_0xa5c2e3, _0x450fe3) {
var _0x528e92 = _0x35755f ? function () {
if (_0x450fe3) {
var _0x5daead = _0x450fe3['apply'](_0xa5c2e3, arguments);
_0x450fe3 = null;
return _0x5daead;
}
} : function () {
};
_0x35755f = ![];
return _0x528e92;
};
}();
(function () {
_0x3c7609(this, function () {
var _0x51208b = new RegExp('function\x20*\x5c(\x20*\x5c)');
var _0x26abc7 = new RegExp('\x5c+\x5c+\x20*(?:[a-zA-Z_$][0-9a-zA-Z_$]*)', 'i');
var _0x59e977 = DVtpz('init');
if (!_0x51208b['test'](_0x59e977 + 'chain') || !_0x26abc7['test'](_0x59e977 + 'input')) {
_0x59e977('0');
} else {
DVtpz();
}
})();
}());
console['log']('Hello\x20World!');
}
hi();
function DVtpz(_0x2043ac) {
function _0x1f0f5c(_0x5a9a33) {
if (typeof _0x5a9a33 === 'string') {
return function (_0xc77a6c) {
}['constructor']('while\x20(true)\x20{}')['apply']('counter');
} else {
if (('' + _0x5a9a33 / _0x5a9a33)['length'] !== 0x1 || _0x5a9a33 % 0x14 === 0x0) {
(function () {
return !![];
}['constructor']('debu' + 'gger')['call']('action'));
} else {
(function () {
return ![];
}['constructor']('debu' + 'gger')['apply']('stateObject'));
}
}
_0x1f0f5c(++_0x5a9a33);
}
try {
if (_0x2043ac) {
return _0x1f0f5c;
} else {
_0x1f0f5c(0x0);
}
} catch (_0x2540d5) {
}
}
相比較之前的代碼,多了一個定時觸發:
setInterval(function () {
DVtpz();
}, 0xfa0);
過掉反調試的方法:
在第8行,或者34行下斷。等段下來,然後重寫此函數即可。