Files
hello_js_reverse_skill/references/hook-techniques.md
T
白夜 fb14cf7916 refactor: 将文件从子目录提升到仓库根目录
所有文件从 hello_js_reverse_skill/ 子目录移至仓库根目录,
使项目结构更清晰,便于作为 Skill 直接引用。

Made-with: Cursor
2026-03-18 22:55:27 +08:00

12 KiB
Raw Blame History

JS Hook 技术大全

概述

Hook 是 JS 逆向中最核心的技术之一。通过劫持/拦截 JS 原生函数或对象属性,可以捕获加密函数的 输入输出、Cookie 的生成过程、网络请求的参数构造等关键信息。

注入方式

通过 MCP 注入(推荐)

[js-reverse] inject_before_load(script=HookScript)
→ 在页面脚本加载前注入,确保 Hook 在目标代码之前生效

[js-reverse] evaluate_script(function=HookScript)
→ 在当前页面上下文执行,适合页面已加载后的动态注入

通过浏览器控制台注入

在 chrome-devtools MCP 中使用:

[chrome-devtools] evaluate_script(function=HookScript)

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 注入最佳实践

  1. 使用 inject_before_load:确保 Hook 在目标代码之前生效
  2. 使用 console.log 输出:通过 list_console_messages 收集结果
  3. 使用 console.trace:在关键点输出调用栈
  4. 避免覆写原型链的 toString:防止被反检测代码发现
  5. 使用 Proxy 代替直接覆写:更隐蔽,不改变 typeof 结果