Anti Anti-debugger

Stops most anti-debugging implementations by JavaScript obfuscators and stops the console logs from being automatically cleared. Fixed issue with missing console tab.

Versione datata 07/10/2024. Vedi la nuova versione l'ultima versione.

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

You will need to install an extension such as Tampermonkey to install this script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name         Anti Anti-debugger
// @name:vi      Chống Anti-debugger
// @name:zh-CN   反反调试
// @namespace    https://greasyfork.org/vi/users/1195312-renji-yuusei
// @version      1.2
// @description  Stops most anti-debugging implementations by JavaScript obfuscators and stops the console logs from being automatically cleared. Fixed issue with missing console tab.
// @description:vi Ngăn chặn hầu hết các triển khai anti-debugging bằng JavaScript obfuscators và ngăn chặn việc xóa nhật ký console tự động. Đã sửa lỗi mất tab console.
// @description:zh-CN  阻止大多数 JavaScript 混淆器实现的反调试,并阻止控制台日志被自动清除。修复了控制台标签丢失的问题。
// @author       Yuusei
// @match        *://*/*
// @grant        unsafeWindow
// @run-at       document-start
// @license      GPL-3.0-only
// ==/UserScript==

(function() {
    'use strict';

    const config = {
        debugKeywords: ['debugger', 'debug', 'debugging', 'breakpoint'],
        consoleProps: ['log', 'warn', 'error', 'info', 'debug', 'assert', 'dir', 'dirxml', 'trace', 'group', 'groupCollapsed', 'groupEnd', 'time', 'timeEnd', 'profile', 'profileEnd', 'count'],
    };

    const originalConsole = { ...console };
    let isScriptActive = false;

    const safeEval = (code, context = {}) => {
        const safeContext = { ...context, console: { log: () => {} } };
        const safeCode = `
            'use strict';
            const alert = () => {};
            const confirm = () => {};
            const prompt = () => {};
            ${Object.keys(safeContext).map(key => `const ${key} = this.${key};`).join('\n')}
            return (${code});
        `;
        try {
            return new Function(safeCode).call(safeContext);
        } catch (error) {
            originalConsole.warn('Failed to evaluate code:', error);
            return null;
        }
    };

    const modifyFunction = (func) => {
        if (typeof func !== 'function') return func;

        let funcStr = func.toString();
        if (config.debugKeywords.some(keyword => funcStr.includes(keyword))) {
            funcStr = funcStr.replace(new RegExp(`\\b(${config.debugKeywords.join('|')})\\b`, 'g'), '/* removed */');
            return safeEval(funcStr) || func;
        }
        return func;
    };

    const wrapConsole = () => {
        const consoleProxy = new Proxy(originalConsole, {
            get: (target, prop) => {
                if (config.consoleProps.includes(prop) && typeof target[prop] === 'function') {
                    return new Proxy(target[prop], {
                        apply: (targetFunc, thisArg, args) => {
                            args = args.map(modifyFunction);
                            return Reflect.apply(targetFunc, thisArg, args);
                        }
                    });
                }
                return Reflect.get(target, prop);
            }
        });

        Object.defineProperty(unsafeWindow, 'console', {
            value: consoleProxy,
            writable: false,
            configurable: false
        });
    };

    const antiAntiDebugger = () => {
        const proxyHandler = {
            apply: (target, thisArg, args) => {
                args = args.map(modifyFunction);
                return Reflect.apply(target, thisArg, args);
            },
            construct: (target, args) => {
                args = args.map(modifyFunction);
                return Reflect.construct(target, args);
            }
        };

        Function.prototype.constructor = new Proxy(Function.prototype.constructor, proxyHandler);
        
        unsafeWindow.eval = new Proxy(unsafeWindow.eval, proxyHandler);
        unsafeWindow.Function = new Proxy(unsafeWindow.Function, proxyHandler);
    };

    const preventDebugging = () => {
        const noop = () => {};
        const protectedProps = ['pause', 'alert', 'confirm', 'prompt'];
        
        protectedProps.forEach(prop => {
            Object.defineProperty(unsafeWindow, prop, {
                get: () => noop,
                set: () => {},
                configurable: false
            });
        });

        const originalDate = unsafeWindow.Date;
        unsafeWindow.Date = new Proxy(originalDate, {
            construct: (target, args) => {
                const date = new target(...args);
                date.getTime = new Proxy(date.getTime, {
                    apply: (target, thisArg, args) => {
                        if (new Error().stack.includes('debugger')) {
                            return 0; // Return a fake timestamp
                        }
                        return Reflect.apply(target, thisArg, args);
                    }
                });
                return date;
            }
        });
    };

    const init = () => {
        wrapConsole();
        antiAntiDebugger();
        preventDebugging();
        isScriptActive = true;
        originalConsole.log('%cAnti Anti-debugger is active', 'color: #00ff00; font-weight: bold; font-size: 20px;');
    };

    init();

    // Periodically check and reapply if necessary
    setInterval(() => {
        if (!isScriptActive) {
            init();
        }
    }, 1000);

    })();