JS Hook

什么是 Hook?

Hook 中文译为钩子,在程序中可以将其理解为“劫持”,我们可以通过 Hook 技术来劫持某个对象,把这个对象的程序拉出来替换成我们自己改写的代码片段,修改参数或替换返回值,从而控制它与其他对象的交互。

通俗来讲,Hook 其实就是拦路打劫,马邦德带着老婆,出了城,吃着火锅,还唱着歌,突然就被麻匪劫了,张麻子劫下县长马邦德的火车,摇身一变化身县长,带着手下赶赴鹅城上任。Hook 的过程,就是张麻子顶替马邦德的过程。

Hook Cookie

(function () {
    let cookieCache = "";
    Object.defineProperty(document, "cookie", {
        set: function (val) {
            console.log("Hook set cookie => ", val);
            if (val.indexOf("spiderapi.cn") !== -1) {
                debugger;
            }
            cookieCache = val;
            return val;
        },
        get: function () {
            return cookieCache;
        }
    });
})();
(function () {
    let cookieCache = document.cookie.__lookupSetter__("cookie");
    document.__defineSetter__("cookie", function (val) {
        console.log("Hook set cookie => ", val);
        if (val.indexOf("spiderapi.cn") !== -1) {
            debugger;
        }
        cookieCache = val;
    });
    document.__defineGetter__("cookie", function () {
        return cookieCache;
    });
})();

Hook Request Header

(function () {
    let headerCache = window.XMLHttpRequest.prototype.setRequestHeader;
    window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
        console.log("Hook set header %s => %s", key, value);
        if (key === "spiderapi.cn") {
            debugger;
        }
        return headerCache.apply(this, arguments);
    };
})();

Hook 无限 Debugger

注意

Firefox、Firefox Developer Edition 浏览器从 121 版本开始,添加了 Pause on debugger statement(在调试器语句上暂停)功能,默认勾选,取消勾选即可轻松绕过无限 debugger。具体详见更新日志 (opens new window)

提示

无限 debugger 生成的形式比较多样,常见于构造函数、定时器和 eval 里,可根据实际场景进行调整。

(function () {
    let constructorCache = Function.prototype.constructor;
    Function.prototype.constructor = function (string) {
        if (string === "debugger") {
            console.log("Hook constructor debugger!");
            return function () {};
        }
        return constructorCache(string);
    };
})();
(function () {
    let setIntervalCache = setInterval;
    setInterval = function (func, delay) {
        if (func.toString().indexOf("debugger") !== -1) {
            console.log("Hook setInterval debugger!");
            return function () {};
        }
        return setIntervalCache(func, delay);
    };
})();
(function () {
    let setTimeoutCache = setTimeout;
    setTimeout = function (func, delay) {
        if (func.toString().indexOf("debugger") !== -1) {
            console.log("Hook setTimeout debugger!");
            return function () {};
        }
        return setTimeoutCache(func, delay);
    };
})();
(function () {
    let evalCache = window.eval;
    window.eval = function (string) {
        if (string.includes("debugger")) {
            console.log("Hook eval debugger!");
        }
        return evalCache(string.replace(/debugger\s*;?/g, ""));
    };
    window.eval.toString = function () {
        return evalCache.toString();
    };
})();

Hook XHR

(function () {
    let openCache = window.XMLHttpRequest.prototype.open;
    window.XMLHttpRequest.prototype.open = function (method, url) {
        console.log("Hook xhr method => %s, url => %s", method, url);
        if (url.indexOf("spiderapi.cn") !== -1) {
            debugger;
        }
        return openCache.apply(this, arguments);
    };
})();

Hook fetch

(function () {
    let fetchCache = Object.getOwnPropertyDescriptor(window, "fetch");
    Object.defineProperty(window, "fetch", {
        value: function (url) {
            console.log("Hook fetch url => ", url);
            debugger;
            return fetchCache.value.apply(this, arguments);
        }
    });
})();

Hook JSON.stringify

(function () {
    let stringifyCache = JSON.stringify;
    JSON.stringify = function (params) {
        console.log("Hook JSON.stringify => ", params);
        debugger;
        return stringifyCache(params);
    };
})();

Hook JSON.parse

(function () {
    let parseCache = JSON.parse;
    JSON.parse = function (params) {
        console.log("Hook JSON.parse => ", params);
        debugger;
        return parseCache(params);
    };
})();

Hook Function

提示

以下代码执行后,所有的函数操作都会在控制台打印输出将要执行的 JS 源码。

