Hook Math.random 逆向分析
一、背景与意义在前端逆向工程与反爬对抗中Math.random()是最常被关注的全局 API 之一。大量网站将其用于生成请求指纹、加密盐值、混淆参数、时间戳扰动、反爬检测探针等场景。当逆向分析者需要还原参数生成逻辑、复现签名算法或绕过随机校验时精准 HookMath.random并捕获其调用栈与输出值往往是突破的第一步。与Canvas、WebGL等指纹 API 不同Math.random调用频率高、侵入性强、返回值无特征直接替换容易触发环境检测。因此对它的 Hook 技术也从简单的函数覆盖逐步演进到字节码插桩、引擎层面劫持等多种方案。二、Math.random 的底层实现在深入 Hook 之前先理解其底层生成逻辑有助于判断逆向价值。2.1 标准定义ECMAScript 标准仅规定Math.random()返回一个[0, 1)区间的伪随机数不指定具体算法由各引擎自行实现。这意味着不同浏览器、不同版本的生成序列可能完全不同。2.2 V8 引擎实现以 Chrome / Node.js 使用的 V8 为例历史上经历过三代算法早期线性同余生成器LCG周期短、可预测性强中期Mersenne TwisterMT19937周期 2^19937 - 1当前V8 v7.5XorShift128 算法基于 128 位状态性能更高XorShift128 的核心逻辑可简化为// 伪代码示意 state0 seed0; state1 seed1; function xorshift128plus() { let s1 state0; let s0 state1; const result s0 s1; state0 s0; s1 ^ s1 23; s1 ^ s1 17; s1 ^ s0; s1 ^ s0 26; state1 s1; return (result 0) / Math.pow(2, 64); }理论上只要捕获到连续的若干次输出就可以反推内部状态进而预测后续所有随机数 —— 这也是逆向分析中追求 “可复现” 的理论基础。2.3 逆向价值判断如果目标网站仅用Math.random生成非关键扰动Hook 捕获值即可如果用于核心加密盐或会话标识则需要进一步还原种子与状态实现 “预测式” 复现。三、基础 Hook 方案3.1 直接覆盖法最简单的 Hook 方式是直接重写Math.randomconst originalRandom Math.random; Math.random function() { const value originalRandom.call(Math); console.trace(Math.random 被调用返回值, value); return value; };优点零依赖、写法简单、兼容性好。缺点极易被检测。网站可通过toString()校验、toString.toString()嵌套校验、原生函数标记检测等手段识别。常见检测方式// 检测 1toString 对比 if (Math.random.toString() ! function random() { [native code] }) { console.log(环境异常); } // 检测 2原型链与原生标记 if (Math.random.constructor ! Function.prototype.constructor) { console.log(环境异常); }3.2 Proxy 包装法针对对象属性访问的 Hook可以使用Proxy拦截Math对象的属性读取const mathProxy new Proxy(Math, { get(target, prop) { if (prop random) { return function hookedRandom() { const val target.random(); // 记录调用栈、参数、返回值 return val; }; } return target[prop]; } });局限网站直接持有Math.random的引用后Proxy 会失效且Proxy本身在部分沙箱环境中可被检测。3.3 原型链 HookMath.random挂载在Math对象上并非原型方法因此原型链 Hook 对它不直接生效。但可以结合Object.defineProperty做属性劫持const originalRandom Math.random; Object.defineProperty(Math, random, { get() { console.trace(Math.random 被访问); return originalRandom; }, configurable: true });这种方式可以捕获 “读取函数” 的动作但无法在每次调用时插入逻辑适合做访问检测而非值捕获。四、进阶 Hook 与对抗检测4.1 伪装 toString绕过最基础的toString检测只需重写钩子函数的toStringconst originalRandom Math.random; function hookedRandom() { const val originalRandom(); console.log(val); return val; } hookedRandom.toString function() { return function random() { [native code] }; }; Math.random hookedRandom;但这只能绕过单层检测。面对Function.prototype.toString.call(Math.random)这种强制调用原型方法的检测自定义toString会失效。4.2 劫持 Function.prototype.toString更深一层的对抗是连toString一起 Hookconst originalToString Function.prototype.toString; const originalRandom Math.random; function hookedRandom() { return originalRandom(); } Function.prototype.toString function() { if (this hookedRandom) { return function random() { [native code] }; } return originalToString.call(this); }; Math.random hookedRandom;风险修改Function.prototype.toString影响面极大更容易触发更底层的环境检测。在高强度反爬站点不建议使用。4.3 基于 AST 插桩的 Hook当运行时 Hook 容易被检测时另一种思路是在代码执行前修改源码 —— 即在 AST 层面将Math.random()替换为自定义函数调用。典型流程通过Service Worker或代理工具拦截目标 JS 文件使用 Babel / Acorn 解析为 AST遍历CallExpression识别callee.object.name Math callee.property.name random替换为自定义钩子函数调用保留原始返回值重新生成代码并交付执行这种方式的优势在于运行时Math.random本身仍是原生函数检测方无法通过函数引用、toString 等手段发现异常。缺点是实现成本高且需要处理代码混淆、eval 动态执行等场景。五、逆向分析实战从 Hook 到还原5.1 捕获调用时机与调用栈逆向的第一步不是改值而是摸清调用规律。一个完整的 Hook 至少应记录调用时间戳调用栈Error().stack或console.trace返回值调用次数计数示例const logs []; const originalRandom Math.random; Math.random function() { const val originalRandom(); const stack new Error().stack; logs.push({ time: performance.now(), value: val, stack: stack }); return val; };通过分析调用栈可以定位到是哪个混淆函数在使用随机数进而缩小逆向范围。5.2 固定返回值用于差分分析在逆向加密算法时常需要 “控制变量”。将Math.random固定返回某个值观察输出变化可以快速判断它是否参与了最终签名Math.random function() { return 0.123456789; // 固定值 };如果签名结果随固定值稳定复现说明随机数是算法输入之一反之则可能仅用于混淆或探针。5.3 状态还原与预测对于 XorShift128 算法理论上收集连续 2~4 个 64 位输出即可反推内部状态。但实际浏览器中Math.random返回的是浮点数低位精度会丢失通常需要更多样本 暴力搜索来恢复状态。这一步的工程复杂度较高一般用于需要 “离线复现整套加密” 的场景。多数逆向任务中直接 Hook 取值并转发到本地计算已经足够。六、反 Hook 检测与绕过思路6.1 常见检测手段原生性检测toString、[native code]字符串匹配、name属性校验引用缓存检测页面加载初期缓存Math.random引用后续对比是否被替换频率与分布检测统计大量调用结果的分布判断是否符合均匀分布时序检测Hook 函数通常比原生函数慢可通过执行耗时判断沙箱探针在 iframe 中创建纯净环境与当前上下文对比6.2 绕过原则最小侵入能不 Hook 就不 Hook优先通过 AST 插桩或断点调试获取值引擎层 Hook使用 CDPChrome DevTools Protocol在调试器层面下断点捕获值运行时完全无感知及时恢复Hook 取值后立即恢复原生函数避免长时间暴露iframe 偷取从干净 iframe 中引入原生Math.random替换回主线程七、总结Math.random的 Hook 是前端逆向的入门级技术但对抗深度可以延伸到引擎层与沙箱安全。从最简单的函数覆盖到 AST 插桩、CDP 调试劫持、状态还原预测不同场景对应不同方案。对于大多数逆向分析场景“Hook 取值 调用栈定位”已经能解决 80% 的问题真正需要还原随机数种子、实现预测的场景并不多见。学习的重点应放在 “如何低检测地 Hook” 与 “如何通过 Hook 结果辅助定位核心算法” 上而非单纯追求替换本身。

