前言
- 上篇讯飞星火认知大模型web端打开控制台就跳转空白页防debugger技术分析学习(一)分析了是用定时器循环检测到devtool开发工具 打开并调用ondevtoolopen方法进行跳转的,附上ondevtoolopen函数跳转代码:
分析
- 代码是如何判断用户是否打开了devtool开发工具呢,肯定需要某种特征
第一种
- 容易想到的,如果,devtool 是嵌入到页面中的,打开时页面的宽高 发生变化,我们就可以监听窗口size 事件,来触发ondevtoolopen方法
- 下面来复现下
- 首先要调成devtool嵌入模式
2. 进行栈回溯,可以看到,对窗口进行了检测,具体的检测窗口变化代码在函数checkWindowSizeUneven,请自行分析
第二种
- 如果devtool ,没有嵌入到页面,这样找开的时间,size事件是不是就监听不到了呢,那要如何来检测呢
- 下面调成devtool非嵌入模式来复现下
- 可以看到onDevToolOpen 打开前有一个判断条件t > 10 * this.maxPrintTime 这个就是用来判断是否打开了devtool,下面摘出代码:
js
{
key:"detect",
value:function() {
var e = this
, t = g((function() {
I(e.largeObjectArray)
}
))
, n = g((function() {
D(e.largeObjectArray)
}
));
if (this.maxPrintTime = Math.max(this.maxPrintTime, n),
M(),
0 === t || 0 === this.maxPrintTime)
return !1;
t > 10 * this.maxPrintTime && this.onDevToolOpen()
}
}
- t > 10 * this.maxPrintTime ,又因为his.maxPrintTime = Math.max(this.maxPrintTime, n)只需要判断t 和10倍n 关系即可,下面分析t 和n怎么等到的:
js
t = g((function() {
I(e.largeObjectArray)
}
))
n = g((function() {
D(e.largeObjectArray)
}
))
function m() {
return (new Date).getTime()
}
function g(e) {
var t = m();
return e(),
m() - t
}
- 可以看到二者都是通过同一个g 得出的,里面函数内部执行了I 函数和D函数
- g 函数内部执行e参数,也就是执行I D 函数,g的返回值就是一个执行代码的时间差值
- 在执行I 函数控制台会打印出一个数组表格 ,肯定就是I函数打印的
- 把鼠标悬在I 函数发现name为table 和console.table对比,是同一个
- D函数同理
- 打印的值就是e.largeObjectArray ,控制台输出e.largeObjectArray是一个二维数组
- 可以先出结论,判断控制台打开条件就是console.table 打印耗费的时间大于console.log 的10倍即可,两者关系不打开控制台的情况下我没对比过,暂时没想出怎么对比,欢迎留言
总结
- 通过分析学习,我们可以使用这两种方法来检测debugger
- 监听窗口的size事件
- 通过输出一个复杂的二维数组,比较console.table 和console.log执行时间
待续
- 百度的文心一言采用了更高级防degguer白屏模式,如果后续呼声高了,就继续分析学习