(function () {
    let FunctionCache = window.Function;
    let newFunction = function () {
        let src = arguments[arguments.length - 1];
        console.log("Hook Function => ", src);
        debugger;
        return FunctionCache.apply(this, arguments);
    };
    newFunction.toString = function () {
        return FunctionCache.toString();
    };
})();

Hook WebSocket

(function () {
    let sendCache = WebSocket.prototype.send;
    WebSocket.prototype.send = function (data) {
        console.info("Hook WebSocket send => ", data);
        return sendCache(data);
    };
})();

Hook String.prototype.split

(function () {
    String.prototype.splitCache = String.prototype.split;
    String.prototype.split = function (separator, limit) {
        console.log("Hook String.prototype.split separator => %s, limit => %s", separator, limit);
        let str = this.toString();
        if(str.includes("spiderapi.cn")) {
            debugger;
        }
        return str.splitCache(separator, limit)
    };
})();

Hook console

(function () {
    let consoleCache = console.log;
    console.log = function (msg) {
        consoleCache("Hook console.log =>", msg);
        if(msg === "spiderapi.cn") {
            debugger;
        }
        consoleCache(msg);
    };
})();

Hook eval

(function () {
    let evalCache = window.eval;
    window.eval = function (string) {
        console.log("Hook eval =>", string);
        debugger;
        return evalCache(string);
    };
    window.eval.toString = function () {
        return evalCache.toString();
    };
})();

Hook onbeforeunload

提示

onbeforeunload 事件在即将离开当前页面(刷新或关闭)时触发。Hook 此事件可阻断跳转,使其留在当前页面,通常用来应对网站打开 F12 就跳转页面的情况。

(function () {
    window.onbeforeunload = function () {
        console.log("Hook window.onbeforeunload.");
        debugger;
        return false;
    };
})();

Hook RegExp

(function () {
    let RegExpCache = RegExp;
    RegExp = function (pattern, flags) {
        console.log("Hook RegExp pattern => %s, flags => %s", pattern, flags);
        debugger;
        return RegExpCache(pattern, flags);
    };
})();

Hook Canvas

(function () {
    let createElementCache = document.createElement;
    document.createElement = function (tagName) {
        console.info("Hook createElement tagName => ", tagName);
        if(tagName === "canvas") {
            debugger;
        }
        return createElementCache(tagName);
    };
})();

Hook createElement

(function () {
    let createElementCache = document.createElement;
    document.createElement = function (tagName) {
        console.info("Hook createElement tagName => ", tagName);
        if(tagName === "div") {
            debugger;
        }
        return createElementCache(tagName);
    };
})();

Hook getElementById

(function () {
    let getElementByIdCache = document.getElementById;
    document.getElementById = function (id) {
        console.info("Hook getElementById id => ", id);
        if (id === "spiderapi") {
            debugger;
        }
        return getElementByIdCache(id);
    };
})();

Hook setAttribute

(function () {
    let setAttributeCache = window.Element.prototype.setAttribute;
    window.Element.prototype.setAttribute = function (name, value) {
        console.info("Hook setAttribute name => %s, value => %s", name, value);
        if (name === "spiderapi") {
            debugger;
        }
        return setAttributeCache(name, value);
    };
})();

Hook setInterval

(function () {
    let setIntervalCache = setInterval;
    setInterval = function (func, delay) {
        console.log("Hook setInterval func => %s, delay => %s", func, delay);
        debugger;
        return setIntervalCache(func, delay);
    };
})();

Hook setTimeout

(function () {
    let setTimeoutCache = setTimeout;
    setTimeout = function (func, delay) {
        console.log("Hook setTimeout func => %s, delay => %s", func, delay);
        debugger;
        return setTimeoutCache(func, delay);
    };
})();

清除定时器

for (let i = 1; i < 99999; i++) window.clearInterval(i);

Hook 固定随机变量

(function () {
    Date.now = function now() { return 1661986251253 };
    Date.parse = function () { return 1661986251253 };
    Date.prototype.valueOf = function () { return 1661986251253 };
    Date.prototype.getTime = function () { return 1661986251253 };
    Date.prototype.toString = function () { return 1661986251253 };
    Performance.prototype.now = function now(){ return Number('1661986251253'.slice(8))}

    Math.random = function random() { return 0.08636862211354912 };
    window.crypto.getRandomValues = function getRandomValues(array32, ...args){
        return array32;
    }
})();

Hook 通用模板

(function () {
    let oldFunc = func;
    func = function (arguments) {
        console.log(arguments);
        return oldFunc.apply(arguments);
    };
})();

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星哲最开心

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值