基于实战经验重构 JSVMP 分析框架: - SKILL.md: 新增路径选择决策树(路径 A 算法追踪 vs 路径 B 环境伪装) - SKILL.md: 路径 B「环境伪装六步法」完整方法论(采集→对比→分级→补丁→验证→端到端) - SKILL.md: 新增场景 10「JSVMP + jsdom 环境伪装」、解法模式 E - SKILL.md: 标注三板斧适用边界与局限,经验法则扩充至 22 条 - references/jsdom-env-patches.md: 新增 jsdom 环境补丁知识库(Function.toString 三层防御 / plugins 完整模拟 / DOM 布局属性 / 30+ API 存根) - cases/: 新增经验库系统(模板 + 首个 JSVMP 实战案例含 58 项环境检测差异全表) - references/jsvmp-analysis.md: JSVMP 专项分析详细指南 - references/troubleshooting.md: 常见问题排查指南 - templates/python-request/: Python 项目模板 - 各 references 文档增强、Python 技术栈支持、MCP v1.1 适配(44→52 工具) Made-with: Cursor
12 KiB
12 KiB
JS Hook 技术大全
概述
Hook 是 JS 逆向中最核心的技术之一。通过劫持/拦截 JS 原生函数或对象属性,可以捕获加密函数的 输入输出、Cookie 的生成过程、网络请求的参数构造等关键信息。
注入方式
通过 MCP 注入(推荐)
[camoufox-reverse] add_init_script(script=HookScript)
→ 在页面脚本加载前注入,确保 Hook 在目标代码之前生效
[camoufox-reverse] evaluate_js(expression=HookScript)
→ 在当前页面上下文执行,适合页面已加载后的动态注入
[camoufox-reverse] inject_hook_preset(preset="xhr|fetch|crypto|websocket|debugger_bypass")
→ 一键注入预设 Hook,覆盖常见逆向场景
[camoufox-reverse] hook_function(function_path="目标函数", hook_code="...", position="before|after|replace")
→ 对指定函数注入自定义 Hook
Hook 模板库
1. Cookie Setter Hook
用途:监控所有 Cookie 写入操作,定位动态 Cookie 生成逻辑
(function() {
let cookieTemp = '';
Object.defineProperty(document, 'cookie', {
set: function(val) {
console.log('[Hook] Cookie Set:', val);
if (val.indexOf('目标cookie名') !== -1) {
console.log('[Hook] ★ 目标Cookie捕获:', val);
console.trace('[Hook] Cookie 调用栈');
}
cookieTemp = val;
return val;
},
get: function() {
return cookieTemp;
}
});
})();
2. XHR Hook
用途:拦截所有 XMLHttpRequest 请求,捕获完整请求参数
(function() {
const _open = XMLHttpRequest.prototype.open;
const _send = XMLHttpRequest.prototype.send;
const _setHeader = XMLHttpRequest.prototype.setRequestHeader;
XMLHttpRequest.prototype.open = function(method, url) {
this._hookMethod = method;
this._hookUrl = url;
this._hookHeaders = {};
console.log('[Hook] XHR Open:', method, url);
return _open.apply(this, arguments);
};
XMLHttpRequest.prototype.setRequestHeader = function(name, value) {
this._hookHeaders[name] = value;
return _setHeader.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function(body) {
console.log('[Hook] XHR Send:', {
method: this._hookMethod,
url: this._hookUrl,
headers: this._hookHeaders,
body: body
});
if (this._hookUrl.indexOf('目标接口') !== -1) {
console.log('[Hook] ★ 目标请求捕获');
console.trace('[Hook] 请求调用栈');
}
return _send.apply(this, arguments);
};
})();
3. Fetch Hook
用途:拦截 fetch API 请求
(function() {
const _fetch = window.fetch;
window.fetch = function(url, options) {
console.log('[Hook] Fetch:', url, options);
if (typeof url === 'string' && url.indexOf('目标接口') !== -1) {
console.log('[Hook] ★ 目标Fetch捕获');
console.trace('[Hook] Fetch 调用栈');
}
return _fetch.apply(this, arguments);
};
})();
4. $.ajax Hook(jQuery 场景)
用途:拦截 jQuery AJAX 请求,捕获加密参数
(function() {
if (typeof $ === 'undefined' || typeof $.ajax === 'undefined') return;
const _ajax = $.ajax;
$.ajax = function(options) {
if (typeof options === 'object') {
console.log('[Hook] $.ajax:', {
url: options.url,
method: options.type || options.method,
data: options.data,
headers: options.headers
});
if (options.url && options.url.indexOf('目标接口') !== -1) {
console.log('[Hook] ★ 目标Ajax捕获');
if (options.data && options.data.m) {
console.log('[Hook] 加密参数 m:', options.data.m);
}
}
}
return _ajax.apply(this, arguments);
};
// 同时 Hook ajaxSetup
if ($.ajaxSetup) {
const _setup = $.ajaxSetup;
$.ajaxSetup = function(options) {
console.log('[Hook] $.ajaxSetup:', options);
return _setup.apply(this, arguments);
};
}
})();
5. eval / Function Hook
用途:捕获动态生成和执行的代码
(function() {
// eval Hook
const _eval = window.eval;
window.eval = function(code) {
console.log('[Hook] eval 调用, 代码长度:', (typeof code === 'string') ? code.length : 'N/A');
if (typeof code === 'string' && code.length < 5000) {
console.log('[Hook] eval 代码:', code.substring(0, 500));
}
return _eval.apply(this, arguments);
};
// Function 构造器 Hook
const _Function = Function;
const handler = {
construct(target, args) {
const body = args[args.length - 1];
console.log('[Hook] new Function, body 长度:', body ? body.length : 0);
if (body && body.indexOf('目标关键词') !== -1) {
console.log('[Hook] ★ 目标 Function 捕获:', body.substring(0, 500));
}
return new target(...args);
},
apply(target, thisArg, args) {
const body = args[args.length - 1];
console.log('[Hook] Function(), body 长度:', body ? body.length : 0);
return target.apply(thisArg, args);
}
};
window.Function = new Proxy(_Function, handler);
})();
6. JSON.parse Hook
用途:捕获 JSON 解析操作,常用于响应数据解密场景
(function() {
const _parse = JSON.parse;
JSON.parse = function(text) {
const result = _parse.apply(this, arguments);
console.log('[Hook] JSON.parse:', typeof text === 'string' ? text.substring(0, 200) : text);
return result;
};
})();
7. JSON.stringify Hook
用途:捕获 JSON 序列化操作,常在签名前执行
(function() {
const _stringify = JSON.stringify;
JSON.stringify = function(obj) {
const result = _stringify.apply(this, arguments);
console.log('[Hook] JSON.stringify:', result ? result.substring(0, 200) : result);
return result;
};
})();
8. atob / btoa Hook
用途:捕获 Base64 编解码操作
(function() {
const _atob = window.atob;
const _btoa = window.btoa;
window.atob = function(str) {
const result = _atob(str);
console.log('[Hook] atob:', str.substring(0, 100), '→', result.substring(0, 100));
return result;
};
window.btoa = function(str) {
const result = _btoa(str);
console.log('[Hook] btoa:', str.substring(0, 100), '→', result.substring(0, 100));
return result;
};
})();
9. setTimeout / setInterval Hook
用途:监控定时器调用,识别反调试和周期性操作
(function() {
const _setTimeout = window.setTimeout;
const _setInterval = window.setInterval;
window.setTimeout = function(fn, delay) {
const fnStr = typeof fn === 'function' ? fn.toString().substring(0, 200) : String(fn).substring(0, 200);
// 过滤 debugger 反调试
if (fnStr.indexOf('debugger') !== -1) {
console.log('[Hook] setTimeout 拦截 debugger,已跳过');
return -1;
}
return _setTimeout.apply(this, arguments);
};
window.setInterval = function(fn, delay) {
const fnStr = typeof fn === 'function' ? fn.toString().substring(0, 200) : String(fn).substring(0, 200);
if (fnStr.indexOf('debugger') !== -1) {
console.log('[Hook] setInterval 拦截 debugger,已跳过');
return -1;
}
return _setInterval.apply(this, arguments);
};
})();
10. WebSocket Hook
用途:拦截 WebSocket 消息
(function() {
const _WebSocket = window.WebSocket;
window.WebSocket = function(url, protocols) {
console.log('[Hook] WebSocket 连接:', url);
const ws = new _WebSocket(url, protocols);
const _send = ws.send.bind(ws);
ws.send = function(data) {
console.log('[Hook] WS 发送:', data);
return _send(data);
};
ws.addEventListener('message', function(event) {
console.log('[Hook] WS 接收:', event.data);
});
return ws;
};
window.WebSocket.prototype = _WebSocket.prototype;
})();
11. window 属性访问 Hook(蜜罐检测)
用途:监控对 window 属性的访问,识别蜜罐检测
(function() {
const handler = {
get(target, prop, receiver) {
if (['__selenium', '__webdriver_script_fn', '__driver_evaluate',
'$cdc_asdjflasutopfhvcZLmcfl_', 'callPhantom', '_phantom'].includes(prop)) {
console.log('[Hook] ★ 蜜罐属性访问:', prop);
return undefined;
}
return Reflect.get(target, prop, receiver);
}
};
// 注意:直接代理 window 风险较大,仅在需要时使用
})();
12. Canvas 指纹 Hook
用途:拦截 Canvas 指纹采集
(function() {
const _toDataURL = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype.toDataURL = function() {
console.log('[Hook] Canvas toDataURL 调用');
console.trace('[Hook] Canvas 调用栈');
return _toDataURL.apply(this, arguments);
};
const _toBlob = HTMLCanvasElement.prototype.toBlob;
HTMLCanvasElement.prototype.toBlob = function() {
console.log('[Hook] Canvas toBlob 调用');
return _toBlob.apply(this, arguments);
};
})();
13. Navigator 属性 Hook
用途:伪装浏览器指纹
(function() {
Object.defineProperty(navigator, 'webdriver', {
get: () => false
});
Object.defineProperty(navigator, 'plugins', {
get: () => [1, 2, 3, 4, 5]
});
Object.defineProperty(navigator, 'languages', {
get: () => ['zh-CN', 'zh', 'en']
});
})();
组合 Hook 模板
通用逆向分析 Hook(一键注入)
(function() {
console.log('[Hook] ========== 通用逆向Hook已注入 ==========');
// 1. Cookie 监控
let _cookie = document.cookie;
Object.defineProperty(document, 'cookie', {
set(v) { console.log('[Cookie] Set:', v); _cookie += '; ' + v; },
get() { return _cookie; }
});
// 2. XHR 监控
const _xhrOpen = XMLHttpRequest.prototype.open;
const _xhrSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(m, u) { this._m = m; this._u = u; return _xhrOpen.apply(this, arguments); };
XMLHttpRequest.prototype.send = function(b) { console.log('[XHR]', this._m, this._u, b); return _xhrSend.apply(this, arguments); };
// 3. Fetch 监控
const _fetch = window.fetch;
window.fetch = function() { console.log('[Fetch]', ...arguments); return _fetch.apply(this, arguments); };
// 4. debugger 拦截
const _si = window.setInterval;
window.setInterval = function(fn, d) {
if (typeof fn === 'function' && fn.toString().indexOf('debugger') > -1) return -1;
return _si.apply(this, arguments);
};
console.log('[Hook] ========== Hook注入完成 ==========');
})();
MCP 注入最佳实践
- 使用
add_init_script:确保 Hook 在目标代码之前生效 - 优先使用
inject_hook_preset:一键注入 xhr/fetch/crypto/websocket/debugger_bypass 预设 Hook - 使用
hook_function:对特定函数注入 before/after/replace Hook - 使用
console.log输出:通过get_console_logs收集结果 - 使用
console.trace:在关键点输出调用栈 - Camoufox 优势:Juggler 协议沙箱隔离,Hook 不会被页面 JS 检测到
- 使用 Proxy 代替直接覆写:更隐蔽,不改变
typeof结果