// ==UserScript==
// @name Anti Anti-debugger
// @name:vi Chống Anti-debugger
// @name:zh-CN 反反调试
// @namespace https://gf.qytechs.cn/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);
})();