允许使用 F12

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

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