文章更新了新内容,更加深入分析了一波
作为前端开发来说,js调试是一项必备的技能。无论是要查找bug,还是想了解别人代码的逻辑,js调试都是一种可以帮助你节省时间的方法。
这是我平时使用的chrome的调试界面。选择它的原因,一是功能真的十分强大,第二个就是新特性支持的比较快(尤其是Google Chrome Canary 版,拥有新版 Chrome 的最新功能,这是专为开发者和早期用户设计的版本,有时可能会造成浏览器彻底当机, ,你可以去这里看看它的功能和特性)这篇文章的目的不是分享 像格式代码,设置断点,查看调用栈,查看变量等一系列调试工具功能的使用,这种网上已经有很多好的文章了,本文主要分析工作中遇到的循环debugger问题,如下图:
有时候我们在扒别人网站的时候,为了了解代码的功能,我们可以通过JavaScript调试工具设置断点,阻止代码执行。进而分析断点的执行环境,对象,变量等一系列有用的信息,完成代码逻辑的解读。
在JavaScript中,我们可以直接使用debugger指令,将代码断在指定位置,举个?
console.log('you can see me')debuggerconsole.log('can you see me?')复制代码
结果其实比较明显,你可以看到第一行的输出,但是运行到第二行时,代码被断住,只有你手动继续执行才能看到第三行的输出。就是这个原理很多商业产品代码中会定义一个无线循环的debugger指令,它的目的是
- 不停地打断你,浪费时间
- 不断的产生不可回收的对象,占据你的内存,造成内存泄漏,没过多久浏览器就会卡顿,甚至可以跑满你的cpu,调试你是不用想了,能关掉页面就已经不错了
在这里给大家举一个简单易懂的?
setTimeout(function(){ while (true) { debugger }},100)复制代码
像这种情况我们怎么应对那? google一圈之后发现普遍的解决方案是:
Deactivate breakpoint,那它能解决问题吗?
看下图就知道了。由于忽略了所有断点,连你自己设置的都不放过(你的断点没有意义了),会继续去执行debugger,创建对象,你的cpu会被跑满,我在实践中发现这种发式不靠谱。抬走,下一个!
还有一招就是:禁止断点 具体操作见下图
我们就可以忽略它,可以继续打其他的断点,还是有效果的。但是这种方式其实是有弊端的,比如创建其他执行环境等,就没办法解决问题了,上一张这种恶心情况的图。 像这样的我能利用上面的方式能解决吗? 能,要不也没有这篇文章了,哈哈 但是一定要耐心 好 我们会到正题,具体怎么解决那? 看调用栈,如图 我们可以看到这段代码是在player.js中的0x51c762调用的,那我们需要看player.js中的0x51c762到底干了什么?好,沿着这个思路我们看一看_0x51c7626和调用它的地方 这代码看着让人崩溃,这是写的什么东西啊!别急,分析一波,之所以能够循环debugger肯定和这个setInterval相关,这个定时器中调用了_0x51c7626函数,说明debugger跟0x51c7626函数有关,那么把他们干掉试一下。具体方法是copy一份player.js,注释掉如下代码_0x51c762();setInterval(function() { _0x51c762()}, 0xfa0);复制代码
用charles(我用的是这个,你可以用别的抓包工具)重定向到你做了修改的js文件
然后再进行调试的时候是不是发现这种创建新执行环境的循环debugger没有了。啊 哈哈哈。其实每个网站做的方式可能不同,但是套路是不变的。 上面只是提到一个单纯使用dubugger指令的反调试方法,其实还有很多其他的方式,比如时间差异的方式var timelimit = 50;var open = false;var starttime = new Date();debugger;if (new Date() - starttime > timelimit) { open = true; //此处执行你的反调试逻辑,比如删除操作 open = false;}复制代码
像这种我们怎么去解决它? 其实很简单,我们可以断点,调大timelimit(比如timelimit = 1000000),轻松绕过。实际中可能还有其他判断条件,我们只要断点一次将它置成false,保证它不会进入debugger的条件语句就好了 希望能对大家有帮助
未经本人允许,不得转载,文章有疏漏浅薄之处,请各位大神斧正