Bypass DevTools Detection

Prevent websites from detecting DevTools (Inspect Element) is open

Você precisará instalar uma extensão como Tampermonkey, Greasemonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Violentmonkey para instalar este script.

Você precisará instalar uma extensão como Tampermonkey ou Userscripts para instalar este script.

Você precisará instalar uma extensão como o Tampermonkey para instalar este script.

Você precisará instalar um gerenciador de scripts de usuário para instalar este script.

(Eu já tenho um gerenciador de scripts de usuário, me deixe instalá-lo!)

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar uma extensão como o Stylus para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

Você precisará instalar um gerenciador de estilos de usuário para instalar este estilo.

(Eu já possuo um gerenciador de estilos de usuário, me deixar fazer a instalação!)

// ==UserScript==
// @name         Bypass DevTools Detection
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Prevent websites from detecting DevTools (Inspect Element) is open
// @author       Serial Desegnation J
// @match        *://*/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // --- Override debugger to noop ---
    window.debugger = function() {};

    // Spoof Function.prototype.constructor to strip debugger statements from strings
    const originalConstructor = Function.prototype.constructor;
    Function.prototype.constructor = new Proxy(originalConstructor, {
        apply(target, thisArg, args) {
            if (args[0] && typeof args[0] === 'string' && args[0].includes('debugger')) {
                args[0] = args[0].replace(/debugger/g, '');
            }
            return Reflect.apply(target, thisArg, args);
        }
    });

    // Spoof Function.prototype.toString to hide overrides (especially debugger function)
    const originalToString = Function.prototype.toString;
    Function.prototype.toString = new Proxy(originalToString, {
        apply(target, thisArg, args) {
            if (thisArg === window.debugger) {
                return 'function debugger() { [native code] }';
            }
            return Reflect.apply(target, thisArg, args);
        }
    });

    // Override eval to strip debugger statements from any eval'd code
    const originalEval = window.eval;
    window.eval = function(code) {
        if (typeof code === 'string') {
            code = code.replace(/debugger;?/g, '');
        }
        return originalEval(code);
    };

    // Override console methods to disable traps and weird behaviors
    ['log', 'debug', 'error', 'info', 'warn'].forEach(method => {
        const originalMethod = console[method];
        console[method] = function(...args) {
            // Skip logging if args include certain trap images or weird data (optional)
            for (const arg of args) {
                if (arg instanceof Image) return;
            }
            return originalMethod.apply(console, args);
        };
    });

    // Block console.clear to prevent wiping logs
    console.clear = function () {
        console.log('[Tampermonkey] Blocked console.clear()');
    };

    // Spoof window.outerWidth and outerHeight to match inner dimensions (for devtools detection)
    function spoofWindowSize() {
        Object.defineProperty(window, 'outerWidth', {
            get: () => window.innerWidth,
            configurable: true
        });
        Object.defineProperty(window, 'outerHeight', {
            get: () => window.innerHeight,
            configurable: true
        });
    }
    spoofWindowSize();
    // Repeat periodically to counter site attempts to redefine
    setInterval(spoofWindowSize, 1000);

    // Override requestAnimationFrame to fudge timestamps (blocks timing detection)
    const originalRAF = window.requestAnimationFrame;
    window.requestAnimationFrame = function(callback) {
        return originalRAF(function(time) {
            callback(time + 1000);
        });
    };

    // Prevent key combos that open DevTools or View Source
    document.addEventListener('keydown', function(e) {
        if (
            e.key === 'F12' ||
            (e.ctrlKey && e.shiftKey && ['I', 'J', 'C'].includes(e.key.toUpperCase())) ||
            (e.ctrlKey && e.key.toUpperCase() === 'U')
        ) {
            e.stopImmediatePropagation();
            e.preventDefault();
        }
    }, true);

    // Prevent detection via image get traps (used in object inspection)
    const imageProto = Object.getPrototypeOf(new Image());
    if (imageProto) {
        Object.defineProperty(imageProto, 'id', {
            get: function() {
                return null;
            },
            configurable: true
        });
    }

    // Spoof performance navigation type to hide reload detection
    try {
        if (performance.getEntriesByType("navigation")[0].type === "reload") {
            Object.defineProperty(performance, 'getEntriesByType', {
                value: () => [{ type: "navigate" }],
                configurable: true
            });
        }
    } catch (e) {}

    // Spoof navigator.plugins and navigator.languages to look real
    Object.defineProperty(navigator, 'plugins', {
        get: () => [1, 2, 3],
        configurable: true
    });
    Object.defineProperty(navigator, 'languages', {
        get: () => ['en-US', 'en'],
        configurable: true
    });

    // Spoof HTMLElement.prototype.toString to prevent element inspection detection
    const originalGetOwnPropDesc = Object.getOwnPropertyDescriptor;
    Object.getOwnPropertyDescriptor = new Proxy(originalGetOwnPropDesc, {
        apply(target, thisArg, args) {
            if (args[0] === HTMLElement.prototype && args[1] === 'toString') {
                return {
                    configurable: true,
                    enumerable: false,
                    value: () => '[object HTMLElement]'
                };
            }
            return Reflect.apply(target, thisArg, args);
        }
    });

    // Debugging confirmation message
    console.log('[Tampermonkey] DevTools detection blocked (enhanced).');

})();