爬虫逆向学习(三):Hook让你快速定位网站逆向疑难杂症
Hook保姆级教程
Hook定义
Hook 技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递。简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。
hook的目的
现在很多网站js都使用了混淆,我们没法直接通过查找的方式定位参数生成位置,js hook能帮助我们找到函数入口以及一些参数变化,便于分析js逻辑,对于爬虫只借助其寻找函数入口。
Hook使用步骤
- 明确要定位的参数类型
- 编写hook逻辑
- 调试代码确定hook成功
Hook函数公式
old_func = funcfunc =function(argument){
mytask;
returnold_func.apply(argument)
}
func.prototype.....= .......
// func :要hook的函数
常用Hook方式
对象中属性
old_attr = obj.attrObject.defineProperty(obj, 'attr', {
get: function() {
console.log(cookie_cache);
return old_attr
},
set: function(val) {
return ......
}
eval/Function
# eval/Function
window.__cr_eval = window.eval
// 捕捉到debugger位置
var myeval = function (src) {
console.log("============ eval begin: length=" + src.length + ",caller=" + (myeval.caller && myeval.caller.name) + " ===============")
console.log(">>>>>>>>>>>> eval injected: " + document.location + " <<<<<<<<<<<<<<<<")
console.log(src);
console.log("============ eval end =============")
return window.__cr_eval(src)
}
// 会有一些反爬会识别是不是本机代码,这个地方是小花招本招,防止被识别
var _myeval = myeval.bind(null)
_myeval.toString = window.__cr_eval.toString
Object.defineProperty(window, 'eval', { value: myeval })
Cookie
// 捕捉window参数写入位置
(function() {
//document 为要hook的对象 这里是hook的cookie
var cookieTemp = "";
Object.defineProperty(document, 'cookie', {
//hook set方法也就是赋值的方法
set: function(val) {
//这样就可以快速给下面这个代码行下断点
//从而快速定位设置cookie的代码
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
debugger;
return val;
},
//hook get方法也就是取值的方法
get: function()
{
return cookieTemp;
}
});
})();
header 参数
//方式一:
var code = function(){
var org = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function(key,value){
if(key=='Authorization'){
debugger;
}
return org.apply(this,arguments);
}
}
var script = document.createElement('script');
script.textContent = '(' + code + ')()';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
// 方式二
(function () {
var org = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
if (key == 'Authorization') {
debugger;
}
return org.apply(this, arguments);
};
})();
关闭alert
var _alert=window.alert
window.alert = function() {
return true;
}
url
(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);
};
})();
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);
}
})();
Function
(function() {
// 保存原始方法
window.__cr_fun = window.Function;
// 重写 function
var myfun = function() {
var args = Array.prototype.slice.call(arguments, 0, -1).join(","),
src = arguments[arguments.length - 1];
console.log(src);
console.log("=============== Function end ===============");
debugger;
return window.__cr_fun.apply(this, arguments);
}
// 屏蔽js中对原生函数native属性的检测
myfun.toString = function() {
return window.__cr_fun + ""
}
Object.defineProperty(window, 'Function', {
value: myfun
});
})();
对象操作
如果想动态操作某个对象,可以参考下面这种方式
用途:将值与a对象的href进行网址动态拼接
a = {
'href': ""
}
var join_url;
Object.defineProperty(a, 'href', {
set: function(val) {
if (val.startsWith('http')) {
join_url = val;
} else {
let baseURL = new URL('');
baseURL.pathname = val;
join_url = baseURL.toString();
}
return join_url;
},
get: function()
{
return join_url;
}
});
本文来自博客园,作者:七夜魔手,转载请注明原文链接:https://www.cnblogs.com/ranbox/p/18461066