您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
阻止大多数 JavaScript 混淆器实现的反调试,并阻止控制台日志被自动清除。修复了控制台标签丢失的问题。
当前为
// ==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); })();