相关新闻

【WEB开发日记2】3D太阳系模型 - 已开源

【WEB开发日记2】3D太阳系模型 - 已开源

源码GitHub地址: https://github.com/HiCodeOnline/WebHi3DSolarSystem 文档地址: https://cloudflare.hicode.online/posts/web-hi3dsolarsystem/ 下载源码后直接双击solar-system.html,使用edge或谷歌浏览器打开即可查看效果 效果图如…

2026/11/1 6:02:04 阅读更多 →
秦Pro 1.5T+6MT手动挡车型深度解析:驾驶乐趣与市场定位

秦Pro 1.5T+6MT手动挡车型深度解析:驾驶乐趣与市场定位

1. 从一则消息说起:手动挡的“逆行者”最近,一则关于某品牌旗下秦Pro 1.5T6MT动力车型即将在3月底上市的消息,在车迷圈和部分汽车媒体中引起了不小的讨论。讨论的焦点,并非这款车本身有多么划时代的技术革新,而恰恰是那…

2026/10/29 23:53:24 阅读更多 →
无人驾驶赛道全景:五大领头羊技术路线与商业化竞速分析

无人驾驶赛道全景:五大领头羊技术路线与商业化竞速分析

1. 赛道全景:从科幻到现实的“无人驾驶”竞速 如果你在五年前问我,什么时候能坐上真正的无人驾驶出租车,我可能会给你一个模糊的、充满技术术语的远期展望。但今天,如果你身处北京亦庄、上海嘉定、深圳坪山或者广州南沙&#xff0…

2026/10/31 3:22:54 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/3 1:09:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/2 10:46:11 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/2 10:47:40 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/2 1:16:51 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/2 10:46:31 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/2 10:46:26 阅读更多 →

日新闻

周新闻

月新闻