// ==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.0 // @description Stops most anti-debugging implementations by JavaScript obfuscators and stops the console logs from being automatically cleared. // @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. // @description:zh-CN 阻止大多数 JavaScript 混淆器实现的反调试,并阻止控制台日志被自动清除。 // @author Yuusei // @match *://*/* // @grant unsafeWindow // @grant GM_setValue // @grant GM_getValue // @run-at document-start // @license GPL-3.0-only // @downloadURL none // ==/UserScript== (function() { 'use strict'; const config = { excludedDomains: ['vidstream.pro', 'mcloud.to'], debugKeywords: ['debugger', 'debug', 'debugging', 'breakpoint'], consoleProps: ['log', 'warn', 'error', 'info', 'debug', 'assert', 'dir', 'dirxml', 'trace', 'group', 'groupCollapsed', 'groupEnd', 'time', 'timeEnd', 'profile', 'profileEnd', 'count'], enabled: true, // Can be toggled at runtime }; // Load user settings const loadSettings = () => { config.enabled = GM_getValue('antiAntiDebuggerEnabled', true); config.excludedDomains = GM_getValue('excludedDomains', config.excludedDomains); }; loadSettings(); const isExcludedDomain = () => config.excludedDomains.some(domain => new RegExp(`(^|\.)${domain.replace(/\./g, '\\.')}$`, 'i').test(location.hostname) ); if (isExcludedDomain()) return; 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) { console.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 originalConsole = { ...console }; const consoleProxy = new Proxy(console, { get: (target, prop) => { if (config.consoleProps.includes(prop) && typeof target[prop] === 'function') { return new Proxy(target[prop], { apply: (targetFunc, thisArg, args) => { if (!config.enabled) return Reflect.apply(targetFunc, thisArg, args); args = args.map(modifyFunction); return Reflect.apply(targetFunc, thisArg, args); } }); } return Reflect.get(target, prop); }, set: () => false // Prevent overwriting console properties }); Object.defineProperty(unsafeWindow, 'console', { get: () => consoleProxy, set: () => false, configurable: false }); }; const antiAntiDebugger = () => { const proxyHandler = { apply: (target, thisArg, args) => { if (!config.enabled) return Reflect.apply(target, thisArg, args); args = args.map(modifyFunction); return Reflect.apply(target, thisArg, args); }, construct: (target, args) => { if (!config.enabled) return Reflect.construct(target, args); args = args.map(modifyFunction); return Reflect.construct(target, args); } }; Function.prototype.constructor = new Proxy(Function.prototype.constructor, proxyHandler); // Protect eval and Function constructor unsafeWindow.eval = new Proxy(unsafeWindow.eval, proxyHandler); unsafeWindow.Function = new Proxy(unsafeWindow.Function, proxyHandler); }; const preventDebugging = () => { const noop = () => {}; const protectedProps = [...config.debugKeywords, 'pause', 'alert', 'confirm', 'prompt']; protectedProps.forEach(prop => { Object.defineProperty(unsafeWindow, prop, { get: () => config.enabled ? noop : unsafeWindow[prop], set: () => {}, configurable: false }); }); // Override common debugging-related Date methods 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 (config.enabled && new Error().stack.includes('debugger')) { return 0; // Return a fake timestamp } return Reflect.apply(target, thisArg, args); } }); return date; } }); }; const setupToggleShortcut = () => { document.addEventListener('keydown', (e) => { if (e.ctrlKey && e.shiftKey && e.key === 'D') { config.enabled = !config.enabled; GM_setValue('antiAntiDebuggerEnabled', config.enabled); console.log(`Anti Anti-debugger ${config.enabled ? 'enabled' : 'disabled'}`); } }); }; wrapConsole(); antiAntiDebugger(); preventDebugging(); setupToggleShortcut(); console.log('Anti Anti-debugger is active'); })();