文章总结: 本文针对JS逆向中固定随机数易被检测导致死循环的问题,提出升级Hook方案。核心是采用伪随机数组重放或伪随机算法替代固定返回值,使结果确定且不重复,从而绕过反爬检测。该思路同样适用于固定时间。建议在逆向分析中使用此法提升Hook隐蔽性,并在数组越界时用原生函数兜底以防报错。 综合评分: 85 文章分类: 逆向分析,WEB安全,爬虫
JS调试技巧:如何让时间和随机数“听你指挥”?升级版!
原创
LLLibra146 LLLibra146
LLLibra146
2025年5月28日 08:02 北京
在小说阅读器读本章
去阅读
大家好,之前写过一篇JS调试技巧:如何让时间和随机数“听你指挥”?的文章,讲到了如何固定时间和随机数,让随机的结果变得固定。本篇文章分享一种升级版的方法,让固定方法不那么容易被发现。
固定随机数
上一篇文章中提到,使用 hook 方法固定随机数,如果只是单纯的固定随机数让其返回一个固定的值,在某些情况下容易被发现,一旦被检测到随机数的返回值固定不变,就会导致代码死循环或者报错。
猿人学 2024 新春题目就会检测随机数,如果我固定 0.5 的话,就会卡死浏览器,猜测应该是走了错误的分支。
这个时候,要如何让随机数的结果“固定”,但是又不“固定”呢?答案就是伪随机数。
伪随机数的生成有两种方式,一种是伪随机数数组,使用一个固定的数组来模拟,另一种就是伪随机算法。
伪随机数数组
伪随机数数组的实现方案有两种,一种是使用固定的随机数数组来模拟随机数,另一种就是使用伪随机数算法,来动态的计算随机数。一个是实时计算,另一个是提前计算然后存储起来,大同小异。
这里我使用固定的随机数数组来模拟伪随机数,首先看下之前的固定随机数的方案:
// 备份原函数
const originalRandom = Math.random;
// 重写为固定返回值
Math.random = function() {
return 0.123456789; // 替换为所需固定值
};
// 防止检测:伪装原生函数特征
Math.random.toString = function() {
return "function random() { [native code] }";
};
为了能获取一些随机数用于填充数组,要先修改上面的方法,新建一个数组来存储获取到的随机数,然后运行一遍程序,填充数组后再重放即可。
const originalRandom = Math.random;
let list = [];
Math.random = function () {
let value = originalRandom();
list.push(value);
return value;
};
执行上面的 hook,list 数组会被填充,获取 list 数组的值并保存下来。
const originalRandom = Math.random;
let list = [0.1, 0.2, 0.3, 0.4, 0.5];
let count = 0
Math.random = function () {
return list[count++];
};
修改 hook 代码后使用数组的值重放即可,后面无论如何调用随机数函数,都会获得一个固定的随机数序列。
这里会有一个问题,如果 hook 以后随机数调用的次数超出了数组的长度怎么办?
这个时候需要定义一个比较长的数组,或者使用后备方案,如果真的超出了,为了不报错就使用真实的随机数函数好了。
修改代码如下:
const originalRandom = Math.random;
let list = [0.1, 0.2, 0.3, 0.4, 0.5];
let count = 0
Math.random = function () {
return list[count++] || originalRandom();
};
在数组越界后调用真实的随机数即可。
伪随机算法
如果不想保存一个很大的数组,可以考虑使用伪随机算法,伪随机算法可以保证对于同一个种子,输出相同的随机数。举个例子:
function createXorshift32(seed) {
var state = typeof seed === 'number' ? seed : 1;
returnfunction() {
var x = state;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
state = x;
return (x >>> 0) / 0xFFFFFFFF; // 转为 [0, 1)
};
}
// 使用示例
var xorshift = createXorshift32(456);
console.log(xorshift());
执行结果:
image-20250527231646750
可以看到,针对相同的种子,获取的随机数是相同的。
当然这里大家也可以使用自己的伪随机算法,或者自己创造一个都可以,其实伪随机算法就是一个比较简单的计算,根据输入计算输出即可,只要结果符合随机数的范围。
还有更多伪随机算法我这里只写一个,大家可以自行搜集。
function createMulberry32(seed) {
var state = typeof seed === 'number' ? seed : 1;
returnfunction() {
state += 0x6D2B79F5;
var t = state;
t = Math.imul(t ^ t >>> 15, t | 1);
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
return ((t ^ t >>> 14) >>> 0) / 0xFFFFFFFF;
};
}
// 使用示例
var mulberry = createMulberry32(789);
console.log(mulberry());
有了伪随机算法后,更改随机数 hook 方案为以下代码即可:
let count = 0
Math.random = function () {
return createXorshift32(count++)()
};
function createXorshift32(seed) {
var state = typeof seed === 'number' ? seed : 1;
returnfunction() {
var x = state;
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
state = x;
return (x >>> 0) / 0xFFFFFFFF; // 转为 [0, 1)
};
}
运行结果如下:
image-20250527232021998
结果符合预期。只是数据不是特别“随机”,这个就需要大家去调整伪随机算法了。
注:以上部分方案来自于零点大佬的 B 站视频(https://www.bilibili.com/video/BV1Eu4m1A7Zm/),在此感谢零点大佬的分享。
固定时间
固定时间的方案和固定随机数相同,只不过时间是递增的,也可以使用数组保存起来重放,具体代码就留给大家自行实现啦。
总结
以上就是升级版的固定随机数和时间的方案了,对于猿人学 2024 新春题目可以达到完美的固定效果,大家感兴趣可以尝试一下。
最近一直有小伙伴问我有没有交流群,为了能让大家更好的交流,我组建了一个逆向交流群,想要进群的小伙伴可以在后台点击“联系我”菜单或者扫码,添加微信并且备注“交流群”,我会拉你进群。
推荐阅读:
AST 技巧:模版(template)的高级用法
如何在浏览器中使用 AST 实时反混淆?(附AST模版可直接使用)
AST 使用技巧:如何快速分析混淆代码结构
在 JS逆向时如何 hook 属性?
如何 “正确” hook JS方法
无需登录,满血版DeepSeek R1,很强!
一日一技:反爬虫的极致手段,几行代码直接炸了爬虫服务器
JS调试技巧:如何让时间和随机数“听你指挥”?
【Windows版】tcpdump + wireshark 联动 frida,实现APP无感抓取HTTPS数据包
AST 技巧:还在手动扣代码?AST技术帮你自动扣代码
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:LLLibra146 LLLibra146 LLLibra146《JS调试技巧:如何让时间和随机数“听你指挥”?升级版!》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论