Hook定义
Hook 技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权
这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递
简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。
在 js 中,系统程序可以指浏览器API,也可以指代码中实现的一些方法等
Hook 步骤
1、寻找 hook 点
2、编写 hook 逻辑
3、调试
注:最常用的是hook cookie response open 表单
常见hook脚本
COOKIE
(function() {
//严谨模式 检查所有错误
'use strict';
var cookieTemp = "";
Object.defineProperty(document, 'cookie', {
set: function(val) {
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
},
get: function()
{
return cookieTemp;
}
});
})();
HEADER
(function () {
var org = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
if (key == 'Authorization') {
debugger;
}
return org.apply(this, arguments);
};
})();
URL / XHR
(function () {
var open = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url, async) {
if (url.indexOf("login") != -1) {
debugger;
}
return open.apply(this, arguments);
};
})();
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);
}
});
})();
EVAL
(function() {
var eval_ = eval;
// 重写 eval
var myeval = function(src) {
if(src.includes('debugger')){
src = src.replace(/debugger\s*;?/g, '')
}
return eval_(src);
}
var myeval_ = myeval.bind(null);
myeval_.toString = function(){
return eval_.toString();
};
Object.defineProperty(window, 'eval', {
value: myeval_
});
})();
var a=eval+""
var _eval=eval
eval=function(arg){
console.log(arg)
return _eval(arg)
}
eval.toString=function(){return "function eval() { [native code] }"}
var _old=Function.prototype.toString.call
Function.prototype.toString.call=function(arg){
if(arg==eval)
return "function eval() { [native code] }"
return _old(arg);
}
console.log(Function.prototype.toString.call(eval))
JSON
// JSON.stringify ------------------------------------------
(function() {
var stringify = JSON.stringify;
JSON.stringify = function(params) {
console.log("Hook JSON.stringify ——> ", params);
debugger;
return stringify(params);
}
})();
// JSON.parse ------------------------------------------
(function() {
var parse = JSON.parse;
JSON.parse = function(params) {
console.log("Hook JSON.parse ——> ", params);
debugger;
return parse(params);
}
})();
无限 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.prototype.constructor_bk = Function.prototype.constructor
Function.prototype.constructor = function(){
if (arguments[0]=="debugger"){
return function () {};
}else{
return Function.prototype.constructor_bk.apply(this, arguments)
}
}
WEBSOCKET
(function () {
let sendCache = WebSocket.prototype.send;
WebSocket.prototype.send = function (data) {
console.info("Hook WebSocket send => ", data);
return sendCache(data);
};
})();
CONSOLE
(function () {
let consoleCache = console.log;
console.log = function (msg) {
consoleCache("Hook console.log =>", msg);
if(msg === "value") {
debugger;
}
consoleCache(msg);
};
})();
CREATEELEMENT
(function () {
let createElementCache = document.createElement;
document.createElement = function (tagName) {
console.info("Hook createElement tagName => ", tagName);
if(tagName === "div") {
debugger;
}
return createElementCache(tagName);
};
})();
GETELEMENTBYID
(function () {
let getElementByIdCache = document.getElementById;
document.getElementById = function (id) {
console.info("Hook getElementById id => ", id);
if (id === "spiderapi") {
debugger;
}
return getElementByIdCache(id);
};
})();
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);
};
})();
SETINTERVAL / SETTIMEOUT
(function () {
let setIntervalCache = setInterval;
setInterval = function (func, delay) {
console.log("Hook setInterval func => %s, delay => %s", func, delay);
debugger;
return setIntervalCache(func, delay);
};
})();
(function () {
let setTimeoutCache = setTimeout;
setTimeout = function (func, delay) {
console.log("Hook setTimeout func => %s, delay => %s", func, delay);
debugger;
return setTimeoutCache(func, delay);
};
})();
原型链
// 备份原函数,并添加至原型链
String.prototype.split_ = String.prototype.split;
// hook split 方法
String.prototype.split = function(val){
str = this.toString();
debugger;
return str.split_(val);
};
// 过检测
String.prototype.split.toString = function (){
return "function split() { [native code] }";
}
- hook 正则 test 方法,使其总是返回 true
RegExp.prototype.test_ = RegExp.prototype.test; RegExp.prototype.test = function (val) { return true; }; RegExp.prototype.test.toString = function () { return "function test() { [native code] }" }