本文介绍了使用特定方案在Edge和Chrome浏览器上忽略debugger语句,同时定义属于自己的debugger,且不影响代码的可移植性。文章涵盖了项目的使用方式、网站检测调试的原理与绕过、以及自定义debugger和CDP协议的相关知识。
包括修改浏览器的启动参数、使用powershell脚本快速启动浏览器、手动添加OpenDevtoolsPage插件、运行cdp_server等步骤。
介绍了网站检测控制台是否打开的方式,以及如何利用anti_dev_detector.js去除这些检测。同时提到了利用Console API、报错式检测等检测逻辑与处理方式。
介绍了如何修改cdp_server和OpenDevtoolsPage插件的配置,以实现自定义debugger,如设置独属于自己的hello_world等。
简要介绍了CDP协议(Chrome DevTools Protocol)的原理,以及它在项目中的应用。同时提到了浏览器插件的debugger API和需要额外搭建服务器进行拦截的原因。
作者
论
坛账号:LoveCode
这次不是斗法、是锻造法器啦。
使用本文的方案,
可以在
Edge、Chrome
浏览器上忽略
debugger
语句,同时可以定义属于自己的
debugger
—— 而且不影响代码的可移植性哟
。
这是本文的结构:
-
本方案的缺点 —— 至关重要,必看内容!
-
项目的使用方式 —— 我知道你很急,所以放在了前面
-
网站检测调试的原理与绕过 —— 安心地打开开发者工具
-
简述本文方案的原理
本方案的缺点
使用本方案需要以下步骤:
上述操作可以在需要过 debugger 时再快速启用,
如果能接受以上繁杂的步骤,可以继续阅读下文了
。
项目的使用方式
本文以
Chrome
浏览器为例进行展示,
Edge
浏览器的配置也是一样的。
基本配置
step 1
访问项目,获取源代码:Hosinoharu/SkipJSDebugger。在
Releases
中的文件根据后文说明按需求下载。
step 2
修改浏览器的启动参数为如下情形,然后打开浏览器。
复制代码 隐藏代码
// chrome.exe --remote-debugging-port=9222 --remote-allow-origins=localhost
// --remote-debugging-port 启动远程调试端口,暂时定为 9222,后续可以手动修改
// --remote-allow-origins 远程调试时允许连接的来源,建议设置为 localhost。使用 * 运行任何来源
项目中提供了一个
powershell
脚本,位于
scripts\debug_browser.ps1
,可以等到需要的时候再快速启动浏览器。不过使用之前需要填入本机浏览器的位置。
复制代码 隐藏代码
# 找到脚本的这个位置,修改这两个变量的值为本机的浏览器的路径
$Edge = "C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
$Chrome = "E:\Google\Chrome\Application\chrome.exe"
基本使用如下:
复制代码 隐藏代码
# 首先修改 powershell 执行脚本的权限
Set-ExecutionPolicy RemoteSigned
# 然后按需执行下面任意一条命令打开浏览器,注意!执行 ps 脚本时需要加上路径哟
.\debug_browser.ps1 # 默认打开 Chrome 浏览器,远程调试端口为 9222
.\debug_browser.ps1 -Port 8888 # 默认打开 Chrome 浏览器,远程调试端口为 8888
.\debug_browser.ps1 Edge # 打开 Edge 浏览器,远程调试端口为 9222
.\debug_browser.ps1 Edge -Port 8888 # 打开 Edge 浏览器,远程调试端口为 8888
step 3
手动添加插件
OpenDevtoolsPage
,其位于项目根目录。在浏览器地址栏输入
chrome://extensions/
打开界面,然后如下进行添加:
step 4
运行
cdp server
,位于项目的
cdp_server
目录中,共有两个版本。
下图本机的处理效果。提交到
Github Releases
的文件
SHA256 hash
:
F96B7896A2ED14BC088DCB37B030F2C6A2B81E559FEE9DA632695B498C2E97EA
step 5
测试效果。先打开项目的
test/test_debugger.html
文件,然后按下述步骤测试:
然后
关闭刚刚打开的开发者工具,刷新网页
,继续下面的操作。
注:现在给插件换了个图标,所以和下图会有些区别。
如果以上过程顺利,那么现在可以忽略其它网站的
debugger
语句了。
关于插件打开的开发者工具
确保点击插件
OpenDevtoolsPage
打开新的开发者工具时,
要关闭由
F12
键等方式打开的、原版自带的开发者工具
,否则在显示上一定会出现问题 —— 因为出现了两个开发者工具调试网站。
如果点击插件打开开发者工具后,出现这样的信息,说明程序可能出错了,先检查上述的步骤,如果依然未能解决问题,可以在评论区说明。
补充说明
内嵌的开发者工具就是按
F12
键打开的那个版本,它的链接是
devtools://devtools/bundled/inspector.html
,在浏览器中可以输入该链接进行访问。
本来是使用这个进行调试的,经过测试它会造成浏览器闪退(是浏览器突然就消失了,并不会弹出一个警告框告诉我浏览器已经崩溃),所以使用了远程调试的版本,即
localhost:port/devtools/inspector.html
这个版本。
这带来一个问题:得重新设置一下开发者工具
,我指的是一些设置项、布局等需要重新设置一下。
自定义 debugger
默认情况下 —— 指的是:启动
cdp_server
,并且用插件打开开发者工具,浏览器会忽略普通的
debugger
语句,且只会在
lovedebug()
函数的下一行断住 —— 其它的手动断点、条件断点均不受影响啦。
即默认情况下使用
lovedebug()
函数作为预定义的
debugger
,下面展示如何使用它。
如果需要设置独属于自己的
debugger
,比如取名为
hello_world
,那么请按照以下步骤进行
。
第一步,修改
cdp server
。
如果使用
Python
实现的版本,修改
cdp_server/py/settings.py
的这里。
如果是使用
Go
实现,后续执行程序时传参:
cdp_server.exe -debugger hello_world
即可,也可以自行修改源代码进行编译。
另外,使用
cdp_server.exe -h
可以查看有哪些参数
。
第二步,修改
OpenDevtoolsPage
插件的配置。
自定义端口
总共有 2 个端口可以自定义。
一个是浏览器的远程调试端口
,默认使用的
9222
。如果要修改它,比如修改为
8888
。
首先要修改
Chrome
的启动参数
--remote-debugging-port=8888
。如果使用上述的 PS 脚本时需要传参。
对于
cdp_server
:
然后打开
OpenDevtoolsPage
插件的设置项做相应的修改。
一个是
cdp_server
的端口
,默认使用的是
9221
。如果要修改它,比如修改为
8887
。
对于
cdp_server
:
然后打开
OpenDevtoolsPage
插件的设置项做相应的修改。
网站检测调试的原理与绕过
现在去除了
debugger
语句,网站还有一些检测控制台是否打开的方式,在项目中有一个 JS 文件,其位于
scripts\anti_dev_detector.js
,它就是为了去除这些检测。
因为整个项目,额……略显鸡肋?所以我将它单独拿了出来,请将它放在油猴插件中运行。
在
test\test_console.html
文件中整理了我搜索到的检测方式,下面阐述相关的检测逻辑与处理。
利用 Console API
如果是使用
Console API
进行检测,那么将其
Hook
并改为空函数即可。当然还有一些检测被
Hook
的方式,常见的是检测
.toString()
返回结果。
我建议不要使用以下方式进行 hook:
复制代码 隐藏代码
const raw_log = console.log;
console.log = function log() {}
// 省略其它的步骤,如增加 toString()、或者添加属性描述符等等
建议利用
Proxy API
进行 hook:
这样处理
.toString()
检测就方便了。
如下是测试:
报错式检测
这种检测方案来自
https://www.bilibili.com/video/BV1Gi421C7Rz
,核心思想是添加属性描述符
getter
,所以通过
Hook Object.defineProperty、Object.prototype.__defineGetter__
等函数可以过掉。
在
test/teset_console.html
文件中已经加入了这种检测。
请注意,一些前端框架可能利用这种方式进行错误日志记录等等,所以如果网站功能出现异常,应该禁用脚本
。
其它检测方案
基于
debugger
语句的检测方案现在可以忽略不谈了,比如下面这种:
复制代码 隐藏代码
const a = new Date;
debugger;
const b = new Date;
if ((b - a) > 10) {
alert("检测到啦")
}
还有检测
F12
按键、浏览器窗口的大小变化的检测方案也不用谈了,因为现在是点击插件打开的浏览器开发者工具。
其它的大都是利用
Console API
,比如下面这种形式。
复制代码 隐藏代码
const re = /x/;
re.toString = function () {
alert("检测到啦");
}
console.log(re);
还有这种形式的递归循环 + debugger,本质上还是利用的 debugger。
复制代码 隐藏代码
setInterval(function() {
check
()
}, 4000);
var check = function() {
function doCheck(a) {
// 无论进入哪个分支都会调用 debugger 语句
if (("" + a/a)["length"] !== 1 || a % 20 === 0) {
(function() {}
["constructor"]("debugger")())
} else {
(function() {}
["constructor"]("debugger")())
}
doCheck(++a) // 这里递归调用
}
// 一直调用,直到堆栈溢出出错,然后进入 catch 块中
try {
doCheck(0)
} catch (err) {}
};
check();
目前我所搜索到的、稳定的检测方案就这些了。
本方案原理
仅图示原理,并未从代码上详细解释。
关于 Chrome Devtools Protocol
Chrome Devtools Protocol
简称
CDP
,是一种通信协议,通常使用
websocket
进行传输。
简单描述为如下:
如何理解呢?
-
按
F12
键能打开开发者工具界面,将它单独分离出来。
-
继续按
Ctrl+Shift+I
还能打开它的开发者工具。
-
然后就能看到原来的那个开发者工具位于
devtools://
下。
-
所以说,开发者工具其实是单独的个体哟,调试过程中它和浏览器引擎进行通信啦。
更详细内容请查看其它文章。
-
深入浅出 CDP (Chrome DevTools Protocol) - Bigben - 博客园 (cnblogs.com)
-
CDP 远程调试方案什么是 cdp 协议 cdp 协议简称 chrome 调试协议,是基于 scoket(websock - 掘金 (juejin.cn)
-
Chrome DevTools 远程调试协议分析及实战-腾讯云开发者社区-腾讯云 (tencent.com)
浏览器可以查看 CDP 协议的内容哟,具体可以见文档:
现在我们已经知道
CDP
,当浏览器开启远程调试时(调试端口为上文提到的
9222
,会开放对应页面的调试链接,通过搭建一个中转服务器(即
Proxy
、代{过}{滤}理),可以拦截、并修改 cdp 协议内容。
浏览器插件的
debugger API
可以发送、查看 cdp 通信内容,无法进行拦截与修改。
所以需要额外搭建一个服务器进行拦截。
好了,下面是画图简述原理。
忽略 debugger 语句
简单来说就是这种的:
具体逻辑是这样的。
那么依据此就可以实现这样的逻辑:
自定义 debugger 语句
先看一个普通函数
hello
的调用情况。
那么思路就是这样的。
在
Debugger.paused
消息中是可以看到调用栈信息的,从而在
cdp server
进行判断与拦截。
End
最初有这个想法、并测试成功时我很激动;当我完成并测试更多网站时,我热血沸腾。直到我找一些开源项目做测试,如
disable-devtool、console-ban
等,看了一些 issue,还有一些网站中作者的留言,感叹各有各的烦恼 —— 小网站流量少,为爱发电被薅羊毛,时间不够钻研技术,用开源方案或花钱买服务,买的肯定不会是瑞数级别的,钱都拿去租服务器了,太简单的又……拿来当入门练习了。
www.52pojie.cn
👆👆👆
公众号
设置“星标”,
您
不会错过
新的消息通知