在 JS 逆向过程中,最耗时的环节往往是 定位加密参数生成位置 和追踪动态代码执行。无论是请求头里的 Authorization、Cookie 中的 Token,还是 WebSocket 传输的加密数据,Hook 技术都是解决这类问题的“手术刀”。本文整理了 6 类高频 Hook 场景的实战脚本,结合 Chrome 调试技巧,帮你 3 分钟定位核心逻辑,避开逆向踩坑点。
一、Hook 环境搭建:油猴脚本基础框架
所有实战脚本均基于 油猴(Tampermonkey)运行,它能确保 Hook 代码在页面脚本加载前执行(关键前提)。先记住这个基础框架,后续只需替换核心 Hook 逻辑即可。
// ==UserScript==
// @name JS 逆向 Hook 工具箱
// @namespace https://yourblog.com
// @match https://target-website.com/* // 替换为目标网站
// @grant none
// @version 1.0.0
// @author 你的名称
// @description JS 逆向高频 Hook 脚本集合
// @run-at document-start // 必须前置执行,否则 Hook 失效
// ==/UserScript==
(function() {
'use strict';
// 此处插入具体 Hook 代码
})();实战细节:@match需精确到目标域名(如 CSDN 用 https://blog.csdn.net/*),@run-at 必须设为document-start,否则页面原生函数已执行,Hook 会失效。
二、JSON Hook:抓包请求 / 响应序列化核心
90% 的异步请求会用 JSON.stringify 序列化参数、JSON.parse 解析响应。Hook 这两个方法,能直接捕获加密前的原始参数和解密后的响应数据。
// 1. Hook JSON.stringify(请求参数序列化)const originalStringify = JSON.stringify;
JSON.stringify = function(params) {console.log("[JSON Hook] 序列化参数:", params);
// 检测关键参数(按需修改 token/sign 等关键词)if (typeof params === 'object' && params !== null) {if ('sign' in params || 'token' in params || 'timestamp' in params) {debugger; // 触发断点,查看调用栈}
}
return originalStringify.apply(this, arguments);
};
// 2. Hook JSON.parse(响应数据解析)const originalParse = JSON.parse;
JSON.parse = function(text) {console.log("[JSON Hook] 解析响应:", text);
// 响应中含关键数据时断点
if (text.includes('userInfo') || text.includes('data')) {debugger;}
return originalParse.apply(this, arguments);
};调试技巧:触发断点后,在 Chrome 开发者工具的「Call Stack」面板向上追溯,找到调用 JSON.stringify 的上级函数,即为参数生成的核心逻辑。


