├── Bypass_Debugger(Proxy).js ├── Bypass_Debugger(备用).js ├── Bypass_Debugger.js ├── README.md └── image └── README ├── 1733639165304.png └── 1733639172782.png /Bypass_Debugger(Proxy).js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Bypass_Debugger(Proxy) 3 | // @namespace https://github.com/0xsdeo/Bypass_Debugger 4 | // @version 2025-1-02 5 | // @description Bypass new Function --> debugger && constructor --> debugger && eval --> debugger 6 | // @author 0xsdeo 7 | // @match http://*/* 8 | // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== 9 | // @grant none 10 | // ==/UserScript== 11 | 12 | (function () { 13 | 'use strict'; 14 | 15 | let temp_eval = eval; 16 | let temp_toString = Function.prototype.toString; 17 | 18 | Function.prototype.toString = function () { 19 | if (this === eval) { 20 | return 'function eval() { [native code] }'; 21 | } else if (this === Function) { 22 | return 'function Function() { [native code] }'; 23 | } else if (this === Function.prototype.toString) { 24 | return 'function toString() { [native code] }'; 25 | } else if (this === Function.prototype.constructor) { 26 | return 'function Function() { [native code] }'; 27 | } 28 | return temp_toString.apply(this, arguments); 29 | } 30 | 31 | window.eval = function () { 32 | if (typeof arguments[0] == "string") { 33 | arguments[0] = arguments[0].replaceAll(/debugger/g, ''); 34 | } 35 | return temp_eval(...arguments); 36 | } 37 | 38 | let Bypass_debugger = Function; 39 | 40 | Function.prototype.constructor = function () { 41 | for (let i = 0; i < arguments.length; i++) { 42 | if (typeof arguments[i] == "string") { 43 | arguments[i] = arguments[i].replaceAll(/debugger/g, ''); 44 | } 45 | } 46 | return Bypass_debugger(...arguments); 47 | } 48 | 49 | Function.prototype.constructor.prototype = Function.prototype; 50 | 51 | let handler = { 52 | apply: function (target, thisArg, argumentsList) { 53 | for (let i = 0; i < argumentsList.length; i++) { 54 | if (typeof argumentsList[i] == "string") { 55 | argumentsList[i] = argumentsList[i].replaceAll(/debugger/g, ''); 56 | } 57 | } 58 | return Bypass_debugger(...argumentsList); 59 | }, 60 | construct: function (target, argumentsList, newTarget) { 61 | for (let i = 0; i < argumentsList.length; i++) { 62 | if (typeof argumentsList[i] == "string") { 63 | argumentsList[i] = argumentsList[i].replaceAll(/debugger/g, ''); 64 | } 65 | } 66 | return Bypass_debugger(...argumentsList); 67 | }, 68 | }; 69 | 70 | Function = new Proxy(Function, handler); 71 | })(); -------------------------------------------------------------------------------- /Bypass_Debugger(备用).js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Bypass_Debugger(备用) 3 | // @namespace https://github.com/0xsdeo/Bypass_Debugger 4 | // @version 2024-12-06 5 | // @description Bypass new Function --> debugger && constructor --> debugger && eval --> debugger 6 | // @author 0xsdeo 7 | // @match http://*/* 8 | // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== 9 | // @grant none 10 | // ==/UserScript== 11 | 12 | (function () { 13 | var temp_toString = Function.prototype.toString; 14 | 15 | Function.prototype.toString = function () { 16 | if (this === eval) { 17 | return 'function eval() { [native code] }'; 18 | } else if (this === Function) { 19 | return 'function Function() { [native code] }'; 20 | } else if (this === Function.prototype.toString) { 21 | return 'function toString() { [native code] }'; 22 | } 23 | return temp_toString.apply(this, arguments); 24 | } 25 | var Bypass_debugger = Function; 26 | 27 | Function = function () { 28 | var reg = /debugger/; 29 | for (var i = 0; i < arguments.length; i++) { 30 | if (typeof arguments[i] == "string") { 31 | var temp_length = arguments[i].match(/debugger/g); 32 | if (temp_length != null) { 33 | temp_length = temp_length.length; 34 | while (temp_length) { 35 | arguments[i] = arguments[i].replace(reg, ""); 36 | temp_length--; 37 | } 38 | } 39 | } 40 | } 41 | return Bypass_debugger(...arguments); 42 | } 43 | 44 | Function.prototype = Bypass_debugger.prototype; 45 | 46 | Function.prototype.constructor = function () { 47 | var reg = /debugger/; 48 | for (var i = 0; i < arguments.length; i++) { 49 | if (typeof arguments[i] == "string") { 50 | var temp_length = arguments[i].match(/debugger/g); 51 | if (temp_length != null) { 52 | temp_length = temp_length.length; 53 | while (temp_length) { 54 | arguments[i] = arguments[i].replace(reg, ""); 55 | temp_length--; 56 | } 57 | } 58 | } 59 | } 60 | return Bypass_debugger(...arguments); 61 | } 62 | 63 | Function.prototype.constructor.prototype = Function.prototype; 64 | 65 | var temp_eval = eval; 66 | 67 | let bridge_fun = function () { 68 | if (typeof arguments[0] == "string") { 69 | var temp_length = arguments[0].match(/debugger/g); 70 | if (temp_length != null) { 71 | temp_length = temp_length.length; 72 | var reg = /debugger/; 73 | while (temp_length) { 74 | arguments[0] = arguments[0].replace(reg, ""); 75 | temp_length--; 76 | } 77 | } 78 | } 79 | return temp_eval(...arguments); 80 | } 81 | 82 | let handler = { 83 | apply: function (target, thisArg, argumentsList) { 84 | if (arguments.callee.caller != null && arguments.callee.caller.arguments.length !== 0 && typeof argumentsList[0] == "string" && argumentsList[0].indexOf('()') === -1) { 85 | let fun = arguments.callee.caller.toString(); 86 | let parameter = fun.substring(fun.indexOf('(') + 1, fun.indexOf(')')).split(','); 87 | let temp_str = ''; 88 | for (let i = 0; i < argumentsList.length; i++) { 89 | temp_str = temp_str + argumentsList[i]; 90 | } 91 | return Function(...parameter, 'return ' + temp_str)(...arguments.callee.caller.arguments); 92 | } 93 | return bridge_fun(...argumentsList); 94 | }, 95 | }; 96 | 97 | eval = new Proxy(eval, handler); 98 | })(); -------------------------------------------------------------------------------- /Bypass_Debugger.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Bypass_Debugger 3 | // @namespace https://github.com/0xsdeo/Bypass_Debugger 4 | // @version 2024-12-06 5 | // @description Bypass new Function --> debugger && constructor --> debugger && eval --> debugger 6 | // @author 0xsdeo 7 | // @match http://*/* 8 | // @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== 9 | // @grant none 10 | // ==/UserScript== 11 | 12 | (function() { 13 | 'use strict'; 14 | 15 | let temp_eval = eval; 16 | let temp_toString = Function.prototype.toString; 17 | 18 | Function.prototype.toString = function () { 19 | if (this === eval) { 20 | return 'function eval() { [native code] }'; 21 | } else if (this === Function) { 22 | return 'function Function() { [native code] }'; 23 | } else if (this === Function.prototype.toString) { 24 | return 'function toString() { [native code] }'; 25 | } else if (this === Function.prototype.constructor) { 26 | return 'function Function() { [native code] }'; 27 | } 28 | return temp_toString.apply(this, arguments); 29 | } 30 | 31 | window.eval = function () { 32 | if (typeof arguments[0] == "string") { 33 | arguments[0] = arguments[0].replaceAll(/debugger/g, ''); 34 | } 35 | return temp_eval(...arguments); 36 | } 37 | 38 | let Bypass_debugger = Function; 39 | 40 | Function = function () { 41 | for (let i = 0; i < arguments.length; i++) { 42 | if (typeof arguments[i] == "string") { 43 | arguments[i] = arguments[i].replaceAll(/debugger/g, ''); 44 | } 45 | } 46 | return Bypass_debugger(...arguments); 47 | } 48 | 49 | Function.prototype = Bypass_debugger.prototype; 50 | 51 | Function.prototype.constructor = function () { 52 | for (let i = 0; i < arguments.length; i++) { 53 | if (typeof arguments[i] == "string") { 54 | arguments[i] = arguments[i].replaceAll(/debugger/g, ''); 55 | } 56 | } 57 | return Bypass_debugger(...arguments); 58 | } 59 | 60 | Function.prototype.constructor.prototype = Function.prototype; 61 | })(); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bypass_Debugger 2 | 3 | ## Intro 4 | 5 | 该脚本可bypass: 6 | 7 | 1. new Function --> debugger 8 | 2. constructor --> debugger 9 | 3. eval --> debugger 10 | 11 | ## 注意事项 12 | 13 | 1. 本脚本在油猴里的运行时期为`document-start`。 14 | 15 | 2. 如果发现hook后打开F12依然存在debugger: 16 | 17 | - **建议开着F12在刷新一次。** 18 | - 请检查油猴或其他插件加载的脚本是不是做了同样的操作,例如重写Function等等,个人建议使用时除不是自己写的脚本(指没有做本脚本同样动作的)都关闭。 19 | 20 | 3. 我的这段Bypass Debugger脚本,目前已知的只有以下这两种情况不能被bypass掉: 21 | ```js 22 | var dbg = function (){ 23 | debugger; 24 | } 25 | setInterval(dbg,3000); 26 | ``` 27 | ![1733639165304](image/README/1733639165304.png) 28 | 29 | 以及直接将debugger写在script当中的: 30 | 31 | ![1733639172782](image/README/1733639172782.png) 32 | 33 | 以上这两种设条件断点就能过(如果不知道怎么设置条件断点的可以去看一下我之前写的反调试与反反调试一文),或者替换也行,不需要hook的,所以我就暂时没去管这个。 34 | 35 | 4. 如果发现hook后站点js出现异常,可以考虑使用备用脚本。 36 | 37 | 5. Bypass_Debugger和Bypass_Debugger(Proxy)这两个脚本都可以使用,两个脚本的区别就是Bypass_Debugger(Proxy)脚本是通过Proxy重写的Function,我的建议是继续使用Bypass_Debugger脚本,Bypass_Debugger(Proxy)脚本可以拿来做学习研究。 38 | 39 | ## Contact 40 | 41 | 如有bug或其他问题可提交issues,或者关注公众号Spade sec联系我。 42 | -------------------------------------------------------------------------------- /image/README/1733639165304.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xsdeo/Bypass_Debugger/504ee6daf81c5e109a896e7edd2b4a026875c184/image/README/1733639165304.png -------------------------------------------------------------------------------- /image/README/1733639172782.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xsdeo/Bypass_Debugger/504ee6daf81c5e109a896e7edd2b4a026875c184/image/README/1733639172782.png --------------------------------------------------------------------------------