js
function recordBehavior(_0x57bedd, _0x1d62c8) {
console["log"]("行为记录:", {
"action": _0x57bedd,
"data": _0x1d62c8,
"timestamp": Date["now"]()
});
}
function _ÿijjji() {
try {
if (console["table"]["toString"]() !== "function table() { [native code] }") {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
};
if (console["table"]["toString"]() !== Function["prototype"]["toString"]["call"](console["table"])) {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
};
if (console["clear"]["toString"]() !== "function clear() { [native code] }") {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
};
if (setInterval["toString"]() !== "function setInterval() { [native code] }") {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
};
if (setTimeout["toString"]() !== "function setTimeout() { [native code] }") {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
};
if (setInterval["toString"]() !== Function["prototype"]["toString"]["call"](setInterval)) {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
};
if (setTimeout["toString"]() !== Function["prototype"]["toString"]["call"](setTimeout)) {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
};
if (Date["now"]["toString"]() !== "function now() { [native code] }") {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
};
if (performance["now"]["toString"]() !== "function now() { [native code] }") {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
}
if (console["log"]["toString"]() !== "function log() { [native code] }") {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
}
return false;
} catch (_0x43ee34) {
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
return true;
}
}
function _ÿbgbad() {
var _0x1d1aeb = performance["now"]();
_ÿijjji();
var _0x29fa91 = Array(1000)["fill"]()["map"](function (_0x31947b, _0x3b4860) {
return {
"id": _0x3b4860,
"name": "test" + _0x3b4860,
"value": Math["random"]()
};
});
console["table"](_0x29fa91);
console["clear"]();
var _0x1a88d8 = performance["now"]();
var _0x33304b = _0x1a88d8 - _0x1d1aeb;
console["log"]("执行时间:", _0x33304b);
if (_0x33304b > 10) {
recordBehavior("debugger_detected", {
"executionTime": _0x33304b,
"timestamp": Date["now"]()
});
location["href"] = "https://yuanshen.com/";
document["body"]["innerHTML"] = "检测到调试环境,页面已被保护。";
}
}
_ÿaedfa = setInterval(_ÿbgbad, 1000);
这段代码是一段典型的前端反调试(Anti-debugging)与代码保护 脚本。它的核心目的是检测用户是否打开了浏览器开发者工具(F12),如果检测到调试行为,就会强制将页面跳转到其他网站(如代码中的 yuanshen.com)。
以下是该代码的详细分析:
1. 核心检测机制
这段代码通过两个维度来判断环境是否"安全":原生函数完整性校验 和执行时间差检测。
A. 函数原生性校验 (_ÿijjji 函数)
它大量使用了 .toString() 方法来检查浏览器内置函数(如 console.log, setInterval, setTimeout, Date.now 等)是否被篡改。
- 原理 :在正常的浏览器环境中,输入
console.log.toString()会返回"function log() { [native code] }"。 - 目的 :防止开发者通过"钩子"(Hook)技术修改这些函数来绕过检测。如果某个函数被用户自定义的代码覆盖了,它的
toString()结果就会改变,从而触发保护机制。
B. 性能差异检测 (_ÿbgbad 函数)
这是最精巧的部分。它利用了开发者工具开启时会对页面性能产生负面影响的特性。
- 它先记录一个开始时间
performance.now()。 - 接着运行
console.table()打印一个包含 1000 条数据的复杂表格,然后迅速用console.clear()清除。 - 关键点 :如果开发者工具(Console 面板)是关闭 的,这个渲染过程极快;如果开发者工具是开启的,浏览器渲染这个大表格会消耗显著的时间。
- 最后计算差值,如果耗时超过 10ms,则判定为正在被调试。
2. 逻辑流程图
3. 函数功能拆解
| 函数名 | 核心功能 |
|---|---|
recordBehavior |
日志记录。将检测到的"异常行为"记录到控制台(或发送至后台),包含动作名称和当前时间戳。 |
_ÿijjji |
环境白名单校验 。检查 console、Date、performance 等对象是否处于原生状态。一旦发现被修改,立即返回 true 并跳转。 |
_ÿbgbad |
主检测循环。执行性能测试。通过模拟高负载的控制台渲染任务,观察系统反馈速度。 |
setInterval |
持续监控。每隔 1000 毫秒(1秒)自动运行一次检测,确保用户在页面停留期间无法中途打开调试器。 |
4. 触发后果
一旦代码判定你在调试(无论是函数被 Hook,还是渲染超时),它会执行以下操作:
- 强制跳转 :
location.href = "https://yuanshen.com/";(将页面重定向)。 - 清空内容 :
document.body.innerHTML = "检测到调试环境,页面已被保护。";。
5. 总结与评价
- 有效性 :这种方法在应对初级和中级分析时非常有效,尤其是
console.table时间差检测,是目前前端反调试的常用手段。 - 局限性:
- 误判率:在性能极差的旧设备或低端手机上,即使不开启调试器,渲染 1000 条数据也可能超过 10ms,导致普通用户无法访问。
- 对抗性 :高级开发者可以通过禁用
setInterval、在页面加载前注入屏蔽脚本、或者使用非标准的调试手段(如远程调试协议)来绕过。