本文旨在梳理了JShook入门的一些概念原理及应用,后续内容会再补充
1.JsHook概念简介:
JsHook(JavaScript Hook)技术是一种在 JavaScript 环境中通过替换
、拦截
、修改
函数,来实现监控、替换、调试、篡改或扩展原有功能等目的。Hook 的核心是 “对目标函数的执行流程进行干预”,只要实现其中某一个功能,就可以称为 Hook。
逆向场景主要用于实现反调试
,监控代码执行流程实现补环境
等。
拦截:记录函数调用参数或返回值(不修改结果),这是 Hook
(监控型 Hook)
const originalLog = console.log;
console.log = function(...args) {
// 只记录调用,不修改参数和原逻辑
console.debug(`log被调用:`, args);
originalLog.apply(this, args); // 执行原函数
};
修改:这种 Hook 的核心是"干预函数的行为
结果
" 而非 “干预流程”。不改变函数的调用时机和基本执行流程,只在原函数执行过程中修改参数、返回值或执行逻辑。(篡改型 Hook)
// 原函数:计算两数之和
function add(a, b) {
return a + b;
}
// Hook:仅修改参数,不改变原函数的调用方式和执行逻辑
const originalAdd = add;
add = function(a, b) {
// 只修改参数(将输入值翻倍),不添加额外流程逻辑
const modifiedA = a * 2;
const modifiedB = b * 2;
// 调用原函数(保持原有执行逻辑)
return originalAdd(modifiedA, modifiedB);
};
// 调用时,用户感知不到Hook的存在,但结果已被修改
console.log(add(1, 2)); // 输出 6(实际计算的是 2 + 4)
替换:用自定义函数
完全替代
原函数(不再调用原逻辑),这同样是 Hook(替换型 Hook)
// 仅替换(完全覆盖)
setTimeout = function(callback, delay) {
// 不调用原setTimeout,完全用自定义逻辑替代
alert(`定时器被拦截,不会执行`);
};
2.常见的hook应用
hook cookie
拦截cookie对象下属性的赋值和取值,对Object方法不熟悉的可参考Object对象中的常用方法
(function () {
'use strict';
var cookieTemp = '';
Object.defineProperty(window, 'gdxidpyhxde', {
set: function (val) {
debugger;
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
},
get: function () {
return cookieTemp;
},
});
})();
hook Headers
(function () {
var org = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
if (key == 'Authorization') {
debugger;
}
return org.apply(this, arguments);
};
})();
hook 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);
};
})();
hook debugger
var _constructor = constructor;
Function.prototype.constructor = function(s) {
if ( s== "debugger") {
console.log(s);
return null;
}
return _constructor(s);
}
hook createElement
document.hookCreateElement = document.createElement;
document.createElement = function(tagName){
if(tagName === "a"){
debugger;
}
return document.hookCreateElement(tagName);
}
3.hook检测原理和保护
原生函数或自定义函数在被 Hook 前,有固定的特征(如toString()
结果、属性描述符等)。被 Hook 后,这些特征会发生变化
下面以toString检测为例子
检测原理
// 保存原始函数的特征(页面加载早期执行)
const _atob=atob;
atob=function (str){
console.log("atob正在被调用,入参为:",str)
result = atob(str)
console.log("返回的结果是:",result)
return result
}
// 检测时对比
function checkAtobHook() {
return atob.toString() === _atob;
}
// 测试:如果atob被Hook,会返回false
console.log(checkAtobHook());
如何防止检测
//修改atob.toString返回值 防止被检测
atob.toString=function (str){
return 'function atob() { [native code] }'
}
Function.prototype.toString =function (){
return `function ${this.name} { [native code] }`
}