无限debugger 原理
一. 原理
- 定时器
简单理解就是利用setInterval 或 setTimeout 另外开了一个线程,每个制定时间,执行一次debugger,如果你打开控制台,就会进入debugger状态。
代码:
setInterval(function (){
debugger;
}, 1000)
setTimeout(function b(){
debugger;
setTimeout(b,1000)
}, 1000)
- 递归 无限调用
function recursionDebugger(){
function a(){
debugger;
b()
}
function b(){
a()
}
b()
}
二 . 解决方案
-
清除计时器:
使用clearInterval() 删除所有的定时器。
但是这样会有一个缺点,当有其他加密逻辑也是用interval的时候会被误伤。
(function (){
var gid = setInterval(clearAllInverval, 1000);
function clearAllInverval(){
var id = setInterval(function(){}, 0);
while (id>0){
if (id!=gid){
clearInterval(id);
};
id --
}
}
})();
- 在debugger的地方设置:
比较笨的办法,有时候不一定生效,即使生效有时候也会,因为无限调用导致内存崩掉卡死。
- hook:
最稳妥的办法还是要用hook的方法。
(1) hook Function 原型的构造函数。
(2) hook 定时器函数。
// hook Function 原型构造函数, 修改debugger
Function.prototype.temp_constructor= Function.prototype.constructor;
Function.prototype.constructor=function(){
if (arguments && typeof arguments[0]==="string"){
if (arguments[0]==="debugger")
return ""
}
return Function.prototype.temp_constructor.apply(this, arguments);
};
// hook 定时器函数 替换debugger
_setInterval = setInterval
setInterval = function setInterval(code, time){
console.log(code, time)
code = code.toString().replace(/debugger/, "").replace(/function ()/, "function xxx")
return _setInterval(new Function(code) , time)
}
_setTimeout = setTimeout
setTimeout = function setTimeout(code, time){
console.log(code, time)
code = code.toString().replace(/debugger/, "").replace(/function ()/, "function xxx")
return _setTimeout(new Function(code), time)
}
- 置空
找到入口函数,在入口函数声明后打断点,然后在控制台重写 这个函数。直接 置空即可。(需要手动,还是hook好一点~)
以上总结了目前网上比较常用的,处理无限debugger的四种方法。如有不足,请批评指出,一定会虚心改正。