JS Hook
什么是 Hook?
Hook 中文译为钩子,在程序中可以将其理解为“劫持”,我们可以通过 Hook 技术来劫持某个对象,把这个对象的程序拉出来替换成我们自己改写的代码片段,修改参数或替换返回值,从而控制它与其他对象的交互。
通俗来讲,Hook 其实就是拦路打劫,马邦德带着老婆,出了城,吃着火锅,还唱着歌,突然就被麻匪劫了,张麻子劫下县长马邦德的火车,摇身一变化身县长,带着手下赶赴鹅城上任。Hook 的过程,就是张麻子顶替马邦德的过程。
注意
收录的 Hook 脚本有限,若需要 Hook 其他函数,可参考 MDN Web API (opens new window) 自行编写。
# Hook Cookie
警告
不推荐方法二,部分特性可能正准备或者已经从相关的 web 标准中移除,参考文档:MDN (opens new window)
(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;
}
});
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(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;
});
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
// Make sure to add code blocks to your code group
# 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);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 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);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
(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);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
(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);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
(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();
};
})();
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
// Make sure to add code blocks to your code group
# 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);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 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);
}
});
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Hook JSON.stringify
(function () {
let stringifyCache = JSON.stringify;
JSON.stringify = function (params) {
console.log("Hook JSON.stringify => ", params);
debugger;
return stringifyCache(params);
};
})();
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# Hook JSON.parse
(function () {
let parseCache = JSON.parse;
JSON.parse = function (params) {
console.log("Hook JSON.parse => ", params);
debugger;
return parseCache(params);
};
})();
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 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();
};
})();
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# Hook WebSocket
(function () {
let sendCache = WebSocket.prototype.send;
WebSocket.prototype.send = function (data) {
console.info("Hook WebSocket send => ", data);
return sendCache(data);
};
})();
1
2
3
4
5
6
7
2
3
4
5
6
7
# 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)
};
})();
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# Hook console
(function () {
let consoleCache = console.log;
console.log = function (msg) {
consoleCache("Hook console.log =>", msg);
if(msg === "spiderapi.cn") {
debugger;
}
consoleCache(msg);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 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();
};
})();
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# Hook onbeforeunload
提示
onbeforeunload 事件在即将离开当前页面(刷新或关闭)时触发。Hook 此事件可阻断跳转,使其留在当前页面,通常用来应对网站打开 F12 就跳转页面的情况。
(function () {
window.onbeforeunload = function () {
console.log("Hook window.onbeforeunload.");
debugger;
return false;
};
})();
1
2
3
4
5
6
7
2
3
4
5
6
7
# 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);
};
})();
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# Hook Canvas
(function () {
let createElementCache = document.createElement;
document.createElement = function (tagName) {
console.info("Hook createElement tagName => ", tagName);
if(tagName === "canvas") {
debugger;
}
return createElementCache(tagName);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Hook createElement
(function () {
let createElementCache = document.createElement;
document.createElement = function (tagName) {
console.info("Hook createElement tagName => ", tagName);
if(tagName === "div") {
debugger;
}
return createElementCache(tagName);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# Hook getElementById
(function () {
let getElementByIdCache = document.getElementById;
document.getElementById = function (id) {
console.info("Hook getElementById id => ", id);
if (id === "spiderapi") {
debugger;
}
return getElementByIdCache(id);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 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);
};
})();
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 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);
};
})();
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 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);
};
})();
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 清除定时器
for (let i = 1; i < 99999; i++) window.clearInterval(i);
1
# Hook 固定随机变量
提示
来源于公众号:y小白的笔记 (opens new window)
(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;
}
})();
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# Hook 通用模板
(function () {
let oldFunc = func;
func = function (arguments) {
console.log(arguments);
return oldFunc.apply(arguments);
};
})();
1
2
3
4
5
6
7
2
3
4
5
6
7
帮助我们改善此页 (opens new window)
上次更新: 2024/10/17, 09:54:53