Anti Anti-debugger

Advanced protection against anti-debugging with improved performance and features. Attempts to fix video playback issues.

目前為 2024-10-08 提交的版本,檢視 最新版本

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

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

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==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.4
// @description  Advanced protection against anti-debugging with improved performance and features. Attempts to fix video playback issues.
// @description:vi Bảo vệ nâng cao chống anti-debugging với hiệu suất và tính năng được cải thiện. Cố gắng sửa lỗi phát lại video.
// @description:zh-CN 高级反反调试保护,具有改进的性能和功能。 尝试修复视频播放问题。
// @author       Yuusei
// @match        *://*/*
// @grant        unsafeWindow
// @run-at       document-start
// @license      GPL-3.0-only
// ==/UserScript==

(function() {
    'use strict';

    const config = {
        debugKeywords: new Set(['debugger', 'debug', 'debugging', 'breakpoint']),
        consoleProps: ['log', 'warn', 'error', 'info', 'debug', 'assert', 'dir', 'dirxml', 'trace', 'group', 'groupCollapsed', 'groupEnd', 'time', 'timeEnd', 'profile', 'profileEnd', 'count'],
        maxLogHistory: 100,
        // Add a whitelist for sites where debugging should be allowed
        whitelist: new Set([]), // Example: ['example.com', 'another-site.net']
    };

    const originalConsole = Object.fromEntries(
        Object.entries(console).map(([key, value]) => [key, value.bind(console)])
    );

    let logHistory = [];

    const safeEval = (code, context = {}) => {
        try {
            return new Function('context', `with(context) { return (${code}) }`)(context);
        } catch (error) {
            originalConsole.error('Failed to evaluate code:', error, code);
            return null;
        }
    };

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

        const funcStr = func.toString();
        if ([...config.debugKeywords].some(keyword => funcStr.includes(keyword))) {
            const modifiedStr = funcStr.replace(
                new RegExp(`\\b(${[...config.debugKeywords].join('|')})\\b`, 'g'),
                '/* removed */'
            );
            try {
                return safeEval(`(${modifiedStr})`);
            } catch (e) {
                originalConsole.error("Error modifying function:", e);
                return func; // Return original function if modification fails
            }
        }
        return func;
    };



    const wrapConsole = () => {
        config.consoleProps.forEach(prop => {
            console[prop] = (...args) => {
                originalConsole[prop](...args);
                const formattedArgs = args.map(formatLogArgument);
                const logMessage = `[${prop.toUpperCase()}] ${formattedArgs.join(' ')}`;
                logHistory.push(logMessage);
                if (logHistory.length > config.maxLogHistory) logHistory.shift();
            };
        });
    };


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

        Object.defineProperties(Function.prototype, {
            constructor: {
                value: new Proxy(Function.prototype.constructor, proxyHandler),
                writable: false,
                configurable: false,
            }
        });

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


    const preventDebugging = () => {
          // Check if the current site is in the whitelist
        if (config.whitelist.some(site => window.location.host.includes(site))) {
            return; // Skip disabling debugging functions
        }

        const noop = () => {};
        ['alert', 'confirm', 'prompt'].forEach(prop => {
            if (prop in unsafeWindow) {
                try { // Try/catch for robustness
                     Object.defineProperty(unsafeWindow, prop, {
                        value: noop,
                        writable: false,
                        configurable: false
                    });
                } catch (e) {
                    originalConsole.error("Error overriding ", prop, ":", e);
                }
            }
        });
       
        // Attempt to restore video playback by re-enabling potentially blocked APIs
        try {
            Object.defineProperty(HTMLMediaElement.prototype, 'play', {
                value: HTMLMediaElement.prototype.play,
                writable: true,
                configurable: true
            });
        } catch (error) {
            originalConsole.error("Error restoring HTMLMediaElement.play:", error);
        }
    };

    const formatLogArgument = (arg) => {
        if (arg === null) return 'null';
        if (arg === undefined) return 'undefined';
        if (typeof arg === 'object') {
            try {
                return JSON.stringify(arg, (key, value) => 
                    typeof value === 'function' ? value.toString() : value, 2);
            } catch (e) {
                return '[Circular]';
            }
        }
        return String(arg);
    };

    const init = () => {
        wrapConsole();

         // Check for whitelist before applying anti-debugging
        if (!config.whitelist.some(site => window.location.host.includes(site))) {
            antiAntiDebugger();
        }
        preventDebugging();
        console.log('%cAnti Anti-debugger is active', 'color: #00ff00; font-weight: bold;');
    };

    init();
})();