三、WebSocket Hook:追踪实时通信加密数据
实时交互场景(如直播、聊天)常用 WebSocket,Hook 其 send 方法可捕获发送的原始数据,无需抓包分析帧协议。
// 保存原生 WebSocket
window._originalWebSocket = window.WebSocket;
// Hook WebSocket 构造函数
window.WebSocket = function(url, protocols) {const ws = new window._originalWebSocket(url, protocols);
// Hook send 方法
const originalSend = ws.send;
ws.send = function(data) {console.log("[WebSocket Hook] 发送数据:", data);
// 含加密关键词时断点
if (data.includes('encrypt') || data.includes('payload')) {debugger;}
return originalSend.apply(this, arguments);
};
return ws;
};浏览器兼容:Firefox 需替换为 window.MozWebSocket,实战中可通过if ('MozWebSocket' in window) 判断环境。
四、Headers 与 Cookie Hook:锁定认证信息来源
Authorization、Token 等认证信息常藏在请求头或 Cookie 中,Hook 这两类场景能快速定位其生成逻辑。
4.1 请求头 Authorization Hook
// 注入脚本避免跨域限制
function injectHeaderHook() {
const originalSetHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.setRequestHeader = function(key, value) {if (key.toLowerCase() === 'authorization') {console.log("[Header Hook] Authorization:", value);
debugger; // 捕获 Token/JWT 生成
}
return originalSetHeader.apply(this, arguments);
};
}
// 动态注入脚本
const script = document.createElement('script');
script.textContent = `(${injectHeaderHook.toString()})()`;
(document.head || document.documentElement).appendChild(script);
script.remove();
4.2 Cookie Hook:追踪 Token/Sign 生成
用 Object.defineProperty 重写 Cookie 的 get/set 方法,监控所有读写操作,支持关键词过滤。
const cookieDescriptor = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') || {
configurable: true,
enumerable: true
};
Object.defineProperty(Document.prototype, 'cookie', {get() {const cookies = cookieDescriptor.get ? cookieDescriptor.get.call(this) : '';
// 读取关键 Cookie 时打印
if (/token|session|sign/i.test(cookies)) {console.log("[Cookie Get] 读取关键 Cookie:", cookies);
}
return cookies;
},
set(value) {console.log("[Cookie Set] 写入 Cookie:", value);
// 写入指定关键词时断点
if (/token=|sign=/.test(value)) {console.trace('关键 Cookie 设置调用栈');
debugger;
}
return cookieDescriptor.set ? cookieDescriptor.set.call(this, value) : value;
}
});快速定位 Cookie 生成请求:在 Chrome「Application」→「Cookies」中右键目标 Cookie,选择「显示涉及此 Cookie 的请求」,Network 面板会自动过滤相关请求,第一个请求即为生成源头。


五、动态代码 Hook:eval 与 Function 拦截
逆向中常遇到用 eval 或 Function 动态执行加密代码的情况,直接搜索关键词无效,需 Hook 这两个函数。
5.1 eval Hook:捕获动态执行代码
// 保存原生 eval 并伪装
const nativeEval = window.eval;
window.eval = function(code) {console.log("[eval Hook] 执行代码:", code.slice(0, 300) + "..."); // 截取前 300 字符
// 含加密关键词时断点
if (/encrypt|signature|login/i.test(code)) {debugger;}
return nativeEval.call(window, code);
};
// 避免被检测为非原生函数
Object.defineProperty(window.eval, 'toString', {value: () => 'function eval() { [native code] }',
writable: false
});
5.2 Function Hook:追踪动态创建函数
Function 是函数构造函数,动态创建的加密函数会通过它生成,用 Proxy 拦截更隐蔽。
function hookFunctionConstructor() {
const nativeFunction = window.Function;
window.Function = new Proxy(nativeFunction, {construct(target, args) {const funcCode = args[args.length - 1]; // Function 最后一个参数是代码
console.log("[Function Hook] 动态创建函数:", funcCode.slice(0, 200) + "...");
if (/encrypt|key/i.test(funcCode)) {debugger;}
return Reflect.construct(target, args);
}
});
}
hookFunctionConstructor();
六、Ajax 断点:无需代码定位请求
简单场景无需写 Hook 脚本,Chrome 自带 XHR 断点功能:在「Sources」→「XHR/ Fetch Breakpoints」中点击「+」,输入请求 URL 关键词(如/api/login),请求触发时会自动断点。

七、实战总结:Hook 技术核心原则
- 前置执行 :所有 Hook 代码必须在页面脚本加载前运行(油猴
document-start或注入脚本); - 关键词精准:断点条件尽量用目标网站的实际参数名(如 sign、token),减少无效断点;
- 隐蔽性:重写函数后需伪装原生特性(如 toString 方法),避免被反爬检测;
- 调用栈追溯:断点触发后,通过 Call Stack 向上找最接近业务逻辑的函数,而非底层方法。
这些脚本经过多个逆向项目验证,能解决 80% 的参数定位问题。但实战中需灵活调整,比如遇到混淆代码时,可结合 AST 反混淆工具再用 Hook 定位。你在逆向中还遇到过哪些 Hook 难题?欢迎在评论区交流。