您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Debug js using monkey patch
// ==UserScript== // @name MonkeyDebugger // @namespace https://github.com/JiyuShao/greasyfork-scripts // @version 2024-07-18 // @description Debug js using monkey patch // @author Jiyu Shao <[email protected]> // @license MIT // @match *://*/* // @run-at document-start // @grant unsafeWindow // @grant GM_registerMenuCommand // @grant GM_unregisterMenuCommand // @grant GM_setValue // @grant GM_getValue // @grant GM_addValueChangeListener // @require https://update.gf.qytechs.cn/scripts/496315/1392531/QuickMenu.js // ==/UserScript== /* eslint-disable no-eval */ (function () { 'use strict'; // 定义通用的补丁代码给 new Function 与 eval 使用 const patchCode = ` debugger; `; // 保存原始的 Function 构造器 const originalFunction = unsafeWindow.Function.prototype.constructor; const addFnPatchCode = function (fn) { const finalFn = function (...args) { if (!args.length) return fn.apply(this, args); args[args.length - 1] = `${patchCode}; ${args[args.length - 1]}`; return fn.apply(this, args); }; finalFn.prototype = originalFunction.prototype; Object.defineProperty(finalFn.prototype, 'constructor', { value: finalFn, writable: true, configurable: true, }); return finalFn; }; const removeFnDebugger = function () { const finalFn = function (...args) { if (!args.length) return originalFunction.apply(this, args); args[args.length - 1] = args[args.length - 1].replace(/debugger/g, ''); return originalFunction.apply(this, args); }; finalFn.prototype = originalFunction.prototype; Object.defineProperty(finalFn.prototype, 'constructor', { value: finalFn, writable: true, configurable: true, }); return finalFn; }; QuickMenu.add({ name: '开启 Function 调试', type: 'toggle', shouldInitRun: true, shouldAddMenu: () => { return unsafeWindow === unsafeWindow.top; }, callback: (value) => { if (value === 'on') { // 替换全局的 Function constructor unsafeWindow.Function = addFnPatchCode(); } else if (value === 'off') { // 替换全局的 Function constructor unsafeWindow.Function = removeFnDebugger(); } }, }); // 保存原始的 eval 函数 const originalEval = unsafeWindow.eval; const addEvalPatchCode = function () { return function (...args) { if (!args.length) return originalEval.apply(this, args); args[0] = `${patchCode}; ${args[0]}`; return originalEval.apply(this, args); }; }; const removeEvalDebugger = function () { return function (...args) { if (!args.length) return originalEval.apply(this, args); args[0] = args[0].replace(/debugger/g, ''); return originalEval.apply(this, args); }; }; QuickMenu.add({ name: '开启 eval 调试', type: 'toggle', shouldInitRun: true, shouldAddMenu: () => { return unsafeWindow === unsafeWindow.top; }, callback: (value) => { if (value === 'on') { // 替换全局的 eval 函数 unsafeWindow.eval = addEvalPatchCode(); } else if (value === 'off') { unsafeWindow.eval = removeEvalDebugger(); } }, }); const originalDefineProperty = unsafeWindow.Object.defineProperty; // 覆盖 `Error` 对象的 `message` 属性的 getter const removeErrorMessageGetter = () => { return function (obj, prop, descriptor) { if (obj instanceof Error && prop === 'message') { delete descriptor.get; delete descriptor.set; } return originalDefineProperty.call(Object, obj, prop, descriptor); }; }; // https://github.com/fz6m/console-ban/tree/master QuickMenu.add({ name: '解除 console-ban 限制', type: 'toggle', shouldInitRun: true, shouldAddMenu: () => { return unsafeWindow === unsafeWindow.top; }, callback: (value) => { if (value === 'on') { unsafeWindow.Object.defineProperty = removeErrorMessageGetter(); } else if (value === 'off') { unsafeWindow.Object.defineProperty = originalDefineProperty; } }, }); const originalFetch = unsafeWindow.fetch; QuickMenu.add({ name: 'Fetch with credentials', type: 'toggle', shouldInitRun: true, shouldAddMenu: () => { return true; }, callback: (value) => { if (value === 'on') { unsafeWindow.fetch = function (input, init) { init = init || {}; init.credentials = 'include'; return originalFetch(input, init); }; } else if (value === 'off') { unsafeWindow.fetch = originalFetch; } }, }); QuickMenu.add({ name: '清空菜单缓存', type: 'button', shouldInitRun: false, shouldAddMenu: () => { return unsafeWindow === unsafeWindow.top; }, callback: () => { QuickMenu.clearStore(); }, }); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址