允许使用 F12

令某些打开 Developer Tools 的网站就弹 debugger 的功能失效。

目前为 2022-08-14 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Allow F12
  3. // @name:zh-CN 允许使用 F12
  4. // @namespace http://lab.wsl.moe/
  5. // @match http://*/*
  6. // @match https://*/*
  7. // @license MIT
  8. // @version 0.3.2
  9. // @description Allow to open Dev Tools on some website.
  10. // @description:zh-CN 令某些打开 Developer Tools 的网站就弹 debugger 的功能失效。
  11. // @author MisakaMikoto
  12. // @run-at document-start
  13. // @grant none
  14. // ==/UserScript==
  15.  
  16. (function() {
  17.  
  18. const origSetInterval = window.setInterval;
  19. const toString = () => {
  20. return 'function constructor() {\n [native code]\n}';
  21. };
  22. toString.toString = toString;
  23. if (toString.toSource) {
  24. toString.toSource = toString;
  25. }
  26.  
  27. window.setInterval = (func, time) => {
  28. if (func.toString().indexOf('debugger') !== -1) {
  29. console.warn('Rejected to register a interval contains debugger statement.');
  30. return;
  31. }
  32. origSetInterval(func, time);
  33. };
  34. window.setInterval.toString = toString;
  35.  
  36. const origFunction = Function;
  37. class FakeFunction extends origFunction {
  38. constructor(func) {
  39. if (func.indexOf('debugger') !== -1) {
  40. //console.warn('Rejected to generate a function contains debugger statement.');
  41. func = '';
  42. }
  43. super(func);
  44. }
  45. }
  46. FakeFunction.constructor = (func) => {
  47. return new FakeFunction(func);
  48. };
  49. origFunction.prototype.constructor = FakeFunction.constructor;
  50. window.Function = FakeFunction;
  51. Function.constructor.toString = toString;
  52. if (Function.constructor.toSource) {
  53. Function.constructor.toSource = toString;
  54. }
  55.  
  56. if (localStorage.__disableEvalHook__ == null || localStorage.__disableEvalHook__ === '') {
  57. localStorage.__disableEvalHook__ = 'true';
  58. }
  59. if (Object && Object.defineProperty) {
  60. const originalConsole = {};
  61. const noWriteAbleConsole = {};
  62. for (let k in console) {
  63. let func = console[k];
  64. originalConsole[k] = func;
  65. }
  66.  
  67. for (let k in originalConsole) {
  68. const origFunc = originalConsole[k];
  69. let func = origFunc;
  70. switch (k) {
  71. case 'clear':
  72. func = () => {};
  73. break;
  74. case 'log':
  75. case 'info':
  76. case 'warn':
  77. case 'error':
  78. func = (...args) => {
  79. const nativeToString = ([]).toString;
  80. for (let i of args) {
  81. const rawToString = i.toString;
  82. rawToString.toString = nativeToString;
  83. const targetSourceCode = rawToString.toString();
  84. if (targetSourceCode.startsWith('function') && targetSourceCode.indexOf('[native code]') === -1) {
  85. console.warn('Some script mabe trying to disable F12 console.');
  86. i.toString = nativeToString;
  87. }
  88. const result = origFunc.apply(this, args);
  89. console.trace();
  90. return result;
  91. }
  92. };
  93. break;
  94. }
  95. Object.defineProperty(noWriteAbleConsole, k, {
  96. get: () => { return func },
  97. set: (val) => {
  98. originalConsole.warn('Some script trying to change console function:');
  99. originalConsole.warn(val);
  100. return val;
  101. }
  102. });
  103. }
  104. Object.defineProperty(window, 'console', {
  105. get: () => { return noWriteAbleConsole },
  106. set: (val) => {
  107. originalConsole.warn('Some script trying to change console object:');
  108. originalConsole.warn(val);
  109. return val;
  110. }
  111. });
  112. const realWindowEval = window.eval;
  113. if (localStorage.__disableEvalHook__ !== 'true') {
  114. window.eval = (func) => {
  115. if (func.indexOf('debugger') !== -1) {
  116. func = func.replace(/debugger?/, 'throw null');
  117. }
  118. console.log(func);
  119. const localEval = realWindowEval;
  120. const result = localEval.apply(this, [func]);
  121. return result;
  122. };
  123. }
  124. const origDefineProperty = Object.defineProperty;
  125. Object.defineProperty = (obj, k, opt) => {
  126. if (obj === window && k === 'console') {
  127. originalConsole.warn('Some script trying to change console object:');
  128. originalConsole.warn(opt);
  129. return;
  130. }
  131. const result = origDefineProperty(obj, k, opt);
  132. return result;
  133. };
  134. const origDefineProperties = Object.defineProperties;
  135. Object.defineProperties = (obj, opt) => {
  136. if (obj === window) {
  137. if (opt.console != null) {
  138. delete opt['console'];
  139. originalConsole.warn('Some script trying to change console object:');
  140. originalConsole.warn(opt);
  141. }
  142. }
  143. const result = origDefineProperties(obj, opt);
  144. return result;
  145. };
  146. } else {
  147. const originalConsole = {};
  148. for (let k in console) {
  149. let func = console[k];
  150. if (k === 'clear') {
  151. func = () => {};
  152. }
  153. originalConsole[k] = func;
  154. }
  155.  
  156. const setConsoleFunc = () => {
  157. for (let k in originalConsole) {
  158. console[k] = originalConsole[k];
  159. }
  160. }
  161.  
  162. setInterval(() => {
  163. setConsoleFunc();
  164. }, 1000);
  165. }
  166. })();