CDP 远程调试
启动浏览器并开放调试端口
# Chrome
chrome.exe --remote-debugging-port=9222
# Edge(建议指定独立 user-data-dir)
msedge.exe --remote-debugging-port=9222 --user-data-dir=D:\edge_debug
获取 WebSocket 调试地址
浏览器启动后,访问:
http://127.0.0.1:9222/json
返回当前所有 Tab 的信息,其中 webSocketDebuggerUrl 是关键字段:
{
"id": "ABC123",
"title": "test page",
"webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/page/ABC123"
}
连接 DevTools 前端
devtools://devtools/bundled/devtools_app.html?ws=127.0.0.1:9222/devtools/page/ABC123
整体链路:--remote-debugging-port 开放 CDP 端口 → /json 获取 ws 地址 → DevTools 前端通过 ws 接入。
Node.js Hook 三件套
在 Node 程序里注入以下 hook 可以拦截运行时数据流。
Hook JSON.parse(记录解析数据)
const fs = require('fs');
const _parse = JSON.parse;
JSON.parse = function (text, reviver) {
const result = _parse.call(this, text, reviver);
// 只保存含 "raw" key 的对象
if (result && typeof result === 'object' && 'raw' in result) {
fs.appendFileSync('./json_log.txt',
JSON.stringify({ time: Date.now(), data: result }) + '\n');
}
return result;
};
过滤条件也可以改为 /"raw"\s*:/.test(text) 在原始字符串层面筛选,减少反序列化开销。
Hook TextDecoder.decode(截获二进制转字符串)
const { TextDecoder } = require('util');
const _decode = TextDecoder.prototype.decode;
TextDecoder.prototype.decode = function (input, options) {
const result = _decode.call(this, input, options);
console.log('[TextDecoder]', result);
return result;
};
适合抓 WebSocket 二进制帧、CDP 协议数据等场景。注意 Buffer.toString('utf-8') 走的是另一条路径,需要单独 hook Buffer.prototype.toString。
Hook AES 加密(抓密钥与明文)
const crypto = require('crypto');
const _createCipheriv = crypto.createCipheriv;
crypto.createCipheriv = function (algorithm, key, iv, options) {
console.log('[AES key]', {
algorithm,
key: key?.toString?.('hex'),
iv: iv?.toString?.('hex')
});
const cipher = _createCipheriv.call(this, algorithm, key, iv, options);
const _update = cipher.update;
cipher.update = function (data) {
console.log('[AES plaintext]', data?.toString?.() ?? data);
return _update.apply(this, arguments);
};
return cipher;
};
Hook createDecipheriv 的结构完全对称,可以抓解密后的明文。
注意事项
JSON.parse被局部引用绕过时(const p = JSON.parse; p(...)),改global.JSON.parse更彻底- 大流量场景建议加过滤条件(
text.length < 5000)避免日志刷屏 - Node.js 版本 >= 11 才有全局
TextDecoder,旧版用require('util').TextDecoder
