本文详细解析JavaScript中11种常用的Hook钩子技术,涵盖DOM操作、Cookie拦截、事件监听、AJAX拦截、函数替换、Header处理、URL监控、JSON序列化与解析、eval执行及Function构造等场景。通过具体示例代码,展示如何在JS逆向和油猴脚本开发中利用Hook技术监视或修改程序行为,帮助开发者掌握前端调试与数据抓包的核心技巧。
在前端JavaScript开发中,Hook(钩子)技术被频繁提及。所谓Hook,即钩子技术,指的是在程序运行期间,对特定方法进行重写,从而在原有方法执行前后插入自定义代码。无论是称为钩子、钩子机制、钩子函数还是Hook,它们指代的都是同一概念。
Windows系统基于事件驱动机制,整个系统通过消息传递实现。Hook作为一种特殊的消息处理机制,能够监视系统或进程中的各类事件消息,截获发往目标窗口的消息并进行处理。它常用于监视特定事件的发生以完成特定功能,例如屏幕取词、日志监视、键盘及鼠标输入截获等。
开发者常利用Hook技术来监视或修改程序行为。下文将介绍几种常用的Hook技术及其对应的示例代码。
1、DOM操作
在JS逆向及油猴脚本开发中,DOM操作是最常见的Hook方式之一。通过修改DOM元素的属性和样式,可以实现对网页的控制与修改。
// 修改DOM元素的属性
document.getElementById('elementId').setAttribute('attrName', 'attrValue');
// 修改DOM元素的样式
document.getElementById('elementId').style.property = 'value';2、Cookie操作
Cookie Hook主要用于定位Cookie中关键参数的生成位置。以下代码演示了当Cookie中匹配到__dfp关键字时,插入断点的逻辑:
(function () {
'use strict';
var cookieTemp = '';
Object.defineProperty(document, 'cookie', {
set: function (val) {
if (val.indexOf('__dfp') != -1) {
debugger;
}
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
},
get: function () {
return cookieTemp;
},
});
})();
(function () {
'use strict';
var org = document.cookie.__lookupSetter__('cookie');
document.__defineSetter__('cookie', function (cookie) {
if (cookie.indexOf('__dfp') != -1) {
debugger;
}
org = cookie;
});
document.__defineGetter__('cookie', function () {
return org;
});
})();3、事件监听操作
事件监听同样是JS逆向和油猴脚本中常用的Hook方式。通过监听网页上的事件,可以触发自定义的操作和行为。
// 监听按钮点击事件
document.getElementById('buttonId').addEventListener('click', function() {
// 自定义操作和行为
});4、AJAX拦截操作
AJAX拦截也是JS逆向和油猴脚本中常用的Hook方式。通过拦截网页上的AJAX请求,可以实现对数据的控制与修改。
// 拦截AJAX请求
XMLHttpRequest.prototype._send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
// 自定义操作和行为
this._send.apply(this, arguments);
};5、函数替换操作
函数替换也是JS逆向和油猴脚本中常用的Hook方式。通过替换网页上的函数,可以实现对函数的控制与修改。
// 替换原有函数
var originalFunction = window.functionName;
window.functionName = function() {
// 自定义操作和行为
originalFunction.apply(this, arguments);
};6、Header操作
Header Hook用于定位Header中关键参数的生成位置。以下代码演示了当Header中包含Authorization关键字时,插入断点的逻辑:
(function () {
var org = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
if (key == 'Authorization') {
debugger;
}
return org.apply(this, arguments);
};
})()7、URL操作
URL Hook用于定位请求URL中关键参数的生成位置。以下代码演示了当请求的URL里包含login关键字时,插入断点的逻辑:
(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);
};
})();8、JSON.stringify操作
JSON.stringify()方法用于将JavaScript值转换为JSON字符串。在某些站点的加密过程中可能会遇到此方法,以下代码演示了遇到JSON.stringify()时插入断点的逻辑:
(function() {
var stringify = JSON.stringify;
JSON.stringify = function(params) {
console.log("Hook JSON.stringify ——> ", params);
debugger;
return stringify(params);
}
})();9、JSON.parse操作
JSON.parse()方法用于将JSON字符串转换为对象。在某些站点的加密过程中可能会遇到此方法,以下代码演示了遇到JSON.parse()时插入断点的逻辑:
(function() {
var parse = JSON.parse;
JSON.parse = function(params) {
console.log("Hook JSON.parse ——> ", params);
debugger;
return parse(params);
}
})();10、eval操作
JavaScript的eval()函数用于计算JavaScript字符串,并将其作为脚本代码执行。如果参数是表达式,eval()将执行该表达式;如果参数是JavaScript语句,eval()将执行该语句。它常被用于动态执行JS。以下代码执行后,后续所有的eval()操作都会在控制台打印出将要执行的JS源码:
(function() {
// 保存原始方法
window.__cr_eval = window.eval;
// 重写 eval
var myeval = function(src) {
console.log(src);
console.log("=============== eval end ===============");
debugger;
return window.__cr_eval(src);
}
// 屏蔽 JS 中对原生函数 native 属性的检测
var _myeval = myeval.bind(null);
_myeval.toString = window.__cr_eval.toString;
Object.defineProperty(window, 'eval', {
value: _myeval
});
})();11、Function操作
以下代码执行后,所有的函数操作都会在控制台打印出将要执行的JS源码:
(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
});
})();12、总结
至此,关于JavaScript中11种常用Hook钩子技术及示例代码的介绍到此结束。如需了解更多JS常用的Hook技术内容,请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!