您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
绕过网站的反开发者工具限制,启用完整的开发者访问权限
- // ==UserScript==
- // @name DevTools Bypass
- // @name:vi Bỏ Qua Chặn DevTools
- // @name:zh-CN 开发工具限制绕过
- // @name:en DevTools Bypass
- // @namespace https://gf.qytechs.cn/vi/users/1195312-renji-yuusei
- // @version 4.0.0
- // @description Bypass website anti-DevTools restrictions and enable full developer access
- // @description:vi Vô hiệu hóa các biện pháp chặn DevTools của website và cho phép truy cập đầy đủ
- // @description:zh-CN 绕过网站的反开发者工具限制,启用完整的开发者访问权限
- // @description:en Bypass website anti-DevTools restrictions and enable full developer access
- // @author Yuusei
- // @match *://*/*
- // @grant unsafeWindow
- // @run-at document-start
- // @license GPL-3.0-only
- // ==/UserScript==
- (() => {
- "use strict";
- // Configuration
- const CONFIG = {
- // Enhanced regex to detect and neutralize anti-DevTools code
- antiDevToolsRegex: new RegExp(
- [
- // Debugger statements - remove completely
- /(?:^|[;\s{(,])\s*debugger\s*(?:[;\s}),]|$)/.source,
- // Function constructor with debugger
- /(?:new\s+)?Function\s*\(\s*['"`][^'"`]*debugger[^'"`]*['"`]\s*\)/
- .source,
- // Timer-based debugger injections
- /(?:setTimeout|setInterval)\s*\(\s*(?:function[^{]*\{[^}]*debugger[^}]*\}|['"`][^'"`]*debugger[^'"`]*['"`])\s*[,)]/
- .source,
- // eval with debugger
- /eval\s*\(\s*['"`][^'"`]*debugger[^'"`]*['"`]\s*\)/.source,
- // Console detection tricks
- /console\s*\[\s*['"`](?:log|warn|error|info|debug|clear|table|dir|group|time)['"`]\s*\]\s*\.\s*toString/
- .source,
- /console\.(?:log|warn|error|info|debug|trace|clear|table|dir|group|time)\s*\.\s*toString\s*\(\s*\)/
- .source,
- // DevTools size detection
- /(?:window\.(?:outer|inner)(?:Width|Height)|screen\.(?:width|height))\s*[-+*\/]\s*(?:window\.(?:outer|inner)(?:Width|Height)|screen\.(?:width|height))\s*[<>=!]+\s*\d+/
- .source,
- // Performance timing detection
- /(?:performance\.now|Date\.now)\s*\(\s*\)\s*[-+]\s*(?:performance\.now|Date\.now)\s*\(\s*\)\s*[><=!]+\s*\d+/
- .source,
- // Known anti-DevTools libraries
- /(?:FuckDevTools|devtools-detector|disable-devtool|console-ban|anti-debug|devtools-detect|fuck-debugger)/
- .source,
- // DevTools event listeners
- /(?:addEventListener|on)\s*\(\s*['"`](?:keydown|keyup|keypress|contextmenu|selectstart|copy|cut|paste|dragstart)['"`][^)]*(?:F12|preventDefault|stopPropagation)/
- .source,
- // Console override attempts
- /console\s*=\s*(?:\{\}|null|undefined|false)/.source,
- /window\.console\s*=/.source,
- // DevTools detection via exceptions
- /try\s*\{[^}]*(?:debugger|console)[^}]*\}\s*catch/.source,
- // Stack trace analysis for DevTools detection
- /(?:Error|TypeError|ReferenceError)\(\)\.stack\.(?:split|match|replace|indexOf|includes|search)/
- .source,
- // Arguments.callee detection (used in some anti-debug)
- /arguments\.callee/.source,
- // toString override for detection
- /toString\s*=\s*function[^{]*\{[^}]*(?:devtools|debug|console)/.source,
- ].join("|"),
- "gim"
- ),
- protection: {
- neutralizeDebugger: true,
- enableDevToolsKeys: true,
- enableRightClick: true,
- enableTextSelection: true,
- enableCopyPaste: true,
- preventAntiDebugTimers: true,
- restoreConsole: true,
- preventKeyBlocking: true,
- },
- logging: {
- enabled: true,
- prefix: "[DevTools Bypass]",
- verbose: false,
- },
- };
- // Logger
- class Logger {
- static #logHistory = new Map();
- static #maxLogsPerType = 5;
- static #canLog(type, message) {
- const key = `${type}:${message}`;
- const count = this.#logHistory.get(key) || 0;
- if (count >= this.#maxLogsPerType) return false;
- this.#logHistory.set(key, count + 1);
- return true;
- }
- static info(message, ...args) {
- if (CONFIG.logging.enabled && this.#canLog("info", message)) {
- console.info(CONFIG.logging.prefix, message, ...args);
- }
- }
- static warn(message, ...args) {
- if (CONFIG.logging.enabled && this.#canLog("warn", message)) {
- console.warn(CONFIG.logging.prefix, message, ...args);
- }
- }
- static debug(message, ...args) {
- if (
- CONFIG.logging.enabled &&
- CONFIG.logging.verbose &&
- this.#canLog("debug", message)
- ) {
- console.debug(CONFIG.logging.prefix, message, ...args);
- }
- }
- }
- // Store original functions before they get overridden
- const ORIGINAL = {
- // Core functions
- Function: window.Function,
- eval: window.eval,
- setTimeout: window.setTimeout,
- setInterval: window.setInterval,
- clearTimeout: window.clearTimeout,
- clearInterval: window.clearInterval,
- // Timing
- Date: window.Date,
- now: Date.now,
- performance: window.performance?.now?.bind(window.performance),
- // DOM
- addEventListener: window.addEventListener,
- removeEventListener: window.removeEventListener,
- createElement: document.createElement,
- // Object methods
- defineProperty: Object.defineProperty,
- getOwnPropertyDescriptor: Object.getOwnPropertyDescriptor,
- keys: Object.keys,
- // Console (store before potential override)
- console: {},
- };
- // Backup console methods
- [
- "log",
- "warn",
- "error",
- "info",
- "debug",
- "trace",
- "dir",
- "table",
- "group",
- "groupEnd",
- "clear",
- "time",
- "timeEnd",
- ].forEach((method) => {
- if (console[method]) {
- ORIGINAL.console[method] = console[method].bind(console);
- }
- });
- // Code Neutralizer - Cleans anti-DevTools code
- class CodeNeutralizer {
- static neutralize(code) {
- if (typeof code !== "string" || !code.trim()) {
- return code;
- }
- try {
- let neutralized = code;
- // Replace anti-DevTools patterns
- neutralized = neutralized.replace(
- CONFIG.antiDevToolsRegex,
- (match, ...args) => {
- const replacement = this.#getReplacement(match);
- Logger.debug(
- "Neutralized anti-DevTools code:",
- match.substring(0, 100)
- );
- return replacement;
- }
- );
- // Handle encoded debugger statements
- neutralized = neutralized.replace(
- /\\u0064\\u0065\\u0062\\u0075\\u0067\\u0067\\u0065\\u0072/g,
- ""
- );
- neutralized = neutralized.replace(
- /\u0064\u0065\u0062\u0075\u0067\u0067\u0065\u0072/g,
- ""
- );
- // Remove obfuscated debugger
- neutralized = neutralized.replace(/['"`]debugger['"`]/g, '""');
- neutralized = neutralized.replace(/\bdebugger\b/g, "");
- // Neutralize console blocking
- neutralized = neutralized.replace(
- /console\s*=\s*(?:\{\}|null|undefined|false)/g,
- "console = console"
- );
- neutralized = neutralized.replace(/window\.console\s*=\s*[^;]+/g, "");
- return neutralized;
- } catch (e) {
- Logger.warn("Code neutralization failed:", e.message);
- return code;
- }
- }
- static #getReplacement(match) {
- if (match.includes("debugger")) {
- return "/* debugger statement removed */";
- }
- if (match.includes("console")) {
- return "/* console detection removed */";
- }
- if (match.includes("addEventListener") || match.includes("keydown")) {
- return "/* key blocking removed */";
- }
- if (match.includes("performance") || match.includes("Date.now")) {
- return "/* timing detection removed */";
- }
- return "/* anti-DevTools code removed */";
- }
- }
- // DevTools Protection Bypass
- class DevToolsProtectionBypass {
- static apply() {
- this.#neutralizeFunctionConstructor();
- this.#neutralizeEval();
- this.#neutralizeTimers();
- this.#preventKeyBlocking();
- this.#restoreRightClick();
- this.#restoreTextSelection();
- this.#restoreConsole();
- this.#preventTimingDetection();
- this.#neutralizeDebuggerTricks();
- this.#patchMutationObserver();
- this.#restoreClipboard();
- this.#preventErrorOverrides();
- }
- // Neutralize Function constructor to prevent debugger injection
- static #neutralizeFunctionConstructor() {
- const handler = {
- construct(target, args) {
- if (args[0] && typeof args[0] === "string") {
- args[0] = CodeNeutralizer.neutralize(args[0]);
- }
- return Reflect.construct(target, args);
- },
- apply(target, thisArg, args) {
- if (args[0] && typeof args[0] === "string") {
- args[0] = CodeNeutralizer.neutralize(args[0]);
- }
- return Reflect.apply(target, thisArg, args);
- },
- };
- try {
- window.Function = new Proxy(ORIGINAL.Function, handler);
- if (typeof unsafeWindow !== "undefined") {
- unsafeWindow.Function = window.Function;
- }
- Logger.info("Function constructor protected");
- } catch (e) {
- Logger.warn("Function protection failed:", e.message);
- }
- }
- // Neutralize eval to prevent debugger injection
- static #neutralizeEval() {
- const safeEval = function (code) {
- if (typeof code === "string") {
- code = CodeNeutralizer.neutralize(code);
- }
- return ORIGINAL.eval.call(this, code);
- };
- try {
- Object.defineProperty(window, "eval", {
- value: safeEval,
- writable: false,
- configurable: false,
- });
- if (typeof unsafeWindow !== "undefined") {
- unsafeWindow.eval = safeEval;
- }
- Logger.info("eval function protected");
- } catch (e) {
- Logger.warn("eval protection failed:", e.message);
- }
- }
- // Neutralize timers that might inject debugger
- static #neutralizeTimers() {
- const wrapTimer = (original, name) => {
- return function (handler, delay, ...args) {
- if (typeof handler === "string") {
- handler = CodeNeutralizer.neutralize(handler);
- }
- return original.call(this, handler, delay, ...args);
- };
- };
- window.setTimeout = wrapTimer(ORIGINAL.setTimeout, "setTimeout");
- window.setInterval = wrapTimer(ORIGINAL.setInterval, "setInterval");
- Logger.info("Timer functions protected");
- }
- // Prevent key blocking (F12, Ctrl+Shift+I, etc.)
- static #preventKeyBlocking() {
- const events = ["keydown", "keypress", "keyup"];
- events.forEach((eventType) => {
- // Override addEventListener to prevent key blocking
- const originalAddListener = ORIGINAL.addEventListener;
- document.addEventListener = function (type, listener, options) {
- if (type === eventType && typeof listener === "function") {
- const originalListener = listener;
- listener = function (event) {
- const key = event.key?.toLowerCase();
- const code = event.code?.toLowerCase();
- // Allow DevTools keys
- const isDevToolsKey =
- key === "f12" ||
- (event.ctrlKey &&
- event.shiftKey &&
- ["i", "j", "c"].includes(key)) ||
- (event.ctrlKey && key === "u");
- if (isDevToolsKey) {
- Logger.debug("Allowing DevTools key:", key);
- return; // Don't call the original listener
- }
- return originalListener.call(this, event);
- };
- }
- return originalAddListener.call(this, type, listener, options);
- };
- // Also handle window events
- window.addEventListener = document.addEventListener;
- });
- // Block existing key event listeners by overriding preventDefault
- const originalPreventDefault = Event.prototype.preventDefault;
- Event.prototype.preventDefault = function () {
- const key = this.key?.toLowerCase();
- const isDevToolsKey =
- key === "f12" ||
- (this.ctrlKey && this.shiftKey && ["i", "j", "c"].includes(key)) ||
- (this.ctrlKey && key === "u");
- if (
- isDevToolsKey &&
- (this.type === "keydown" ||
- this.type === "keypress" ||
- this.type === "keyup")
- ) {
- Logger.debug("Prevented preventDefault on DevTools key:", key);
- return; // Don't prevent default for DevTools keys
- }
- return originalPreventDefault.call(this);
- };
- Logger.info("Key blocking prevention enabled");
- }
- // Restore right-click context menu
- static #restoreRightClick() {
- // Override contextmenu event blocking
- const originalAddListener = document.addEventListener;
- document.addEventListener = function (type, listener, options) {
- if (type === "contextmenu") {
- // Replace with a dummy function that doesn't block
- listener = function (e) {
- Logger.debug("Context menu allowed");
- return true;
- };
- }
- return originalAddListener.call(this, type, listener, options);
- };
- // Also handle oncontextmenu attribute
- const observer = new MutationObserver((mutations) => {
- mutations.forEach((mutation) => {
- if (
- mutation.type === "attributes" &&
- mutation.attributeName === "oncontextmenu"
- ) {
- mutation.target.removeAttribute("oncontextmenu");
- Logger.debug("Removed oncontextmenu attribute");
- }
- });
- });
- observer.observe(document.documentElement, {
- attributes: true,
- subtree: true,
- attributeFilter: ["oncontextmenu"],
- });
- Logger.info("Right-click restored");
- }
- // Restore text selection
- static #restoreTextSelection() {
- // Override selectstart event blocking
- const originalAddListener = document.addEventListener;
- const blockedEvents = ["selectstart", "dragstart", "copy", "cut"];
- document.addEventListener = function (type, listener, options) {
- if (blockedEvents.includes(type)) {
- listener = function (e) {
- Logger.debug("Selection/copy event allowed:", type);
- return true;
- };
- }
- return originalAddListener.call(this, type, listener, options);
- };
- // Remove CSS that prevents text selection
- const style = document.createElement("style");
- style.textContent = `
- *, *::before, *::after {
- -webkit-user-select: text !important;
- -moz-user-select: text !important;
- -ms-user-select: text !important;
- user-select: text !important;
- }
- `;
- document.head.appendChild(style);
- Logger.info("Text selection restored");
- }
- // Restore console if it was overridden
- static #restoreConsole() {
- try {
- // Check if console was disabled/overridden
- if (!window.console || typeof window.console.log !== "function") {
- window.console = ORIGINAL.console;
- Logger.info("Console restored");
- }
- // Ensure console methods are working
- Object.keys(ORIGINAL.console).forEach((method) => {
- if (!console[method] || typeof console[method] !== "function") {
- console[method] = ORIGINAL.console[method];
- }
- });
- // Prevent future console overrides
- Object.defineProperty(window, "console", {
- value: window.console,
- writable: false,
- configurable: false,
- });
- } catch (e) {
- Logger.warn("Console restoration failed:", e.message);
- }
- }
- // Prevent timing-based DevTools detection
- static #preventTimingDetection() {
- // Add small random delays to timing functions to break detection
- const addNoise = () => Math.random() * 2;
- try {
- Object.defineProperty(Date, "now", {
- value: () => ORIGINAL.now() + addNoise(),
- writable: false,
- configurable: false,
- });
- if (window.performance?.now) {
- Object.defineProperty(window.performance, "now", {
- value: () => ORIGINAL.performance() + addNoise(),
- writable: false,
- configurable: false,
- });
- }
- Logger.info("Timing detection prevented");
- } catch (e) {
- Logger.warn("Timing protection failed:", e.message);
- }
- }
- // Neutralize debugger tricks
- static #neutralizeDebuggerTricks() {
- // Override toString methods that might be used for detection
- const safeToString = function () {
- return this.name
- ? `function ${this.name}() { [native code] }`
- : "function() { [native code] }";
- };
- try {
- // Protect critical functions from toString inspection
- window.Function.prototype.toString = safeToString;
- window.eval.toString = () => "function eval() { [native code] }";
- Logger.info("Debugger tricks neutralized");
- } catch (e) {
- Logger.warn("Debugger trick neutralization failed:", e.message);
- }
- }
- // Monitor and clean injected scripts
- static #patchMutationObserver() {
- if (!window.MutationObserver) return;
- try {
- new MutationObserver((mutations) => {
- mutations.forEach((mutation) => {
- mutation.addedNodes.forEach((node) => {
- if (node.nodeType === Node.ELEMENT_NODE) {
- // Clean script content
- if (node.tagName === "SCRIPT" && node.textContent) {
- const originalContent = node.textContent;
- const cleanedContent =
- CodeNeutralizer.neutralize(originalContent);
- if (originalContent !== cleanedContent) {
- node.textContent = cleanedContent;
- Logger.debug("Cleaned injected script");
- }
- }
- // Clean event attributes
- if (node.attributes) {
- Array.from(node.attributes).forEach((attr) => {
- if (
- attr.name.startsWith("on") ||
- attr.name === "oncontextmenu"
- ) {
- const cleaned = CodeNeutralizer.neutralize(attr.value);
- if (
- cleaned !== attr.value ||
- attr.name === "oncontextmenu"
- ) {
- node.removeAttribute(attr.name);
- Logger.debug(
- "Removed/cleaned event attribute:",
- attr.name
- );
- }
- }
- });
- }
- }
- });
- });
- }).observe(document.documentElement, {
- childList: true,
- subtree: true,
- attributes: true,
- attributeFilter: [
- "onload",
- "onerror",
- "onclick",
- "oncontextmenu",
- "onkeydown",
- "onkeyup",
- ],
- });
- Logger.info("DOM monitoring active");
- } catch (e) {
- Logger.warn("DOM monitoring failed:", e.message);
- }
- }
- // Restore clipboard functionality
- static #restoreClipboard() {
- const clipboardEvents = ["copy", "cut", "paste"];
- clipboardEvents.forEach((eventType) => {
- document.addEventListener(
- eventType,
- (e) => {
- // Ensure clipboard events are not blocked
- e.stopImmediatePropagation();
- },
- true
- );
- });
- Logger.info("Clipboard functionality restored");
- }
- // Prevent error handling overrides that might block DevTools
- static #preventErrorOverrides() {
- const originalErrorHandler = window.onerror;
- window.addEventListener(
- "error",
- (e) => {
- // Don't let websites block error reporting
- e.stopImmediatePropagation();
- },
- true
- );
- // Prevent overriding of error handlers
- Object.defineProperty(window, "onerror", {
- set: function (handler) {
- Logger.debug("Prevented error handler override");
- },
- get: function () {
- return originalErrorHandler;
- },
- });
- Logger.info("Error override prevention active");
- }
- }
- // Main bypass controller
- class DevToolsBypass {
- static init() {
- try {
- Logger.info("Starting DevTools protection bypass...");
- // Apply all bypasses
- DevToolsProtectionBypass.apply();
- // Clean existing page content
- this.#cleanExistingContent();
- Logger.info("DevTools bypass activated successfully");
- // Show success indicator
- this.#showSuccessIndicator();
- } catch (e) {
- Logger.warn("Bypass initialization failed:", e.message);
- }
- }
- static #cleanExistingContent() {
- try {
- // Clean all existing script tags
- const scripts = document.querySelectorAll("script");
- scripts.forEach((script) => {
- if (script.textContent) {
- const cleaned = CodeNeutralizer.neutralize(script.textContent);
- if (cleaned !== script.textContent) {
- script.textContent = cleaned;
- Logger.debug("Cleaned existing script");
- }
- }
- });
- // Remove problematic event attributes
- const elementsWithEvents = document.querySelectorAll(
- "[oncontextmenu], [onkeydown], [onkeyup], [onselectstart], [ondragstart]"
- );
- elementsWithEvents.forEach((element) => {
- [
- "oncontextmenu",
- "onkeydown",
- "onkeyup",
- "onselectstart",
- "ondragstart",
- ].forEach((attr) => {
- if (element.hasAttribute(attr)) {
- element.removeAttribute(attr);
- Logger.debug("Removed event attribute:", attr);
- }
- });
- });
- } catch (e) {
- Logger.warn("Content cleaning failed:", e.message);
- }
- }
- static #showSuccessIndicator() {
- if (!CONFIG.logging.enabled) return;
- // Create a temporary success indicator
- const indicator = document.createElement("div");
- indicator.style.cssText = `
- position: fixed;
- top: 20px;
- right: 20px;
- background: #4CAF50;
- color: white;
- padding: 10px 20px;
- border-radius: 5px;
- z-index: 999999;
- font-family: Arial, sans-serif;
- font-size: 14px;
- box-shadow: 0 2px 10px rgba(0,0,0,0.3);
- `;
- indicator.textContent = "✓ DevTools Bypass Active";
- document.body?.appendChild(indicator);
- // Remove after 3 seconds
- setTimeout(() => {
- indicator.remove();
- }, 3000);
- }
- }
- // Initialize immediately and on various events
- DevToolsBypass.init();
- // Also initialize when DOM is ready (fallback)
- if (document.readyState === "loading") {
- document.addEventListener("DOMContentLoaded", DevToolsBypass.init);
- }
- // Initialize on window load (another fallback)
- window.addEventListener("load", DevToolsBypass.init);
- })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址