菜鸟-创作你的创作

JS 逆向控制台 Hook 注入解析

下面给你一份 《JS 逆向控制台 Hook 注入解析》——最新、最清晰、适合做笔记或用作项目逆向分析参考的版本。


✅ JS 逆向控制台 Hook 注入解析

(完整思路 + 常用 Hook 技巧 + 防 Hook 对抗)

在前端逆向中,Hook(劫持)是最常见、最有效的手段之一,用于:


1️⃣ 什么是 Hook?

Hook 就是“修改某个原生函数,让我们能在它执行前/后插入自己的代码”。

例如劫持 console.log:

(function() {
    const oldLog = console.log;
    console.log = function(...args) {
        debugger;  // 打断点分析
        oldLog("Hook 捕获到 ->", ...args);
    };
})();


2️⃣ 常见控制台 Hook 类型


✔ 2.1 Hook console 系列

最常用,用来抓日志或逆向前端逻辑。

🔹 Hook 所有 console 输出:

['log','warn','error','info'].forEach(fn=>{
    const old = console[fn];
    console[fn] = function(...args){
        debugger;
        old.call(this, `[Hook ${fn}]`, ...args);
    }
});

用途:
✔ 定位关键变量
✔ 抓加密前/后参数
✔ 分析运行时的调用链


✔ 2.2 Hook XHR(XMLHttpRequest)

抓取 Ajax 请求中的参数(如 sign、token、timestamp)

(function() {
    const open = XMLHttpRequest.prototype.open;
    const send = XMLHttpRequest.prototype.send;

    XMLHttpRequest.prototype.open = function(method, url) {
        this._url = url;
        this._method = method;
        return open.apply(this, arguments);
    };

    XMLHttpRequest.prototype.send = function(body) {
        debugger;
        console.log("XHR Hook:", this._method, this._url, body);
        return send.apply(this, arguments);
    };
})();


✔ 2.3 Hook Fetch

前端大型项目基本都用 fetch。

const oldFetch = window.fetch;
window.fetch = async function(...args) {
    debugger;
    console.log("Fetch Hook ->", args[0], args[1]);
    const res = await oldFetch.apply(this, args);
    return res;
};


✔ 2.4 Hook WebSocket

抓实时加密通讯流(游戏、直播、加密应用常见)。

const OldWS = window.WebSocket;

window.WebSocket = function(url, protocols) {
    console.log("WebSocket Hook ->", url);
    const ws = new OldWS(url, protocols);

    ws.addEventListener("message", msg => {
        debugger;
        console.log("WS接收:", msg.data);
    });

    const oldSend = ws.send;
    ws.send = function(data) {
        debugger;
        console.log("WS发送:", data);
        return oldSend.call(ws, data);
    };

    return ws;
};


✔ 2.5 Hook Object.defineProperty(前端逆向常见加密点)

许多网站用 defineProperty 限制调试、隐藏变量,这可以 Hook。

const oldDefine = Object.defineProperty;
Object.defineProperty = function(obj, prop, desc) {
    console.log("Hook defineProperty ->", prop, desc);
    debugger;
    return oldDefine.call(this, obj, prop, desc);
}


✔ 2.6 Hook 原型链函数(抓取关键算法)

比如抓 Array.prototype.push:

const oldPush = Array.prototype.push;
Array.prototype.push = function(...args){
    debugger;
    console.log("Push Hook:", args);
    return oldPush.apply(this, args);
};

用途:
✔ 抓混淆代码中的数据构建过程
✔ 把隐藏变量“逼出来”


3️⃣ JS 逆向中的常用 Hook 思路


🧩 3.1 定位加密函数

观察:

Hook:

console.log
XHR / fetch
Object.defineProperty
Crypto API


🧩 3.2 跟踪运行流程

Hook:

Function.prototype.call
Function.prototype.apply
setTimeout / setInterval

极其强大:

(function(){
    const oldCall = Function.prototype.call;
    Function.prototype.call = function(...args){
        debugger;
        return oldCall.apply(this, args);
    }
})();

可以看到任何被调用的函数。


🧩 3.3 控制调试暂停

使用 debugger 自动中断:

console.log = function(...args){
    debugger;
    return oldLog.apply(this, args);
};

任何经过 console.log 的地方都会停下。


4️⃣ Hook 的加载方式


✔ 方式 1:浏览器控制台直接执行

最方便、最常用。


✔ 方式 2:CSP 受限,可以用 Snippet(Chrome Sources → Snippets)

绕过 CSP/XSS 限制。


✔ 方式 3:TamperMonkey(油猴)脚本注入

用于长期抓包逆向。


✔ 方式 4:Chrome DevTools Sniffer

使用:

sources → overrides → 替换目标 JS 文件


5️⃣ 反 Hook 对抗(网站常用)

网站常用反逆向技术:

例如:

console.log = function(){};
Object.defineProperty(console, "log", { writable: false });

解决:
→ 先 Hook defineProperty
→ 再 Hook console
→ 或在网页加载前用 Snippet 注入


6️⃣ 提供给你的万能 Hook 模板

一个 Hook 所有关键前端 API 的综合脚本:

(function() {
    // console
    ['log','warn','error','info'].forEach(fn=>{
        const old = console[fn];
        console[fn] = function(...args){
            debugger;
            old.call(this, `[Hook ${fn}]`, ...args);
        };
    });

    // XHR
    const open = XMLHttpRequest.prototype.open;
    const send = XMLHttpRequest.prototype.send;
    XMLHttpRequest.prototype.open = function(method, url) {
        this._url = url;
        return open.apply(this, arguments);
    };
    XMLHttpRequest.prototype.send = function(body) {
        debugger;
        console.log("XHR", this._url, body);
        return send.apply(this, arguments);
    };

    // fetch
    const oldFetch = window.fetch;
    window.fetch = async function(...args) {
        debugger;
        console.log("Fetch", args);
        return oldFetch.apply(this, args);
    };

    // WebSocket
    const OldWS = window.WebSocket;
    window.WebSocket = function(url) {
        console.log("WS Connect:", url);
        const ws = new OldWS(url);
        const oldSend = ws.send;
        ws.send = function(data) {
            debugger;
            console.log("WS Send:", data);
            return oldSend.call(ws, data);
        };
        return ws;
    };
})();

退出移动版