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.

Verze ze dne 07. 10. 2024. Zobrazit nejnovější verzi.

K instalaci tototo skriptu si budete muset nainstalovat rozšíření jako Tampermonkey, Greasemonkey nebo Violentmonkey.

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

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Violentmonkey.

K instalaci tohoto skriptu si budete muset nainstalovat rozšíření jako Tampermonkey nebo Userscripts.

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

K instalaci tohoto skriptu si budete muset nainstalovat manažer uživatelských skriptů.

(Už mám manažer uživatelských skriptů, nechte mě ho nainstalovat!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(Už mám manažer uživatelských stylů, nechte mě ho nainstalovat!)

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

    })();