如何重写window.console.debug使其在Chrome DevTools启用时行为一致?
解决console.debug反DevTools检测的方案
核心问题分析
恶意网站通过校验console.debug的原生特性(比如函数标识、内部属性、调用耗时)来判断Chrome开发者工具是否打开。你之前的两种方案都破坏了这些原生特性,所以被检测到。要绕过检测,必须在保留原生函数所有属性与行为的前提下,仅拦截检测逻辑。
可行解决方案
方案1:精准拦截检测调用(推荐)
如果网站是通过传递特定参数调用console.debug做检测(比如传入带标记的对象),用Proxy包装原生函数,只针对检测调用返回预期结果,其余情况正常执行:
const originalDebug = console.debug; window.console.debug = new Proxy(originalDebug, { apply(target, thisArg, args) { // 根据网站实际检测逻辑调整判断条件,比如识别特定参数 const isDetectionCall = args.some(arg => typeof arg === 'object' && arg?.hasOwnProperty('__devtoolsDetect') ); if (isDetectionCall) { // 返回DevTools关闭时的预期结果(通常为undefined) return undefined; } // 正常执行原生debug方法 return Reflect.apply(target, thisArg, args); } });
方案2:完全模拟原生函数特性
如果网站检测的是console.debug的原生身份(比如校验toString()输出、函数内部属性),复制原生函数的所有属性到自定义函数,同时保留原生行为:
const originalDebug = console.debug; const fakeDebug = function(...args) { // 掩盖DevTools打开时的执行耗时差异 const start = performance.now(); const result = originalDebug.apply(this, args); // 强制让调用耗时与DevTools关闭时一致 while (performance.now() - start < 0.1) {} return result; }; // 复制原生函数的所有属性,避免检测异常 Object.getOwnPropertyNames(originalDebug).forEach(prop => { Object.defineProperty(fakeDebug, prop, Object.getOwnPropertyDescriptor(originalDebug, prop)); }); // 覆盖toString方法,返回原生函数的特征字符串 fakeDebug.toString = () => originalDebug.toString(); window.console.debug = fakeDebug;
关键注意事项
- 必须保留
console.debug的所有原生属性(如name、length、toString()输出),否则网站会通过Object.prototype.toString.call(console.debug)或console.debug.toString()检测出异常。 - 如果网站通过调用耗时判断DevTools状态,需通过强制等待抹平耗时差异。
- 优先分析网站的具体检测逻辑,针对性拦截比全量模拟更高效,也不会影响正常的
console.debug功能。
内容的提问来源于stack exchange,提问作者Jimmy J.K.
相关产品推荐
相关产品推荐

