在做爬虫的时候,我们经常会在代码中遇到关键字debugger。debugger是JavaScript中定义的关键字,专门用于断点调试。只要遇到,JavaScript的执行就会在这里中断,进入调试模式。通过关键字debugger,我们可以非常方便的调试JavaScript代码。比如在使用JavaScriptHook的时候,我们可以加上关键字debugger,让它停在关键位置,寻找反向突破口。但是有时候,调试器会被网站开发者使用,给我们正常的调试带来了阻碍。本节介绍一个绕过无限Debug的案例。一、案例介绍先来看一个案例,网址为:https://antispider8.scrape.center/,打开这个网站,正常运行和之前的网站没什么区别。但是,我们一打开开发者工具,发现马上就进入了断点模式,如图。进入断点模式我们没有设置任何断点,也没有执行任何额外的脚本,它只是进入了断点模式。这时候我们可以点击Resumescriptexecution(恢复脚本执行)按钮尝试跳过这个断点继续执行,如图。尝试跳过断点,但是无论我们按了多少次,它还是一次次进入断点模式,死循环不断。我们可以将这种情况称为无限调试器。我应该怎么办?断点调试好像不能正常中断。有什么解决办法吗?当然有解决办法。本节我们将总结一下无限Debugger的解决方法。2.实现原理首先我们要做的就是找到infiniteDebugger的源码。在Sources面板中,您可以看到debugger关键字出现在JavaScript文件中。这个时候点击左下角的格式化按钮,如图。点击Sources面板中的format按钮,setInterval循环用于每秒执行一次debugger语句,如图。每秒执行一次调试器语句。当然,类似的实现还有很多,比如无限for循环、无限while循环、无限递归调用等,都可以达到这样的效果,原理也差不多。了解了原理,我们就对症下药吧!3.禁用断点,因为调试器其实就是对应的断点,相当于用代码显式声明断点。要删除它,我们只需要禁用断点就够了。首先,我们可以禁用所有断点。全局禁用开关位于Sources面板的右上角,称为Deactivatebreakpoints,如图所示。点击全局禁用开关,然后你会发现所有的断点都变成了灰色,如图。Disableallbreakpoints此时,我们再次点击Resumescriptexecution按钮,跳过当前断点,页面将不再进入无限Debugger状态。但是这种全局禁用其实并不是一个好的解决方案,因为禁用之后我们就不能在其他地方加断点进行调试了,所有的断点都失效了。这个时候我们可以选择禁用本地断点。取消刚才的Deactivatebreakpoints模式,页面会重新进入无限Debugger模式。我们尝试用另一种方法来跳过这个无限的Debugger。我们可能会考虑去掉Breakpoints中勾选的断点,以为这样就可以禁用了?我们试试取消勾选,如图。但是如果取消检查后继续点击Resume按钮,还是会停在debugger关键字出现的地方,没有任何效果。实际上,Breakpoints只代表我们手动添加的断点。对于debugger关键字声明的断点,这里直接取消是没有用的。这种情况还有其他办法吗?是的。我们可以先删除当前Breakpoints中的断点,然后在debugger语句所在行的行号上点击鼠标右键,这里会出现一个下拉菜单,如图。在行号上点击鼠标右键,会出现一个叫Neverpausehere的选项,意思是从不在这里暂停,我们选择这个选项,页面变成如图所示。点击Neverpausehere选项后,页面当前断点显示为橙色,并且多了一个?符号在断点前,Breakpoints也显示刚刚添加的断点位置。这时,再次点击Resume按钮,可以发现我们将不再进入无限Debugger模式。当然,我们也可以选择另外一个选项Addconditionalbreakpoint,如图。Addconditionalbreakpointoption这种模式比较高级,我们可以设置进入断点的条件,比如在调试过程中,期望某个变量的值大于某个特定值才停止。但是在这种情况下,由于这是一个死循环,我们没有任何具体的变量作为判断的依据,所以我们可以直接写一个简单的表达式来控制它。点击Addconditionalbreakpoint选项,直接填false,如图。设置Conditionalbreakpoint为false,设置为false,效果和这里选择Neverpause是一样的,再次点击Resume不会进入Debugger死循环。4.替换文件我们在上一节中介绍了Overrides面板的用法。我们可以使用它来用本地JavaScript文件替换远程JavaScript文件。这里我们仍然可以使用这种方法来替换文件。应该更换什么?很简单,我们只需要删除新文件中的debugger关键字即可。我们将当前的JavaScript文件复制到文本编辑器中,删除或者直接注释掉关键字debugger,修改如下:setInterval((function(){//debugger;//可以直接删除这一行或者注释掉这一行console.log("debugger")}打开Sources面板下的Overrides面板,将修改后的完整JavaScript文件复制进去,修改后的内容如图:替换JavaScript文件,会进入无限Debugger模式。在另外,我们也可以使用Charles、Fiddler等抓包工具进行替换,或者使用ReRes等浏览器插件进行替换,或者使用Playwright等工具使用RequestInterception进行替换,实现的效果是一致的,原理就是替换掉线上加载的JavaScript文件,最终消除无限Debugger。5.小结本节讲解无限Debugger绕过方案,包括禁用全局断点、条件断点、替换原始文件等。从这些操作中,我们也可以学到一些JavaScript逆向工程的基本思路。建议好好掌握这部分内容。
