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.

Version au 07/10/2024. Voir la dernière version.

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==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);

    })();