允许使用 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.1
  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. window.Function = FakeFunction;
  50. Function.constructor.toString = toString;
  51. if (Function.constructor.toSource) {
  52. Function.constructor.toSource = toString;
  53. }
  54.  
  55. if (localStorage.__disableEvalHook__ == null || localStorage.__disableEvalHook__ === '') {
  56. localStorage.__disableEvalHook__ = 'true';
  57. }
  58. if (Object && Object.defineProperty) {
  59. const originalConsole = {};
  60. const noWriteAbleConsole = {};
  61. for (let k in console) {
  62. let func = console[k];
  63. originalConsole[k] = func;
  64. }
  65.  
  66. for (let k in originalConsole) {
  67. const origFunc = originalConsole[k];
  68. let func = origFunc;
  69. switch (k) {
  70. case 'clear':
  71. func = () => {};
  72. break;
  73. case 'log':
  74. case 'info':
  75. case 'warn':
  76. case 'error':
  77. func = (...args) => {
  78. const nativeToString = ([]).toString;
  79. for (let i of args) {
  80. const rawToString = i.toString;
  81. rawToString.toString = nativeToString;
  82. const targetSourceCode = rawToString.toString();
  83. if (targetSourceCode.startsWith('function') && targetSourceCode.indexOf('[native code]') === -1) {
  84. console.warn('Some script mabe trying to disable F12 console.');
  85. i.toString = nativeToString;
  86. }
  87. const result = origFunc.apply(this, args);
  88. console.trace();
  89. return result;
  90. }
  91. };
  92. break;
  93. }
  94. Object.defineProperty(noWriteAbleConsole, k, {
  95. get: () => { return func },
  96. set: (val) => {
  97. originalConsole.warn('Some script trying to change console function:');
  98. originalConsole.warn(val);
  99. return val;
  100. }
  101. });
  102. }
  103. Object.defineProperty(window, 'console', {
  104. get: () => { return noWriteAbleConsole },
  105. set: (val) => {
  106. originalConsole.warn('Some script trying to change console object:');
  107. originalConsole.warn(val);
  108. return val;
  109. }
  110. });
  111. const realWindowEval = window.eval;
  112. if (localStorage.__disableEvalHook__ !== 'true') {
  113. window.eval = (func) => {
  114. if (func.indexOf('debugger') !== -1) {
  115. func = func.replace(/debugger?/, 'throw null');
  116. }
  117. console.log(func);
  118. const localEval = realWindowEval;
  119. const result = localEval.apply(this, [func]);
  120. return result;
  121. };
  122. }
  123. const origDefineProperty = Object.defineProperty;
  124. Object.defineProperty = (obj, k, opt) => {
  125. if (obj === window && k === 'console') {
  126. originalConsole.warn('Some script trying to change console object:');
  127. originalConsole.warn(opt);
  128. return;
  129. }
  130. const result = origDefineProperty(obj, k, opt);
  131. return result;
  132. };
  133. const origDefineProperties = Object.defineProperties;
  134. Object.defineProperties = (obj, opt) => {
  135. if (obj === window) {
  136. if (opt.console != null) {
  137. delete opt['console'];
  138. originalConsole.warn('Some script trying to change console object:');
  139. originalConsole.warn(opt);
  140. }
  141. }
  142. const result = origDefineProperties(obj, opt);
  143. return result;
  144. };
  145. } else {
  146. const originalConsole = {};
  147. for (let k in console) {
  148. let func = console[k];
  149. if (k === 'clear') {
  150. func = () => {};
  151. }
  152. originalConsole[k] = func;
  153. }
  154.  
  155. const setConsoleFunc = () => {
  156. for (let k in originalConsole) {
  157. console[k] = originalConsole[k];
  158. }
  159. }
  160.  
  161. setInterval(() => {
  162. setConsoleFunc();
  163. }, 1000);
  164. }
  165. })();