// ==UserScript==
// @name 高级Debugger防护系统 v1.2
// @namespace http://tampermonkey.net/
// @version 1.2
// @description 全方位拦截网站反调试机制,支持白名单、日志记录及多场景防护
// @author doubao
// @match *://*/*
// @grant unsafeWindow
// @grant document-start
// @grant GM_addStyle
// ==/UserScript==
(function() {
'use strict';
// 配置选项
const config = {
enableLogging: true, // 启用日志记录
blockAllDebuggers: true, // 拦截所有debugger(包括自身)
useWhiteList: false, // 启用白名单模式
whiteList: ['example.com'], // 白名单域名(支持子域名包含匹配)
enableIframeGuard: true, // 启用iframe内容监控
enableConsoleGuard: true, // 启用控制台方法防护
};
// 日志系统
function log(message, type = 'info') {
if (!config.enableLogging) return;
const prefix = `[Debugger防护] [${type.toUpperCase()}]`;
switch(type) {
case 'error': console.error(prefix, message); break;
case 'warn': console.warn(prefix, message); break;
default: console.log(prefix, message);
}
}
// 域名白名单检查
function isDomainWhitelisted() {
if (!config.useWhiteList) return false;
const hostname = window.location.hostname;
return config.whiteList.some(domain => hostname.includes(domain));
}
// 白名单域名直接返回
if (isDomainWhitelisted()) {
log('当前域名在白名单中,防护系统未启用');
return;
}
// 加载Font Awesome图标(用于状态指示器)
GM_addStyle(`
@import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css');
#debugger-protector-status .fas { margin-right: 5px; }
`);
// 创建防护状态指示器
function createStatusIndicator() {
const indicator = document.createElement('div');
indicator.id = 'debugger-protector-status';
indicator.style.cssText = 'position:fixed;top:10px;right:10px;background:rgba(0,0,0,0.7);color:white;padding:5px 10px;border-radius:5px;font-size:12px;z-index:9999;';
indicator.innerHTML = '<i class="fas fa-shield-alt"></i> Debugger防护已启动';
document.body.appendChild(indicator);
}
// 调试器活动检测陷阱
function createDebugTrap() {
let trapTriggered = false;
setInterval(() => {
const start = performance.now();
debugger; // 主动触发debugger检测
const end = performance.now();
// 调试器激活时执行时间会显著增加(>100ms)
if (end - start > 100) {
if (!trapTriggered) {
log('检测到调试器活动!', 'warn');
trapTriggered = true;
}
} else {
trapTriggered = false;
}
}, 5000); // 每5秒检测一次
}
// === 核心Hook防护模块 ===
// Hook构造函数
Function.prototype._constructor = Function.prototype.constructor;
Function.prototype.constructor = function() {
const argsStr = arguments.toString();
if (argsStr.includes("debugger")) {
log(`拦截到构造函数注入debugger: ${argsStr.substring(0, 100)}...`);
return null;
}
return Function.prototype._constructor.apply(this, arguments);
};
// Hook Function构造器
const originalFunction = Function;
Function = function() {
const args = Array.from(arguments).join(' ');
if (args.includes('debugger')) {
log(`拦截到Function注入debugger: ${args.substring(0, 100)}...`);
return () => {}; // 返回空函数避免异常
}
return originalFunction.apply(this, arguments);
};
Function.prototype = originalFunction.prototype;
// Hook eval函数(使用unsafeWindow确保拦截原生方法)
const originalEval = eval;
unsafeWindow.eval = function(code) {
const codeStr = String(code);
if (codeStr.includes('debugger')) {
log(`拦截到eval注入debugger: ${codeStr.substring(0, 100)}...`);
return ''; // 返回空字符串防止执行
}
return originalEval.call(unsafeWindow, code);
};
// 保护Function.prototype.toString不被检测Hook
const originalToString = Function.prototype.toString;
Function.prototype.toString = function() {
if (this.name === 'eval' || this.name === 'Function') {
return originalToString.call(this); // 保留原生方法避免检测
}
return originalToString.apply(this, arguments);
};
// Hook定时器家族(setInterval/setTimeout/requestAnimationFrame)
const hookTimer = (originalTimer, timerName) => {
return function(callback, delay, ...args) {
let cbStr = '';
if (typeof callback === 'function') {
cbStr = callback.toString();
} else if (typeof callback === 'string') {
cbStr = callback;
}
if (cbStr.includes('debugger')) {
log(`拦截到${timerName}注入debugger: ${cbStr.substring(0, 100)}...`);
return null; // 阻止定时器创建
}
return originalTimer.apply(this, [callback, delay, ...args]);
};
};
window.setInterval = hookTimer(window.setInterval, 'setInterval');
window.setTimeout = hookTimer(window.setTimeout, 'setTimeout');
window.requestAnimationFrame = hookTimer(window.requestAnimationFrame, 'requestAnimationFrame');
// Hook DOM操作(拦截innerHTML中的debugger)
const originalAppendChild = Node.prototype.appendChild;
Node.prototype.appendChild = function(node) {
if (node && node.innerHTML) {
const html = node.innerHTML;
if (html.includes('debugger')) {
const cleanedHtml = html.replace(/debugger/g, '// debugger已被拦截');
node.innerHTML = cleanedHtml;
log(`拦截到DOM注入debugger,已清理内容`);
}
}
return originalAppendChild.apply(this, arguments);
};
// Hook元素属性设置(拦截事件属性中的debugger)
const originalSetAttribute = Element.prototype.setAttribute;
Element.prototype.setAttribute = function(name, value) {
if (typeof value === 'string' && value.includes('debugger')) {
const cleanedValue = value.replace(/debugger/g, '// debugger已被拦截');
log(`拦截到属性注入debugger: ${name}`);
return originalSetAttribute.call(this, name, cleanedValue);
}
return originalSetAttribute.apply(this, arguments);
};
// Hook事件监听(拦截事件回调中的debugger)
const originalAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(type, listener, options) {
if (typeof listener === 'function') {
const listenerStr = listener.toString();
if (listenerStr.includes('debugger')) {
log(`拦截到事件监听器注入debugger: ${type}`);
return; // 阻止添加带debugger的监听器
}
}
return originalAddEventListener.apply(this, arguments);
};
// Hook Web Workers(检测worker脚本中的debugger)
if (window.Worker) {
const OriginalWorker = window.Worker;
window.Worker = function(url, options) {
if (typeof url === 'string') {
// 同步检查worker脚本(避免跨域问题使用try-catch)
try {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, false);
xhr.send();
if (xhr.status === 200 && xhr.responseText.includes('debugger')) {
log(`拦截到Worker注入debugger: ${url}`);
return {
postMessage: () => {},
terminate: () => {}
}; // 返回空Worker对象
}
} catch (e) {
log(`Worker同步检查失败: ${e.message}`, 'warn');
}
}
return new OriginalWorker(url, options);
};
}
// === 增强防护模块 ===
// Hook控制台debug方法(防止console.debug注入debugger)
if (config.enableConsoleGuard && console.debug) {
const originalConsoleDebug = console.debug;
console.debug = function() {
const args = Array.from(arguments).join(' ');
if (args.includes('debugger')) {
log('拦截到console.debug注入debugger', 'warn');
return;
}
return originalConsoleDebug.apply(this, arguments);
};
}
// 监控iframe创建(拦截iframe中的debugger)
if (config.enableIframeGuard) {
new MutationObserver(mutations => {
for (const mutation of mutations) {
if (mutation.type === 'childList') {
for (const node of mutation.addedNodes) {
if (node.tagName === 'IFRAME') {
try {
const contentDoc = node.contentDocument || node.contentWindow?.document;
if (contentDoc) {
const contentText = contentDoc.documentElement?.textContent || '';
if (contentText.includes('debugger')) {
log('拦截到iframe注入debugger,已移除', 'warn');
node.remove();
}
}
} catch (e) {
// 跨域iframe会报错,忽略即可
}
}
}
}
}
}).observe(document, { childList: true, subtree: true });
}
// === 启动防护 ===
createStatusIndicator();
if (config.blockAllDebuggers) {
createDebugTrap();
}
log('高级Debugger防护系统 v1.2 已启动', 'info');
})();