不知道从什么时候开始,越来越多的网站都使用了各式手段来阻止用户使用浏览器的开发者工具(DevTools / debugger) 对页面进行分析、下载或修改。而对于现代前端而言,使用 JavaScript 对 DOM 进行渲染如同家常便饭,离开开发者工具则很难从页面中找到有价值的内容。
我将例举几种我见过的反调试方案,并简单介绍对这些反调试方案的 反反调试 手段。
按键事件劫持
一般而言大家应该都会比较习惯使用 Ctrl+Shift+I 组合键,或者 F12 来打开开发者工具,也会使用类似 Ctrl+S、等组合键保存页面,很多网站也针对这些按键做出了事件监听来劫持用户的真实操作意图。对于这种情况,稍有经验的开发者或用户都可以在浏览器的工具栏中找到“开发者工具”。以 Chrome 为例,该选项位于此处:
这种方案其实是最理智的。防君子不防小人,足够挡下通过百度经验和小红书这类地方学习 ”使用小技巧“ 就想要下载你网站里内容的用户;对于专业用户而言前端本身就防不胜防,何必互相为难呢。
debugger 命令
如果你遇到打开浏览器开发者工具后页面就无法正常工作的情况,100% 都是此类手段。因为 debugger 命令只有在开发者工具打开时才有效,平时是没有任何效果的,所以当用户打开开发者工具时,一直被 setInterval()
轮询的 debugger 将触发断点,并在断点后面紧接一行 window.close()
甩脸来干扰正常调试。这种方案更精准,也更具攻击性。
如果只是想要获得网站资源的话只需要提前通过 Ctrl+F8 停用断点功能就行了。而如果你想继续调试的话,说明站长已经决定和身为前端开发的你宣战,接招吧!
另外,在调试之前方便起见,可以先禁止一些类似这样的事件
写在明处的 debugger 指令
右键点击 debugger 所在的行号,选择 Never pause here 并按一下 F8 使代码继续执行就好了。
如果是 uglify 压缩处理后的代码,先使用浏览器的工具将其自动格式化成人类友好的代码,操作如上。
使用匿名函数构造的 debugger
一般来说断点信息是这样的:
(function anonymous(
) {
debugger
})
在 console 中输入以下代码并 F8 继续执行就行。
Function.prototype.constructor=function(){}
使用 Function 构造 debugger
断点信息大概是这样的结构,比构造函数多了一个 Function 关键字的样子:
(function anonymous(
) {
Function("debugger")()
})
同理,在 console 中输入以下代码并 F8 继续执行就行。
Function = function () {}
上面的例子只是典型,有时候网站开发者会用拼接字符串的方法掩饰 debugger 字样,但是本质还是换汤不换药的。
检查视口大小和浏览器窗口大小
非常少见的方案,一个很简单的解决方案是直接把 DevTools 设置为浮动窗口就行了。我自己遇到的一个例子里,开发者是这样写的:
var check = setInterval(function() {
if (window.outerWidth - window.innerWidth > threshold || window.outerHeight - window.innerHeight > threshold) {
window.location.reload();
}
}, 1000);
不难看出,我只要抢在一切发生前在终端输入 clearInterval(check)
清除掉这个定时器就行了。其实遇到这种情况时,作为专业水平更高,对项目同样感兴趣的你应当主动私信询问对方是否需要技术方面的帮助;你的帮助对于用爱发电的大家很有必要。
抓包
浏览器端没有什么证书验证,一个自签证书走天下。应该是最简单高效的获取页面资源的方案了。
该方案针对资源抓取和接口分析都是杀手锏。虽然有时候接口传递的数据被预先加密或编码,但动态分析因为未知原因行不通的你还是静下心做静态分析吧。