您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
全方位拦截disable-devtool,支持多种加载方式,可拖拽悬浮控制面板
// ==UserScript== // @name DisableDevtool万能拦截器 - 增强版 // @namespace http://tampermonkey.net/ // @version 3.1 // @description 全方位拦截disable-devtool,支持多种加载方式,可拖拽悬浮控制面板 // @author MissChina // @match *://*/* // @run-at document-start // @grant none // @icon https://github.com/MissChina/anti-disable-devtool/raw/main/icon.png // ==/UserScript== (function() { 'use strict'; // 扩展的检测关键字(根据源码分析得出的特征) const TARGET_PATTERNS = [ // 文件名模式 'disable-devtool', 'anti-debug', 'devtool-disable', 'security', 'protect', // 域名模式(常见CDN) 'cdn.jsdelivr.net', 'unpkg.com', 'cdnjs.cloudflare.com', // 你遇到的具体案例 'vf.uujjyp.cn', 'frameworks' ]; // 代码特征检测(检测内联脚本) const CODE_SIGNATURES = [ 'DisableDevtool', // 核心对象名 'ondevtoolopen', // 特征方法名 'detectors', // 配置属性 'RegToString', // 检测器类型 'FuncToString', // 检测器类型 'clearIntervalWhenDevOpenTrigger', // 特有配置项 ]; let interceptCount = 0; let statusDiv = null; let isExpanded = false; let isDragging = false; let dragStartX = 0; let dragStartY = 0; let panelStartX = 0; let panelStartY = 0; let isMinimized = false; // 初始化启动信息 console.log('%c🛡️ DisableDevtool万能拦截器 - 增强版 v3.1', 'color: #10B981; font-weight: bold; font-size: 14px;'); console.log('%c👨💻 作者: MissChina (GitHub)', 'color: #6B7280; font-size: 12px;'); console.log('%c🔗 项目地址: https://github.com/MissChina/anti-disable-devtool', 'color: #6B7280; font-size: 12px;'); console.log('%c⚠️ 仅供个人非盈利使用,禁止商用', 'color: #F59E0B; font-size: 12px;'); // 检查是否为目标脚本 function isTargetScript(url, content = '') { if (!url && !content) return false; // 检查URL if (url) { const urlLower = url.toLowerCase(); if (TARGET_PATTERNS.some(pattern => urlLower.includes(pattern.toLowerCase()))) { return true; } } // 检查代码内容特征 if (content) { const codeSignatureCount = CODE_SIGNATURES.filter(sig => content.includes(sig) ).length; // 如果包含3个或以上特征,判定为目标脚本 return codeSignatureCount >= 3; } return false; } // 创建可拖拽的状态面板 function createStatusPanel() { if (!document.body) { setTimeout(createStatusPanel, 100); return; } statusDiv = document.createElement('div'); statusDiv.style.cssText = ` position: fixed; top: 15px; right: 15px; background: rgba(16, 185, 129, 0.9); color: white; padding: 8px 12px; border-radius: 20px; font-family: 'Segoe UI', sans-serif; font-size: 12px; z-index: 999999; box-shadow: 0 4px 20px rgba(0,0,0,0.25); border: 1px solid rgba(255,255,255,0.2); cursor: move; transition: all 0.3s ease; min-width: 120px; text-align: center; user-select: none; backdrop-filter: blur(10px); `; // 添加作者信息水印 const authorInfo = document.createElement('div'); authorInfo.style.cssText = ` position: absolute; bottom: -20px; right: 0; font-size: 8px; color: rgba(255,255,255,0.6); pointer-events: none; opacity: 0; transition: opacity 0.3s ease; `; authorInfo.textContent = 'by MissChina'; statusDiv.appendChild(authorInfo); updateStatusPanel(); document.body.appendChild(statusDiv); // 创建控制按钮容器 const controlButtons = document.createElement('div'); controlButtons.style.cssText = ` position: absolute; top: -8px; right: -8px; display: none; gap: 4px; `; // 最小化按钮 const minimizeBtn = document.createElement('div'); minimizeBtn.innerHTML = '−'; minimizeBtn.style.cssText = ` width: 16px; height: 16px; background: rgba(255, 193, 7, 0.9); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 10px; font-weight: bold; color: white; `; minimizeBtn.onclick = (e) => { e.stopPropagation(); toggleMinimize(); }; // 关闭按钮 const closeBtn = document.createElement('div'); closeBtn.innerHTML = '×'; closeBtn.style.cssText = ` width: 16px; height: 16px; background: rgba(220, 38, 38, 0.9); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 12px; font-weight: bold; color: white; `; closeBtn.onclick = (e) => { e.stopPropagation(); hidePanel(); }; controlButtons.appendChild(minimizeBtn); controlButtons.appendChild(closeBtn); statusDiv.appendChild(controlButtons); // 鼠标事件处理 statusDiv.addEventListener('mousedown', startDrag); statusDiv.addEventListener('click', handleClick); statusDiv.addEventListener('mouseenter', showControls); statusDiv.addEventListener('mouseleave', hideControls); // 全局事件监听 document.addEventListener('mousemove', handleDrag); document.addEventListener('mouseup', endDrag); // 悬停效果显示作者信息 statusDiv.addEventListener('mouseenter', () => { if (!isDragging) { statusDiv.style.background = 'rgba(16, 185, 129, 1)'; statusDiv.style.transform = 'scale(1.05)'; authorInfo.style.opacity = '1'; } }); statusDiv.addEventListener('mouseleave', () => { if (!isDragging) { statusDiv.style.background = 'rgba(16, 185, 129, 0.9)'; statusDiv.style.transform = 'scale(1)'; authorInfo.style.opacity = '0'; } }); // 5秒后自动半透明,减少干扰 setTimeout(() => { if (statusDiv && !isExpanded && !isMinimized) { statusDiv.style.opacity = '0.6'; } }, 5000); function startDrag(e) { if (e.target === minimizeBtn || e.target === closeBtn) return; isDragging = true; dragStartX = e.clientX; dragStartY = e.clientY; const rect = statusDiv.getBoundingClientRect(); panelStartX = rect.left; panelStartY = rect.top; statusDiv.style.cursor = 'grabbing'; statusDiv.style.transition = 'none'; e.preventDefault(); } function handleDrag(e) { if (!isDragging) return; const deltaX = e.clientX - dragStartX; const deltaY = e.clientY - dragStartY; let newX = panelStartX + deltaX; let newY = panelStartY + deltaY; // 边界检测 const maxX = window.innerWidth - statusDiv.offsetWidth; const maxY = window.innerHeight - statusDiv.offsetHeight; newX = Math.max(0, Math.min(newX, maxX)); newY = Math.max(0, Math.min(newY, maxY)); statusDiv.style.left = newX + 'px'; statusDiv.style.top = newY + 'px'; statusDiv.style.right = 'auto'; statusDiv.style.bottom = 'auto'; } function endDrag() { if (!isDragging) return; isDragging = false; statusDiv.style.cursor = 'move'; statusDiv.style.transition = 'all 0.3s ease'; } function handleClick(e) { if (e.target === minimizeBtn || e.target === closeBtn) return; if (isDragging) return; // 延迟执行,避免与拖拽冲突 setTimeout(() => { if (!isDragging) { togglePanel(); } }, 100); } function showControls() { if (!isMinimized) { controlButtons.style.display = 'flex'; } } function hideControls() { controlButtons.style.display = 'none'; } function toggleMinimize() { isMinimized = !isMinimized; if (isMinimized) { statusDiv.innerHTML = '<div style="padding: 2px 6px;">🛡️</div>'; statusDiv.style.minWidth = 'auto'; statusDiv.style.width = '24px'; statusDiv.style.height = '24px'; statusDiv.style.borderRadius = '50%'; controlButtons.style.display = 'none'; // 重新添加控制按钮到最小化状态 statusDiv.appendChild(controlButtons); } else { updateStatusPanel(); statusDiv.style.width = 'auto'; statusDiv.style.height = 'auto'; statusDiv.style.borderRadius = '20px'; statusDiv.appendChild(controlButtons); } } function hidePanel() { statusDiv.style.opacity = '0'; statusDiv.style.transform = 'scale(0.5)'; setTimeout(() => { if (statusDiv) { statusDiv.style.display = 'none'; } }, 300); // 10秒后重新显示 setTimeout(() => { if (statusDiv) { statusDiv.style.display = 'block'; statusDiv.style.opacity = '0.6'; statusDiv.style.transform = 'scale(1)'; } }, 10000); } } // 切换面板状态 function togglePanel() { isExpanded = !isExpanded; statusDiv.style.opacity = '1'; updateStatusPanel(); } // 更新状态显示 function updateStatusPanel() { if (!statusDiv || isMinimized) return; if (!isExpanded) { const status = interceptCount > 0 ? '🛡️' : '👁️'; const text = interceptCount > 0 ? `已拦截 ${interceptCount}` : '守护中'; statusDiv.innerHTML = ` <span>${status} ${text}</span> <div style="position: absolute; bottom: -20px; right: 0; font-size: 8px; color: rgba(255,255,255,0.6); pointer-events: none; opacity: 0; transition: opacity 0.3s ease;">by MissChina</div> `; statusDiv.style.padding = '6px 10px'; // 重新添加控制按钮 const existingControls = statusDiv.querySelector('[data-control-buttons]'); if (!existingControls) { const controlButtons = createControlButtons(); statusDiv.appendChild(controlButtons); } return; } // 详细模式 const devToolsStatus = testDevTools() ? '<span style="color: #86efac;">✅ 控制台可用</span>' : '<span style="color: #fca5a5;">❌ 控制台被禁</span>'; const interceptStatus = interceptCount > 0 ? `<span style="color: #86efac;">🛡️ 成功拦截 ${interceptCount}</span>` : '<span style="color: #fde68a;">👁️ 持续守护</span>'; statusDiv.innerHTML = ` <div style="font-weight: bold; margin-bottom: 4px;"> 🔒 万能拦截器 </div> ${devToolsStatus}<br> ${interceptStatus} <div style="margin-top: 6px; font-size: 10px; color: rgba(255,255,255,0.8);"> 点击收缩 • 拖拽移动 • by MissChina </div> <div style="position: absolute; bottom: -20px; right: 0; font-size: 8px; color: rgba(255,255,255,0.6); pointer-events: none; opacity: 0; transition: opacity 0.3s ease;">by MissChina</div> `; statusDiv.style.padding = '10px 14px'; // 重新添加控制按钮 const controlButtons = createControlButtons(); statusDiv.appendChild(controlButtons); } // 创建控制按钮 function createControlButtons() { const controlButtons = document.createElement('div'); controlButtons.setAttribute('data-control-buttons', 'true'); controlButtons.style.cssText = ` position: absolute; top: -8px; right: -8px; display: none; gap: 4px; `; // 最小化按钮 const minimizeBtn = document.createElement('div'); minimizeBtn.innerHTML = '−'; minimizeBtn.style.cssText = ` width: 16px; height: 16px; background: rgba(255, 193, 7, 0.9); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 10px; font-weight: bold; color: white; `; minimizeBtn.onclick = (e) => { e.stopPropagation(); toggleMinimize(); }; // 关闭按钮 const closeBtn = document.createElement('div'); closeBtn.innerHTML = '×'; closeBtn.style.cssText = ` width: 16px; height: 16px; background: rgba(220, 38, 38, 0.9); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; font-size: 12px; font-weight: bold; color: white; `; closeBtn.onclick = (e) => { e.stopPropagation(); hidePanel(); }; controlButtons.appendChild(minimizeBtn); controlButtons.appendChild(closeBtn); return controlButtons; } // 最小化切换 function toggleMinimize() { isMinimized = !isMinimized; if (isMinimized) { statusDiv.innerHTML = '<div style="padding: 2px 6px; cursor: pointer;">🛡️</div>'; statusDiv.style.minWidth = 'auto'; statusDiv.style.width = '24px'; statusDiv.style.height = '24px'; statusDiv.style.borderRadius = '50%'; statusDiv.style.opacity = '0.8'; } else { statusDiv.style.minWidth = '120px'; statusDiv.style.width = 'auto'; statusDiv.style.height = 'auto'; statusDiv.style.borderRadius = '20px'; statusDiv.style.opacity = '1'; updateStatusPanel(); } } // 隐藏面板 function hidePanel() { statusDiv.style.opacity = '0'; statusDiv.style.transform = 'scale(0.5)'; setTimeout(() => { if (statusDiv) { statusDiv.style.display = 'none'; } }, 300); // 10秒后重新显示为最小化状态 setTimeout(() => { if (statusDiv) { statusDiv.style.display = 'block'; statusDiv.style.opacity = '0.6'; statusDiv.style.transform = 'scale(1)'; isMinimized = true; toggleMinimize(); // 设为最小化状态 } }, 10000); } // 测试开发者工具 function testDevTools() { try { return typeof console !== 'undefined' && typeof console.log === 'function'; } catch(e) { return false; } } // 拦截脚本核心函数 function interceptScript(scriptElement, method) { const src = scriptElement.src || scriptElement.getAttribute('src') || ''; const content = scriptElement.textContent || scriptElement.innerHTML || ''; if (isTargetScript(src, content)) { interceptCount++; console.log(`🛡️ [万能拦截器] ${method}方式拦截成功:`, src || '内联脚本'); updateStatusPanel(); // 创建无害的替代脚本 const dummyScript = document.createElement('script'); dummyScript.textContent = ` // DisableDevtool 已被万能拦截器安全移除 console.log('🛡️ 检测到反调试脚本,已安全拦截'); // 提供兼容性支持,防止页面报错 window.DisableDevtool = function() { return { success: false, reason: 'intercepted by universal blocker' }; }; `; return dummyScript; } return null; } // 劫持各种脚本加载方式 const originalAppendChild = Element.prototype.appendChild; Element.prototype.appendChild = function(child) { if (child && child.tagName === 'SCRIPT') { const replacement = interceptScript(child, 'appendChild'); if (replacement) { return originalAppendChild.call(this, replacement); } } return originalAppendChild.call(this, child); }; const originalInsertBefore = Element.prototype.insertBefore; Element.prototype.insertBefore = function(newNode, referenceNode) { if (newNode && newNode.tagName === 'SCRIPT') { const replacement = interceptScript(newNode, 'insertBefore'); if (replacement) { return originalInsertBefore.call(this, replacement, referenceNode); } } return originalInsertBefore.call(this, newNode, referenceNode); }; const originalCreateElement = Document.prototype.createElement; Document.prototype.createElement = function(tagName) { const element = originalCreateElement.call(this, tagName); if (tagName && tagName.toLowerCase() === 'script') { let realSrc = ''; Object.defineProperty(element, 'src', { get: function() { return realSrc; }, set: function(value) { if (value && isTargetScript(value)) { interceptCount++; console.log(`🛡️ [万能拦截器] createElement拦截:`, value); updateStatusPanel(); return; // 阻止设置src } realSrc = value; element.setAttribute('src', value); } }); // 劫持textContent设置(拦截内联脚本) const originalTextContentSetter = Object.getOwnPropertyDescriptor(Node.prototype, 'textContent').set; Object.defineProperty(element, 'textContent', { get: function() { return this._textContent || ''; }, set: function(value) { if (value && isTargetScript('', value)) { interceptCount++; console.log('🛡️ [万能拦截器] 内联脚本拦截成功'); updateStatusPanel(); this._textContent = '// 内联反调试脚本已被拦截'; return; } this._textContent = value; originalTextContentSetter.call(this, value); } }); } return element; }; // 全局保护 Object.defineProperty(window, 'DisableDevtool', { get: function() { console.log('🛡️ [万能拦截器] DisableDevtool对象访问被拦截'); return function() { return { success: false, reason: 'blocked by universal interceptor' }; }; }, set: function() { console.log('🛡️ [万能拦截器] 禁止设置DisableDevtool'); } }); // 初始化 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', createStatusPanel); } else { setTimeout(createStatusPanel, 100); } // 检查已存在脚本 setTimeout(() => { document.querySelectorAll('script').forEach(script => { const src = script.src; const content = script.textContent || script.innerHTML; if (isTargetScript(src, content)) { console.log('🛡️ [万能拦截器] 发现并移除已存在脚本:', src || '内联脚本'); if (script.parentNode) { script.parentNode.removeChild(script); interceptCount++; updateStatusPanel(); } } }); }, 500); console.log('🛡️ DisableDevtool万能拦截器已启动 - 适配全网站'); })();