当前位置: 首页 > news >正文

油猴脚本:Hook Function构造器实现前端反调试绕过

1. 为什么需要Hook Function构造器

当你打开Chrome开发者工具调试某些网站时,经常会遇到无限debugger暂停的问题,导致无法正常调试代码。这是因为目标网站的前端代码中植入了大量反调试代码,最常见的就是使用debugger语句。

传统的解决方案是直接禁用所有断点,但这会导致我们失去正常的调试能力。更优雅的方式是通过Hook Function.prototype.constructor来精准拦截并净化包含debugger的恶意代码,就像外科手术一样精确。

我在实际爬虫项目中遇到过这样一个案例:某电商网站使用了动态生成debugger语句的混淆代码,每隔几秒就会触发一次debugger。通过分析发现,他们是通过Function构造器动态生成包含debugger的代码。这时候就需要用到我们今天要介绍的Hook技术。

2. debugger反调试原理剖析

2.1 常见的debugger实现方式

网站开发者通常会用以下几种方式实现反调试:

  1. 直接插入debugger语句:
setInterval(function(){ debugger; }, 1000);
  1. 通过Function构造器动态生成:
new Function("debugger")();
  1. 使用eval执行包含debugger的字符串:
eval("deb" + "ugger");
  1. 更隐蔽的拼接方式:
var a = "deb"; var b = "ugger"; setInterval(function(){ eval(a + b); }, 100);

2.2 为什么Hook Function构造器有效

JavaScript中所有函数都是Function构造器的实例,包括通过function关键字定义的函数。当我们Hook Function.prototype.constructor时,实际上拦截了所有函数的创建过程。这让我们有机会在函数被创建时检查其内容,如果发现包含debugger就进行净化处理。

这种方法的优势在于:

  • 精准拦截,不影响其他正常代码
  • 无需禁用所有断点,保留调试能力
  • 可以处理动态生成的debugger代码
  • 兼容大多数现代浏览器

3. 油猴脚本实现详解

3.1 完整脚本代码

下面是一个完整的油猴脚本实现,可以直接安装使用:

// ==UserScript== // @name Anti Anti-debugger // @namespace http://tampermonkey.net/ // @version 1.0 // @description 通过Hook Function构造器绕过前端反调试 // @author YourName // @match *://*/* // @grant unsafeWindow // @run-at document-start // ==/UserScript== (function() { 'use strict'; // 保存原始Function构造器 var originalConstructor = unsafeWindow.Function.prototype.constructor; // Hook Function构造器 unsafeWindow.Function.prototype.constructor = function() { // 获取函数体内容 var fnBody = arguments[0]; if (fnBody && typeof fnBody === 'string') { // 检查是否包含debugger if (fnBody.includes('debugger')) { // 获取调用者信息(非标准实现,部分浏览器支持) var caller = Function.prototype.constructor.caller; if (caller) { var callerStr = caller.toString(); if (callerStr.includes('debugger')) { // 移除调用者中的所有debugger语句 callerStr = callerStr.replace(/\bdebugger\b/gi, ''); try { // 重新定义调用者函数 eval('caller = ' + callerStr); } catch(e) { console.warn('Failed to redefine caller:', e); } } } // 返回一个空函数替代原函数 return function(){}; } } // 正常情况使用原始构造器 return originalConstructor.apply(this, arguments); }; })();

3.2 关键代码解析

  1. @run-at document-start:确保脚本在页面加载前执行,尽早Hook

  2. unsafeWindow:访问页面的原始window对象

  3. 保存原始构造器:先备份原始Function.prototype.constructor,以便后续正常调用

  4. 检查函数体:分析传入的代码字符串是否包含debugger关键字

  5. 处理调用链:尝试找到并净化调用链上的debugger语句

  6. 返回空函数:对于包含debugger的函数,返回一个无害的空函数

4. 高级应用与优化

4.1 处理混淆代码

