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