文章目录
- JS中实现debugger的方法
- 无限Debugger示例
- Demo1
- Demo2
- Demo3
- Demo4
- 总结
- 无限Debugger实战
JS中实现debugger的方法
首先,我们要知道,在浏览器实现debugger的方法有哪些
- debugger关键词 ,相当于C++内联汇编的int3,在代码中嵌入这么一个关键词方便调试
- eval(‘debugger’) ,原理跟第一个一样,只不过是使用eval方法来调用。这个可操作空间比较大,字符串可以经过混淆或者拼接以后最后变成
debugger
这个关键词即可。 - Function(“debugger”), 原理跟2类似,只不过是在虚拟机里面执行匿名函数,匿名函数里有debugger的方法
这些debugger方法,是实现debugger的基础,可以理解为是三元素。基于三种元素,可以形成多种多样的玩法
无限Debugger示例
Demo1
那么接下来, 我就将上面的三元素进行组合,产生各种无限debugger
setInterval('debugger', 500)
这种是利用定时器的方法,去不断间隔的创造宏任务队列,用来干扰我们的调试 。
解决方案:
- 右键-> Never pause here
- 在定时器启动之前重写 setInterval
- AutoResponse 直接把干扰点干掉
Demo2
html页面生产时,直接自动生成几千个script标签,标签里只写一个debugger
<script>
!function (){debugger}()
</script>
<script>
!function (){debugger}()
</script><script>
!function (){debugger}()
</script><script>
!function (){debugger}()
</script><script>
!function (){debugger}()
</script><script>
如果是这种方式的话,刚刚那种解决方案就不行了。解决方案:AutoResponse 直接把干扰点干掉
Demo3
for (let i=0;i<=5000;i++)
{
Function('debugger')() // 原型链 获取Function
eval('debugger')
debugger;
}
解决方案
- Never pause here
- 干掉这个循环进入的函数
- AutoResponse 直接把干扰点干掉
Demo4
添加script标签,插入debugger
for (let i=0;i<=5000;i++)
{
cont = document.body
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.innerHTML = 'debugger';
cont.appendChild(newScript);
}
解决方案: document.createElement里面把script重写
总结
- 优先尝试 Never pause here (最方便快捷,但是最卡,也最容出问题)
- 次优先尝试重写调用函数
- 使用 AutoResponse/mapping/overrides 替换
无限Debugger实战
这个是猿人学第五十四题,大家也可以自己动手体验下。
进入到目标网站,直接打开调试器,就出现了一个反调试
通过调用栈找到上一层,可以看到这个反调试的函数
s(s(11))
ƒ eval() { [native code] }
直接在控制台敲一下s11,可以看到这个就是eval函数
s(38)+s(56)+s(62)+s(50)
'debugger'
执行一下这四个字符串,就可以看到是debugger这个字符串。
这个反调试只有一层的话,就可以直接Never pause here
就可以过掉,也可以采用HOOK的方法,重写一个eval函数,让这个地方不会断下来。
_eval = eval;
eval= function()
{
if ([arguments[0]].indexOf('debugger'))
return eval(arguments[0])
}
这样这个反调试的点就过掉了,然后我们进行一个翻页,又出现一个无限debugger,查看一下当前的堆栈
这里用循环的方式一直去添加一个o的节点,
o实际上就是一个带debugger关键字的标签,按照之前的思路,我们应该把appendChild这个函数给hook掉。
_appendChild = Node.prototype.appendChild
Node.prototype.appendChild = function()
{
if (arguments[0].innerHTML && arguments[0].innerHTML.indexOf('debugger') != -1)
{
arguments[0].innerHTML = ''
}
return _appendChild.apply(this, arguments)
}
执行一下这段代码,这个无限Debugger就过掉了。
继续运行,这里也有个无限Debugger,直接右键Never pause here解决
然后刷新一下页面,这里就会出现一个新的无限debugger,这里有一堆的debugger标签
这里用Overrides把这几百个debugger关键词替换掉。
重新刷新页面,这样就过掉了这个无限Debugger
再继续,这里又出现了一个无限Debugger,因为这个位置只有一行,不管多复杂,其实都可以右键Never pause here
搞定,也可以直接Overrides删掉,混淆的太厉害了,原理就不看了。
到这里,整个无限Debugger的案例就结束了。