特别声明:本公众号文章只作为学术研究,不用于其它不法用途;如有侵权请联系作者删除。
Hook 是一种钩子技术,在系统没有调用函数之前,钩子程序就先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,也可以强制结束消息的传递。简单来说,修改原有的 JS 代码就是 Hook。
Hook 技术之所以能够实现有两个条件:
1、客户端拥有JS的最高解释权,可以决定在任何时候注入JS,而服务器无法阻止或干预。服务端只能通过检测和混淆的手段,另 Hook 难度加大,但是无法直接阻止。
2、除了上面的必要条件之外,还有一个条件。就是 JS 是一种弱类型语言,同一个变量可以多次定义、根据需要进行不同的赋值,而这种情况如果在其他强类型语言中则可能会报错,导致代码无法执行。js 的这种特性,为我们 Hook 代码提供了便利。
Hook步骤:
1、寻找hook的点
2、编写hook逻辑
3、调试
注:最常用的是hook cookie response open 表单
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 === "value") {debugger;}return headerCache.apply(this, arguments);};
})();
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("value") !== -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 无限 Debugger
(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 WebSocket
(function () {let sendCache = WebSocket.prototype.send;WebSocket.prototype.send = function (data) {console.info("Hook WebSocket send => ", data);return sendCache(data);};
})();
Hook console
(function () {let consoleCache = console.log;console.log = function (msg) {consoleCache("Hook console.log =>", msg);if(msg === "value") {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 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 === "value") {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);};
})();
原创 Dang Python爬虫大数据可视化