Leave-debugger

用于破解网页无限debugger,支持多种调试方式拦截

  1. // ==UserScript==
  2. // @name Leave-debugger
  3. // @namespace https://github.com/SherryBX/Leave-debugger
  4. // @version v2.2.0
  5. // @description 用于破解网页无限debugger,支持多种调试方式拦截
  6. // @author Sherry
  7. // @match *://*/*
  8. // @include *://*/*
  9. // @run-at document-start
  10. // @license MIT
  11. // @icon https://mms0.baidu.com/it/u=2886239489,318124131&fm=253&app=138&f=JPEG?w=800&h=800
  12. // ==/UserScript==
  13.  
  14. (function () {
  15. 'use strict';
  16.  
  17. // 配置项
  18. const CONFIG = {
  19. version: 'v2.2.0',
  20. debugMode: false, // 调试模式开关
  21. checkPatterns: ['debugger', 'debug', 'DevTools'], // 检查的关键字模式
  22. };
  23.  
  24. // 统一的日志输出
  25. const Logger = {
  26. styles: {
  27. main: 'color: #43bb88; font-size: 14px; font-weight: bold;',
  28. info: 'color: #666; font-size: 12px;',
  29. hook: 'color: #43bb88;'
  30. },
  31. print(message, style = 'main') {
  32. console.log(`%c ${message}`, this.styles[style]);
  33. },
  34. debug(...args) {
  35. if (CONFIG.debugMode) {
  36. console.log('[Debug]', ...args);
  37. }
  38. }
  39. };
  40.  
  41. // Hook 状态管理
  42. const HookManager = {
  43. notified: new Set(),
  44. markNotified(type) {
  45. if (!this.notified.has(type)) {
  46. this.notified.add(type);
  47. Logger.print(`🎯 Hook ${type} debugger!`, 'hook');
  48. }
  49. }
  50. };
  51.  
  52. // 工具函数
  53. const Utils = {
  54. // 安全地检查函数字符串
  55. safeToString(func) {
  56. try {
  57. const str = Function.prototype.toString.call(func);
  58. return typeof str === 'string' ? str.replace(/\s+/g, '') : '';
  59. } catch (e) {
  60. Logger.debug('toString error:', e);
  61. return '';
  62. }
  63. },
  64. // 检查是否包含调试相关代码
  65. containsDebugger(content) {
  66. if (!content) return false;
  67. return CONFIG.checkPatterns.some(pattern => content.includes(pattern));
  68. },
  69. // 创建空函数
  70. createEmptyFunction() {
  71. return function () { return -1; };
  72. }
  73. };
  74.  
  75. // Hook 实现
  76. const Hooks = {
  77. // Hook Function constructor
  78. hookConstructor() {
  79. const original = Function.prototype.constructor;
  80. Function.prototype.constructor = function (string) {
  81. if (Utils.containsDebugger(string)) {
  82. HookManager.markNotified('constructor');
  83. return Utils.createEmptyFunction();
  84. }
  85. return original.apply(this, arguments);
  86. };
  87. },
  88.  
  89. // Hook setInterval
  90. hookSetInterval() {
  91. const original = window.setInterval;
  92. window.setInterval = function (func, delay) {
  93. if (typeof func === 'function' && Utils.containsDebugger(Utils.safeToString(func))) {
  94. HookManager.markNotified('setInterval');
  95. return Utils.createEmptyFunction();
  96. }
  97. return original.apply(this, arguments);
  98. };
  99. },
  100.  
  101. // Hook setTimeout
  102. hookSetTimeout() {
  103. const original = window.setTimeout;
  104. window.setTimeout = function (func, delay) {
  105. if (typeof func === 'function' && Utils.containsDebugger(Utils.safeToString(func))) {
  106. HookManager.markNotified('setTimeout');
  107. return Utils.createEmptyFunction();
  108. }
  109. return original.apply(this, arguments);
  110. };
  111. },
  112.  
  113. // Hook eval
  114. hookEval() {
  115. const original = window.eval;
  116. window.eval = function (string) {
  117. if (Utils.containsDebugger(string)) {
  118. HookManager.markNotified('eval');
  119. string = string.replace(/debugger\s*;?/g, '');
  120. }
  121. return original.call(this, string);
  122. };
  123. // 保持 toString 的原始行为
  124. Object.defineProperty(window.eval, 'toString', {
  125. value: function() { return original.toString(); },
  126. configurable: false,
  127. writable: false
  128. });
  129. }
  130. };
  131.  
  132. // 错误处理
  133. const ErrorHandler = {
  134. setup() {
  135. window.addEventListener('error', function (event) {
  136. if (event.error?.message?.includes('Cannot read properties') ||
  137. event.error?.message?.includes('Cannot set property')) {
  138. event.preventDefault();
  139. Logger.debug('Prevented error:', event.error.message);
  140. return false;
  141. }
  142. }, true);
  143. }
  144. };
  145.  
  146. // 初始化
  147. function initialize() {
  148. Logger.print('Leave-debugger 已启动 🚀');
  149. Logger.print(`Version: ${CONFIG.version} 📦`, 'info');
  150. Logger.print('Author: Sherry 🛡️', 'info');
  151.  
  152. // 应用所有 hooks
  153. Object.values(Hooks).forEach(hook => {
  154. try {
  155. hook();
  156. } catch (e) {
  157. Logger.debug('Hook error:', e);
  158. }
  159. });
  160.  
  161. // 设置错误处理
  162. ErrorHandler.setup();
  163. }
  164.  
  165. // 启动脚本
  166. initialize();
  167. })();