JsHook入门
本文旨在梳理了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] }`
}