关于浏览器Devtools的open,close监听

关于浏览器Devtools的open/close监听

前言

常见open行为结果

  • 无限debugger
  • 反复刷新页面
  • 跳转指定页面

页面跳转:

*// 类似 HTTP 重定向到菜鸟教程*
window.location.replace("http://localhost");
*// 类似点击菜鸟教程的链接(a 标签)*
window.location.href = "http://localhost";

关闭页面:

window.close()  // 不过只能由 Window.open() 方法打开的窗口的 window 对象来调用。

通常各个监听行为都使用了setIntervalsetTimeout函数, 不方便debug的时候可以使用 定时器事件断点

以下是sgcc.com.cn中对于打开devtool行为的处理

    try {
        window.opener = null,  // 返回打开当前窗口的那个窗口的引用
            window.open("", "_self"),  // 这里先使用了, open方法打开当前窗口, 再使用close去关闭
            window.close(),   // 关闭当前窗口, 不过有时候还是会失败(应该与浏览器有关系)
            window.history.back()  // 会话历史记录中向后移动一页, 没有不执行
    } catch (e) {
    }
    setTimeout((function () {
            window.location.href = f.timeOutUrl || 
              "https://theajack.github.io/disable-devtool/404.html?h=".concat(encodeURIComponent(location.host))
        }
    ), 500)

一些使用了反调试的网站

TIP: 浏览器的不同可能导致方法在不同的浏览器出现不同的结果

1. 窗口判断

方案: 根据浏览器窗口判断

缺点: 无法监听独立窗口的devtool

demo: https://sindresorhus.com/devtools-detect/

代码: sindresorhus/devtools-detect: Detect if DevTools is open and its orientation (github.com)

const devtools = {
	isOpen: false,
	orientation: undefined,
};

const threshold = 170;

const main = ({emitEvents = true} = {}) => {
	const widthThreshold = globalThis.outerWidth - globalThis.innerWidth > threshold;
	const heightThreshold = globalThis.outerHeight - globalThis.innerHeight > threshold;
	const orientation = widthThreshold ? 'vertical' : 'horizontal';

	if (
		!(heightThreshold && widthThreshold)
		&& ((globalThis.Firebug && globalThis.Firebug.chrome && globalThis.Firebug.chrome.isInitialized) || widthThreshold || heightThreshold)
	) {
		devtools.isOpen = true;
		devtools.orientation = orientation;
	} else {

		devtools.isOpen = false;
		devtools.orientation = undefined;
	}
};

2. debugger时间差

方案: 打开控制台会触发debugger, 导致debugger前后时间差过大; 根据时间差判断是否打开控制台

缺点: 容易被定位到关键代码位置, 覆盖/重写关键函数即可破解; 使用debugger直接使用永不在此暂停就跳过了这个debug

相关:

  • demo: https://codepo8.github.io/console-killer/demo.html
  • 代码: https://github.com/codepo8/console-killer
  • 文章: https://dev.to/codepo8/cracking-a-developer-tools-killer-script-2lpl

具体代码还做了对F12, 右键菜单做了屏蔽,无法在demo中打开控制台; 但是这种无法避免我先打开控制台, 再进行访问地址

var minimalUserResponseInMiliseconds = 200;
function check() { 
    console.clear();
    before = new Date().getTime();
    debugger;
    after = new Date().getTime();
    if (after - before > minimalUserResponseInMiliseconds) { 
        document.write(" Dont open Developer Tools. ");
        self.location.replace(
            window.location.protocol + window.location.href.substring(
                window.location.protocol.length
            )
        );  
    } else { 
        before = null;
        after = null;
        delete before;
        delete after;
    }
    setTimeout(check, 100);
}

3. 读取元素id

利用Chrome开发者工具会自动读取元素id的特性,重写getter实现需求
let element = document.createElement('checkDevTools');
Object.defineProperty(element, 'id', {
    get: function () {
        /* TODO */
        isDevToolsOpened = true;
    }
});
element.__defineGetter__('id', function () {
    isDevToolsOpened = true;
});
console.debug(element); //使用console.debug()使打印出的辅助信息默认隐藏

4. performance对象比较性能

博客: 如何知道 Chrome 控制台何时打开 (guya.net)

demo: Chrome Developer Tools State (guya.net)

APi: Performance - Web API | MDN (mozilla.org)

  • **通过performance对象:**可以使用performance对象来检测页面加载的性能。一般情况下,开发者工具的打开会对性能指标产生一些影响,如资源加载时间的延长。因此,可以通过比较某些性能指标的值来判断开发者工具是否打开。
if (performance.memory && performance.memory.usedJSHeapSize > 0) {
  console.log("Developer tools open"); // 内存使用情况大于0,可能表示开发者工具已打开
}

5. toString

对于一些浏览器,比如Chrome、FireFox,如果控制台输出的是对象,则保留对象的引用,每次打开开发者工具的时候都会重新调用一下对象的toString()方法将返回结果打印到控制台(console tab)上。

所以只需要创建一个对象,重写它的toString()方法,然后在页面初始化的时候就将其打印在控制台上(这里假设控制台还没有打开),当用户打开控制台时会再去调用一下这个对象的toString()方法,用户打开控制台的行为就会被捕获到。

缺点: 只能捕获到开发者工具处于关闭状态向打开状态转移的过程(先打开devtool再访问网页即可破解)

var devtools = function() {};
// var devtools = /./;
devtools.toString = function() {
  if (!this.opened) {
    alert("Opened");
  }
  this.opened = true;
}

console.log('%c', devtools);

不过使用这个在新版的 chrome 126.0.6478.127中貌似已经失效了, 我测试theajack/disable-devtool库只能使用窗口判断和性能判断两种方式可以触发这个版本的 chrome.

三方库:

1. theajack/disable-devtool

github: theajack/disable-devtool: Disable web developer tools from the f12 button, right-click and browser menu (github.com)

demo: Disable web developer tools with one line (theajack.github.io)

使用的检测方法如下:

  RegToString = 0, // 根据正则检测
  DefineId, // 根据dom id检测
  Size, // 根据窗口尺寸检测
  DateToString, // 根据Date.toString 检测
  FuncToString, // 根据Function.toString 检测
  Debugger, // 根据断点检测,仅在ios chrome 真机情况下有效
  Performance, // 根据log大数据性能检测

sgcc.com.cn 网站使用了这个库

2. AEPKILL/devtools-detector

使用了多种检查方式判断

github: devtools-detector/src/index.ts at master · AEPKILL/devtools-detector (github.com)

demo: https://blog.aepkill.com/demos/devtools-detector/

other:

讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦中千秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值