在 JS逆向时,首先需要做的就是定位加密参数的生成位置,然而在大量的 JS 中找到它不是很容易。在定位过程中,经常用到的一个技术就是 hook
技术,今天分享几个可以快速定位 JS 逆向加密参数的通用 hook
脚本。
油猴脚本框架
以下所有的脚本都要放到油猴脚本中使用,为了简化代码,这里先给出油猴脚本的框架,后续在进行 hook
的时候,只需要在框架中添加相应的 hook
代码即可。
// ==UserScript==
// @name demo
// @namespace Violentmonkey Scripts
// @match https://xxxx.xxxx-xxxx.com/*
// @grant none
// @version 1.0
// @author -
// @description 2025/2/25 21:20:14
// @run-at document-start
// ==/UserScript==
(function () {
//这里添加所需的 hook 代码
})();
别忘了修改上面的 @match
注释中的网址,此网址是 hook
脚本运行的网站,例如想要 hook 百度,填写 // @match https://www.baidu.com/*
即可。可以按需修改其他注释,但是 @run-at
一定要是 document-start
,这样才可以在网页加载前执行 hook
代码,hook
才能正常生效。
定位 json 序列化反序列化
json
数据是在逆向中经常遇到的,分享一个 hook
json
序列化和反序列化过程的脚本,可以在遇到请求和响应都是 json 数据的情况下快速定位 json
的序列化和反序列化的位置。
// Hook JSON.stringify
const originalStringify = JSON.stringify;
JSON.stringify = function(params) {
console.log("[Hook] JSON.stringify 参数:", params);
// 检测关键加密参数(如token、sign等)
if (typeof params === 'object' && params !== null) {
if ('encryptedData'in params || 'token'in params) {
debugger; // 触发断点
}
}
return originalStringify.apply(this, arguments);
};
// Hook JSON.parse
const originalParse = JSON.parse;
JSON.parse = function(text) {
console.log("[Hook] JSON.parse 输入数据:", text);
// 检测解密后的响应数据
if (typeof text === 'string' && text.includes('{')) {
try {
const parsed = originalParse(text);
if ('data'in parsed && parsed.data.length > 100) {
debugger; // 触发断点
}
} catch (e) {}
}
return originalParse.apply(this, arguments);
};
在请求和响应的时候都会打印出对应的数据,这个时候如果想要打断点的话,直接点击图片上的蓝色脚本在 hook
代码中打断点即可,向上查找调用栈即可找到 json
数据生成的位置。
定位 cookie 生成和读取
cookie
在逆向中也经常遇到,一般情况下会在本地通过 JS 生成一段 cookie
,提交请求的时候发送给服务端验证,如果验证不通过,则拒绝。这个时候往往要先定位特定的 cookie
是在哪里生成的。
// ====== 核心:重写 document.cookie 的 getter/setter ======
const cookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') || {
configurable: true,
enumerable: true
};
Object.defineProperty(Document.prototype, 'cookie', {
configurable: cookieDesc.configurable,
enumerable: cookieDesc.enumerable,
get: function() {
const cookies = cookieDesc.get ? cookieDesc.get.call(this) : this._cookie || '';
// 监控所有读取操作
if (/(token|session|auth)/i.test(cookies)) {
console.log('[Cookie Get]', cookies);
}
return cookies;
},
set: function(value) {
// 监控所有写入操作
console.log('[Cookie Set]', value);
if (/(token=|session=|sign=)/i.test(value)) {
console.trace('关键Cookie设置');
}
return cookieDesc.set ? cookieDesc.set.call(this, value) : (this._cookie = value);
}
});
手动获取 token
并且设置 token
,可以看到均正常 hook
到了 cookie
操作并且打印了日志。
定位 eval 执行代码
eval
也是 JS逆向中常用的方式,将代码进行混淆加密后转成字符串形式,在运行时使用 eval
动态的加载并执行,这时可以通过 hook
eval
函数的方式来定位动态加载的代码。
// 配置检测关键词(支持正则表达式)
const TARGET_PATTERN = /login|encrypt|signature/; // ← 修改这里
// 保存原生eval
const _nativeEval = window.eval;
// 重定义eval
window.eval = function(code) {
console.log("[eval监控] 捕获关键代码:\n", code.slice(0, 200) + "...");
// 调试触发逻辑
if (TARGET_PATTERN.test(code)) {
console.log("[eval监控] 捕获关键代码:\n", code.slice(0, 200) + "..."); // 截取前200
debugger; // 自动断点
}
// 执行原始eval
return _nativeEval.call(window, code);
};
// 伪装成原生eval
Object.defineProperty(window.eval, 'toString', {
value: () =>'function eval() { [native code] }',
writable: false,
configurable: false
});
可以看到,在执行 eval
的时候,会自动打印出所有 eval
执行的代码。
定位 Function 执行
Function
是 JS 中动态创建函数的一种方式,它是所有函数的构造函数。在 JS逆向中,很多时候会通过新建 Function
对象的方式来新建一个函数,从而在搜索某个加密函数的时候会搜索不到,因为它不是静态的,而是动态创建的。
它与 eval
的区别如下:
|
|
|
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Function
用法示例:
const code = 'return Date.now().toString(32)';
const getDynamicValue = new Function(code);
console.log(getDynamicValue()); // 输出类似 "1smn3v"
function hookFunction(func) {
returnnewProxy(func, {
construct(target, args) {
console.log(`拦截构造函数: ${target.name}, 参数: ${args}`);
returnReflect.construct(target, args);
},
apply(target, thisArg, args) {
console.log(`拦截函数调用: ${target.name}, 参数: ${args}`);
returnReflect.apply(target, thisArg, args);
}
});
}
// Hook 所有通过 Function 创建的函数
window.Function = hookFunction(window.Function);
使用代理的方式来拦截针对 Function
的调用,因为一般在使用 Function
的时候,会遇到比较强的校测,重写函数可能会被检测到,使用代理的隐蔽性更强,不会轻易被检测到。
定位 Ajax 请求
定位 Ajax
请求不使用 hook
,只需要在浏览器中添加 XHR
断点即可。
可以选择对所有的 Ajax
请求或者某个含有特定字符串的请求打断点,这样在请求发起时,会自动断在 send
函数上。
快速定位 cookie 生成请求
如果想要快速定位某个特定的 cookie
是从哪个请求生成的,其实也可以不用写 hook
代码,直接点点鼠标就可以了。
来看方法:
例如想要快速定位这个 sign
是在哪个请求生成的,网络请求有这么多,这个网站比较简单,如果是复杂的网站可能会达到几十个之多。
只需要在 cookie
上面点击右键,然后点显示涉及此 cookie
的请求,就会自动跳转到 network
选项卡,并且将 cookie
中有 sign
的请求全部都过滤出来,此时只要看第一个请求就可以了。
此方法其实就是 Chrome 自动添加了过滤条件,过滤出所有涉及到 cookie
的请求,对于快速定位 cookie
生成位置还是很有用的。
总结
以上就是本次分享的所有 hook
脚本,由于每个网站的加密内容都不同,大家可以根据上面的代码自行编写其他 hook 操作。
转自微信公众号
暂无评论内容