目录
Hook定义
Hook 技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权
这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递
简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。
在 js 中,系统程序可以指浏览器API,也可以指代码中实现的一些方法等
Hook 步骤
1、寻找 hook 点
2、编写 hook 逻辑
3、调试
函数 hook 公式:
old_func = func
func = function(argument){
my task;
return old_func .apply(argument)
}
func.prototype..... = .......
func :要hook的函数
对象中属性 hook 公式:
old_attr = obj.attr
Object.defineProperty(obj, 'attr', {
get: function() {
console.log(cookie_cache);
return old_attr
},
set: function(val) {
return ......
}
hook cookie
Object.defineProperty(document, 'cookie', {
get: function(){
debugger;
return;
},
set: function(val){
debugger;
return;
}
})
(function () {
'use strict';
var cookieTemp = '';
Object.defineProperty(document, 'cookie', {
set: function (val) {
if (val.indexOf('UN_distincatid') != -1) {
debugger;
}
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
},
get: function () {
return cookieTemp;
},
});
})();
在 Network 请求列表后面回溯,找到请求的位置 request
Object.defineProperty(document, 'cookie', {
set: function(cookie){
if (cookie.indexOf('RM4hZBv0dDon443M') != -1){
debugger;
}
return cookie;
}
})
页面一刷新,注入代码就会失效,可以在刷新之前找个断点断住,然后注入代码
成功 hook 住之后,按 F8 往后走,发现 cookie 生成的时候,这个时候在调用栈里回溯到上一层
然后再具体找到 cookie 生成的地方
hook eval
eval_bk = eval
eval = function(val){
debugger;
return eval_bk(val)
}
eval.toString = function(){
return "function eval() { [native code] }"
}
js hook目的是找到函数入口以及一些参数变化,便于分析js逻辑
Hook 插件:油猴脚本
Tampermonkey
// ==UserScript==
// @name Hook global
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author 悦来客栈的老板+妄为写代码+萌木盖
// @include *
// @grant none
// @run-at document-start
// ==/UserScript==
(function() {
'use strict';
//全局变量 监控
var t = window._t;
var window_flag = '_t';
var window_value = window[window_flag];
Object.defineProperty(window, window_flag, {
get: function() {
console.log('Getting window._t',window_value);
return t;
},
set: function(val) {
console.log('Setting window._t', val);
debugger;
t = val;
return t;
}
});
})();
hook的关键代码:@run-at document-start
意思为脚本将尽快注入。
还一个主要函数是defineProperty
他监控函数值,set该值和get该值都会调用这里面的两个方法。
此脚本是针对一号店的登录页面,其他网站需根据想监控的数据改对象名和变量值
原型链 hook
String.prototype.split_bk = String.prototype.split;
String.prototype.split = function(val){
str = this.toString()
debugger;
return str.split_bk(val)
}
逻辑正常需要返回 split_bk
XMLHttpRequest.protorype.setRequestHeader = function(){
degugger;
}
a = new XMLHttpRequest()
a.setRequestHeader
hreders hook
(function () {
var org = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
if (key == 'keys') {
debugger;
}
return org.apply(this, arguments);
};
})();
json hook
//将 JavaScript 值转换为 JSON 字符串
(function() {
var stringify = JSON.stringify;
JSON.stringify = function(params) {
console.log("Hook JSON.stringify ——> ", params);
debugger;
return stringify(params);
}
})();
// 将字符串解析成对象,多用于返回加密数据
(function() {
var parse = JSON.parse;
JSON.parse = function(params) {
console.log("Hook JSON.parse ——> ", params);
debugger;
return parse(params);
}
})();
绕过检测方法
(function() {
if (window.__cr_eval) return
window.__cr_eval = window.eval
var myeval = function (src) {
console.log("================ eval begin: length=" + src.length + ",caller=" + (myeval.caller && myeval.caller.name) + " ===============")
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 })
console.log(">>>>>>>>>>>>>> eval injected: " + document.location + " <<<<<<<<<<<<<<<<<<<")
})();
(function() {
if (window.__cr_fun) return
window.__cr_fun = window.Function
var myfun = function () {
var args = Array.prototype.slice.call(arguments, 0, -1).join(","), src = arguments[arguments.length - 1]
console.log("================ Function begin: args=" + args + ", length=" + src.length + ",caller=" + (myfun.caller && myfun.caller.name) + " ===============")
console.log(src);
console.log("================ Function end ================")
return window.__cr_fun.apply(this, arguments)
}
myfun.toString = function() { return window.__cr_fun + "" } // 小花招
Object.defineProperty(window, 'Function', { value: myfun })
console.log(">>>>>>>>>>>>>> Function injected: " + document.location + " <<<<<<<<<<<<<<<<<<<")
})();
绕过 hook 检测方法
// 防止检测
// hook alert 防检测
alert.toString = function () {return "function alert() { [native code] }"}
// hook setInterval 防检测
setInterval.toString = function () {
return "function setInterval() { [native code] }"
}