检测手段
- function.toString, regexp.toString()等(详细见他的源码)
效果

nop掉检测
const originalSymbol = Symbol('hookMethod');
// copy original function
function copyFunction(fn){
return typeof fn === "function" && Object.create(fn).__proto__;
}
function hookMethod(object, prop, newHandler){
const originalHandler = copyFunction(object[prop]);
if (!originalHandler) return;
newHandler[originalSymbol] = originalHandler;
object[prop] = function(){
return newHandler.apply(this, arguments);
};
}
const methods = ['debug', 'info', 'log', 'error', 'table', 'dir'];
methods.forEach(key=>{
hookMethod(console, key, function handler(fn){
if(typeof fn === "function" && fn.name === "devtoolsTestFunction"){
handler[originalSymbol]("function devtoolsTestFunction.toString() get called")
return;
}
/*
\src\checkers\performance.checker.ts
大数组打印耗时检测, 如果不打开控制台, 耗时直接为0了
这里发现是大数组后先返回,然后setTimeout执行打印。
既避开了检测,又可以正常打印。
*/
if (Array.isArray(fn) && fn.length === 50){
setTimeout(function(){
return handler[originalSymbol].apply(this, arguments);
});
return
}
return handler[originalSymbol].apply(this, arguments);
})
});
// disable console.clear function call
hookMethod(console, "clear", function(){
});
/*
动态构造debugger检测
*/
hookMethod(Function.prototype, "constructor", function handler(code){
arguments[0] = code.replace("debugger", "")
return handler[originalSymbol].apply(this,arguments );
});
hookMethod(window, "eval", function handler(code){
arguments[0] = code.replace("debugger")
return handler[originalSymbol].apply(this,arguments );
});
/*
reg.toString 检测
*/
Object.defineProperty(RegExp.prototype, "toString", {
set(val){
/*
由于打包工具的存在,这里实际的代码可能会有变化, 重写 RegExp.prototype.toString 极为少见,这里选择nop掉
*/
}
})
/*
date.toString 检测
*/
Object.defineProperty(Date.prototype, "toString", {
set(handler){
/*
new Date().toString() 还是蛮常用的(自定义formatter啥的),所以这里不能nop 掉, 但目前没啥好方法,先nop吧
*/
}
})