对于经过混淆的代码,简单的字符串匹配可能不够。我们可以增强检测逻辑:

// 增强版的debugger检测 function containsDebugger(code) { // 处理简单debugger if (code.includes('debugger')) return true; // 处理拆分的debugger var debuggerParts = ['de', 'bug', 'ger']; var combined = debuggerParts.join(''); if (code.includes(combined)) return true; // 处理通过字符编码表示的debugger var charCodes = [100, 101, 98, 117, 103, 103, 101, 114]; var fromCharCode = String.fromCharCode(...charCodes); if (code.includes(fromCharCode)) return true; return false; }

4.2 性能优化

Hook Function构造器可能影响页面性能,特别是对于大量使用动态函数的网站。我们可以添加白名单机制:

// 域名白名单 var whitelist = [ 'trusted-site.com', 'cdn.google.com' ]; // 检查当前域名是否在白名单 function isWhitelisted() { return whitelist.some(function(domain) { return window.location.hostname.endsWith(domain); }); } // 修改Hook逻辑 if (!isWhitelisted()) { unsafeWindow.Function.prototype.constructor = function() { // Hook逻辑... }; }

4.3 错误处理增强

添加更健壮的错误处理,避免脚本自身导致页面崩溃:

try { var originalConstructor = unsafeWindow.Function.prototype.constructor; unsafeWindow.Function.prototype.constructor = function() { try { // Hook逻辑... } catch (e) { console.error('Hook error:', e); return originalConstructor.apply(this, arguments); } }; } catch (e) { console.error('Initialization failed:', e); }

5. 实际案例分析

5.1 电商网站反调试破解

某电商网站使用了如下反调试代码:

function createDebugger() { return new Function( 'var a="deb";var b="ugger";' + 'if(window.console){' + ' eval(a+b);' + '}' ); } setInterval(createDebugger(), 3000);

我们的Hook脚本成功拦截了这种动态生成的debugger,因为:

  1. 检测到new Function调用
  2. 分析出拼接的debugger字符串
  3. 返回了空函数替代原函数

5.2 金融网站保护机制绕过

某金融网站使用了更复杂的保护:

var _0xad3b = ["\x64\x65\x62\x75\x67\x67\x65\x72"]; (function(_0x12cf8a, _0xad3b82) { var _0x5e4f4a = function(_0x1a8f00) { while (--_0x1a8f00) { _0x12cf8a["push"](_0x12cf8a["shift"]()); } }; _0x5e4f4a(++_0xad3b82); })(_0xad3b, 0x1a3); var _0x5e4f = function(_0x12cf8a, _0xad3b82) { _0x12cf8a = _0x12cf8a - 0x0; var _0x5e4f4a = _0xad3b[_0x12cf8a]; return _0x5e4f4a; }; setInterval(function() { var _0x1a8f00 = _0x5e4f("0x0"); new Function(_0x1a8f00)(); }, 0x7d0);

即使在这种复杂混淆下,我们的Hook仍然有效,因为它最终还是要通过Function构造器执行。

6. 常见问题与解决方案

6.1 Hook后功能异常

有时Hook可能导致网站功能异常,解决方案:

  1. 检查是否是白名单网站
  2. 添加更精确的匹配条件
  3. 在特定条件下恢复原始构造器
var isDebugging = false; unsafeWindow.Function.prototype.constructor = function() { if (!isDebugging) { return originalConstructor.apply(this, arguments); } // 正常的Hook逻辑... };

6.2 无法拦截eval执行的debugger

对于直接使用eval的情况,可以额外Hook eval:

var originalEval = unsafeWindow.eval; unsafeWindow.eval = function(code) { if (containsDebugger(code)) { console.log('Blocked debugger in eval'); return; } return originalEval.apply(this, arguments); };

6.3 性能开销问题

对于性能敏感的场景:

  1. 限制Hook的作用范围
  2. 使用更高效的正则匹配
  3. 避免不必要的调用栈分析
// 简化的性能优化版 unsafeWindow.Function.prototype.constructor = function() { var fnBody = arguments[0]; if (typeof fnBody === 'string' && /d\s*e\s*b\s*u\s*g\s*g\s*e\s*r/i.test(fnBody)) { return function(){}; } return originalConstructor.apply(this, arguments); };

7. 安全与伦理考量

在使用这类技术时,需要注意:

  1. 仅用于合法授权的测试
  2. 尊重网站的robots.txt协议
  3. 不要绕过合理的访问限制
  4. 遵守相关法律法规

技术本身是中立的,关键在于使用者的意图。作为开发者,我们应当把这类技术用于提升Web安全性,而不是滥用它。

http://www.cnnetsun.cn/news/3351632.html

相关文章:

  • 2026年实测8款主流AI数字人直播平台:盘点选型雷区,降低开播试错成本
  • 如何用Playnite打造终极游戏库管理器:一站式解决多平台游戏管理难题
  • 您的软件未签名,部分打印功能受限使用。请使用官方签名的软件版本
  • G-Helper终极指南:专业级华硕笔记本性能优化与色彩恢复解决方案
  • YimMenu深度解析:如何在GTA5中实现安全增强的游戏体验
  • The Rock-It Company进军阿布扎比,进一步巩固该首都作为奢侈品、文化及重大活动全球枢纽的地位
  • PalEdit幻兽编辑器:打造专属幻兽世界的终极神器
  • G-Helper:华硕笔记本色彩恢复与系统优化的完整指南
  • 终极Mac窗口管理神器:AltTab让Windows用户无缝切换MacOS
  • 【6.29】芯片工艺对比 + Bring-up 上电全流程
  • 猫抓浏览器资源嗅探:三步实现高效媒体捕获的终极指南
  • SmolLM2-135M-Instruct配置文件详解:genai_config.json参数调优终极指南
  • scroll-world安装指南:3种方法快速部署你的3D滚动世界(Claude Code/Codex/手动安装)
  • mlx-community/Qwen3.5-2B-OptiQ-4bit的MTP推测解码技术详解:实现1.4倍推理加速终极指南
  • GPT-OSS-120B量化模型与原始模型对比:精度与效率平衡之道终极指南
  • Ornith-1.0-35B-6bit快速上手指南:3行代码实现图片描述,Mac用户必看
  • 革命性世界建模AI:LingBot-World 2.0如何实现无限交互视界?
  • Qwen2架构详解:VibeThinker-3B-8bit背后的技术原理与创新点
  • 解密MXFP4量化黑科技:Kimi-K2-Instruct-0905-MXFP4模型压缩技术深度解析
  • 深入理解Llama-2-7b-chat-hf_rai_1.7.1_npu_4K的Hybrid OGA架构:NPU与CPU协同推理机制
  • Gemma-4-26B-A4B-it-8bit终极配置指南:优化参数设置提升图像理解能力
  • AMD Ryzen AI模型部署实战:Mistral-7B-Instruct-v0.3的16K上下文处理能力
  • 10个实用技巧:用Kimodo-SOMA-RP-v1.1提升游戏开发动画效率
  • Qwen3-8B-WMXFP4FP8-AMXFP4FP8-AMP-KVFP8模型原理详解:KV Cache FP8量化如何提升推理速度
  • 点亮智慧之眼!2026武汉国际车灯照明展会开幕,重塑未来出行光影美学
  • furrr性能调优:如何设置chunk_size和scheduling提升速度
  • 2026 实体产品包装数字化升级路径|全链路一体化服务体系解析
  • 源码交付与禁止转包成为挑选软件开发服务商的硬性标尺——西安服务商实力排行与行业趋势解析
  • 如何快速部署Qwen2.5-Coder-7B-Instruct_rai_1.7.1_npu_4K:5分钟入门指南
  • vLLM与Kimi-K2-Thinking-MXFP4-AttnFP8集成指南:高效推理服务器配置