JS逆向Hook实战指南:快速定位加密参数与关键代码

110次阅读
没有评论

在 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 的上级函数,即为参数生成的核心逻辑。

JS 逆向 Hook 实战指南:快速定位加密参数与关键代码
JS 逆向 Hook 实战指南:快速定位加密参数与关键代码

三、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();
JS 逆向 Hook 实战指南:快速定位加密参数与关键代码

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 面板会自动过滤相关请求,第一个请求即为生成源头。

JS 逆向 Hook 实战指南:快速定位加密参数与关键代码
JS 逆向 Hook 实战指南:快速定位加密参数与关键代码

五、动态代码 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
});
JS 逆向 Hook 实战指南:快速定位加密参数与关键代码

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();
JS 逆向 Hook 实战指南:快速定位加密参数与关键代码

六、Ajax 断点:无需代码定位请求

简单场景无需写 Hook 脚本,Chrome 自带 XHR 断点功能:在「Sources」→「XHR/ Fetch Breakpoints」中点击「+」,输入请求 URL 关键词(如/api/login),请求触发时会自动断点。

JS 逆向 Hook 实战指南:快速定位加密参数与关键代码

七、实战总结:Hook 技术核心原则

  • 前置执行 :所有 Hook 代码必须在页面脚本加载前运行(油猴document-start 或注入脚本);
  • 关键词精准:断点条件尽量用目标网站的实际参数名(如 sign、token),减少无效断点;
  • 隐蔽性:重写函数后需伪装原生特性(如 toString 方法),避免被反爬检测;
  • 调用栈追溯:断点触发后,通过 Call Stack 向上找最接近业务逻辑的函数,而非底层方法。

这些脚本经过多个逆向项目验证,能解决 80% 的参数定位问题。但实战中需灵活调整,比如遇到混淆代码时,可结合 AST 反混淆工具再用 Hook 定位。你在逆向中还遇到过哪些 Hook 难题?欢迎在评论区交流。

正文完
 0
Fr2ed0m
版权声明:本站原创文章,由 Fr2ed0m 于2025-11-25发表,共计4647字。
转载说明:Unless otherwise specified, all articles are published by cc-4.0 protocol. Please indicate the source of reprint.
评论(没有评论)