JS逆向教程三:Hook注入与混淆代码分析
本文详细介绍了JS逆向中的Hook技术、油猴插件注入、混淆代码分析、Webpack打包逆向、开发者工具检测绕过以及魔数识别等高级技巧,帮助读者掌握复杂场景下的逆向分析方法。
JS Hook油猴插件注入
1. 场景痛点
- 控制台注入的 Hook 代码 在页面刷新(URL 变化)后立即失效 → 断点永远踩不到。
- 需要 “随页面生命周期自动注入” 的持久化方案 → 油猴(Tampermonkey)插件。
2. 油猴安装与新建脚本
- 浏览器扩展商店 / 极简插件网 → 搜索 Tampermonkey → 安装。
- 点击图标 →「添加新脚本」→ 清空默认模板 → 粘贴 Hook 代码。
3. 脚本模板(最小可用)
1 | |
@match支持通配符,可细化到域名/路径。@run-at document-start保证在网站任何 JS 执行前完成注入,避免漏钩。
4. 使用流程(以”周末票房”接口为例)
- 开启油猴开关 → 脚本状态 **”已启用”**。
- 正常点按钮/翻页 → 页面刷新也无妨,Hook 依旧生效。
- 触发请求后 弹出 Debugger → 此时参数即为 密文。
- 跳过一行 → 变量变为 明文 → 向上跟栈即可定位解密函数(本例
webInstance.shell(...))。
5. 什么时候选用油猴注入
| 场景 | 控制台注入 | 油猴注入 |
|---|---|---|
| 单页应用(XHR 无刷新) | ✅ | ✅ |
| 整页跳转/URL 刷新 | ❌(失效) | ✅ |
| 需要随页面自动生效 | ❌ | ✅ |
| 临时调试一句话 | ✅ | ❌(需建脚本) |
6. 扩展技巧
- 一键开关:图标→脚本列表→点击即可停用/启用,无需刷新。
- 多脚本管理:不同站点写不同
@match,互不干扰。 - 日志版:把
debugger;换成console.log(arguments[0])可静默收集。 - 配合外部编辑器:油猴「外部编辑器」选项 → 用 VSCode 实时保存同步。
7. 脚本示例
1 | |
这段脚本通过覆盖原生的 JSON.stringify 和 JSON.parse 方法,添加了调试和日志记录功能。每当这些方法被调用时,脚本会在控制台打印出参数,并进入调试模式。这种技术通常用于调试或监控 JSON 数据的处理过程。
混淆代码分析与 WebAssembly (WASM) 技术
在进行 JavaScript 逆向分析 时,经常会遇到混淆代码和 WebAssembly (WASM) 技术的结合。理解这些技术能够帮助你更好地分析和还原复杂的加密或混淆的应用。
1. 混淆代码 (Obfuscated Code)
定义:混淆代码是指通过技术手段改变代码的可读性,使得代码的逻辑更加难以理解和逆向分析。混淆的目标通常是提高代码的安全性,防止破解或盗用。
常见方法:
- 重命名变量和函数:将变量名、函数名替换为无意义的字符或随机字符串,如
a,b,c等。 - 死代码注入:加入一些无效的、不会执行的代码,以混淆程序的控制流。
- 控制流扁平化:改变程序的控制结构,使其难以理解。
- 字符串加密:将字符串加密后存储,在运行时解密并使用,避免明文存储敏感信息。
- 重命名变量和函数:将变量名、函数名替换为无意义的字符或随机字符串,如
分析混淆代码的策略:
- 调试工具:使用
Chrome DevTools、Firefox Developer Tools等工具,在浏览器中设置断点,逐步跟踪程序的执行流。 - 逐步还原:通过控制台输出、中断点和手动跟踪代码执行来识别关键函数和变量。
- 解混淆脚本:有时可以使用自动化工具(如
jsnice、prettier)来尝试解混淆变量名和函数名。
- 调试工具:使用
2. WebAssembly (WASM) 技术
定义:WebAssembly 是一种低级字节码格式,设计用来在现代浏览器中运行。它通常与 JavaScript 配合使用,能提高执行速度并扩展浏览器的功能。WebAssembly 代码通常难以直接理解,需要专门的工具来分析。
用途:
- 性能优化:对于性能要求高的应用,如视频解码、图像处理等,WebAssembly 提供了显著的性能提升。
- 加密与解密:WebAssembly 由于其运行效率高,常被用于加密算法、解密操作等场景,增加逆向分析的难度。
如何逆向分析 WASM:
- WASM 文件分析:WASM 通常编译自 C、C++ 或 Rust 等高级语言,了解其源代码的编程语言能帮助你理解其实现逻辑。使用工具如 WebAssembly Studio 或 Wasm Explorer 来查看和调试 WASM 文件。
wasm2wat工具:这是一个命令行工具,将 WASM 文件转换为 WebAssembly Text Format (WAT),该格式比二进制的 WASM 更容易阅读和分析。可以通过wasm2wat工具转换和查看其内容。- 浏览器调试工具:现代浏览器(如 Chrome)提供了内置的 WASM 调试支持,可以在开发者工具中查看 WASM 代码的堆栈、变量等。
- 反编译工具:通过反编译 WASM 文件,可以尝试恢复源代码,虽然这并不总是精确的,但可以帮助分析其工作原理。常用的反编译工具有 Binaryen、Emscripten 等。
3. 混淆与 WASM 结合的复杂性
- 当混淆代码与 WebAssembly 结合使用时,逆向分析的复杂度会增加。
- WASM 加密算法:加密算法通常会被用 WebAssembly 编写,以提高执行速度,这样就很难通过 JavaScript 的源代码直接逆向。你需要通过 WASM 的反编译和调试来分析其内部逻辑。
- JavaScript 与 WASM 的交互:在一些应用中,JavaScript 和 WASM 代码密切交互。通过 JavaScript 调用 WASM 的函数,或者在 WASM 中执行 JavaScript 代码,这种交互使得代码的逆向更加复杂。
- 混淆的 WAT 文件:有些开发者会对 WebAssembly 的源代码(WAT 文件)进行混淆,使得源代码即使被反编译也不易理解。
4. 逆向分析流程
- 抓包与分析:首先,使用浏览器开发者工具抓包视频流或其他关键数据,分析其传输过程中的加密方式(如
blobURL、加密的 JSON 请求等)。 - 查看 WebAssembly 模块:如果识别到 WASM 文件,可以使用浏览器的调试工具或
wasm2wat等工具分析 WASM 模块的内部结构,查看其导出的函数。 - 分析 JavaScript 代码:通过调试和逆向 JavaScript 代码,理解其如何与 WASM 模块交互。例如,如何将数据传递给 WASM 模块进行处理,以及如何处理 WASM 模块返回的数据。
- 还原解密过程:通过逆向分析混淆代码和 WASM 算法的解密过程,最终还原出真实的视频链接或其他资源。
5. 工具推荐
调试工具:
- Chrome DevTools:功能强大的浏览器开发者工具,适用于 JavaScript 和 WASM 代码的调试。
- Firefox Developer Tools:支持对 WASM 模块的调试。
WASM 工具:
- Wasm Explorer:一个在线工具,用于查看 WASM 文件并分析其结构。
- wasm2wat:将二进制 WASM 文件转为可读的 WAT 格式。
解混淆工具:
- JSNice:自动化的 JavaScript 混淆代码还原工具。
- Prettier:可以格式化代码,去除混淆。
小结
- 混淆代码:通过变更代码结构、重命名变量、注入无效代码等手段,增加逆向分析的难度。解决方法是使用调试工具和手动还原。
- **WebAssembly (WASM)**:通过提升执行效率,使得加密算法或重要逻辑通过 WASM 执行,从而避免被直接分析。使用 WASM 分析工具和浏览器开发者工具来调试和分析 WASM 模块。
逆向分析混淆代码与 WASM 结合的应用,通常需要较强的技术积累和耐心。逐步从简单的混淆代码和 WASM 模块入手,掌握其基本特性后,逐渐处理复杂的应用。
Webpack打包(扣js代码)
1. 什么是 Webpack?
- Webpack 是一个现代 JavaScript 应用程序的静态模块打包器。它可以将开发中的静态资源(如 JavaScript、CSS、图片等)打包成模块,利用加载器和插件处理这些资源,最终输出适合生产环境的代码。
- Webpack 构建时会递归分析依赖关系图,处理模块并将它们打包在一起,常用于前端开发中的资源管理。

2. Webpack 工作原理
Webpack 通过一个自执行的匿名函数实现模块加载。核心流程包括:
- **加载器 (Loader)**:将资源转化为 JavaScript 模块。
- **模块 (Module)**:包含实际的业务代码或库,通常是 JavaScript 函数。
- **插件 (Plugin)**:对打包的过程进行扩展和优化。
Webpack 输出的文件形式包括:
- 数组形式:通过数组下标访问模块。
- 字典形式:通过对象的键来访问模块。
3. 如何通过 Webpack 打包的代码逆向获取加密算法
在 Webpack 打包后的代码中,模块一般会通过加载器来加载,模块本质上通常是函数。
逆向过程中,我们需要找到加载器的位置以及模块的定义位置,常见的步骤包括:
- 找到加载器:通过形参、函数调用链等方式找到加载器。
- 找到模块:通过数组或者字典对象访问模块,并分析其功能。
- 解密加密算法:逆向过程中,通常需要找到加密模块,并通过调用这些模块还原加密逻辑。
4. 逆向过程步骤
- 定位加载器:首先需要找到 Webpack 输出的加载器(例如
N函数)。加载器一般通过形参传递模块,内部使用exports导出模块。


- 获取模块:Webpack 会将模块通过下标或键值对的方式存储在数组或字典对象中。在数组形式下,模块按顺序排列,可以通过下标访问;在字典形式下,可以通过键来直接访问模块。
- 处理加密模块:例如,在解密登录算法时,找到加密模块后,我们需要将其提取出来并在本地模拟执行,从而还原加密过程。

5. 常见问题与难点
- 加载器位置难以定位:由于 Webpack 的打包方式灵活,加载器的位置可能不容易发现。需要通过调试、日志等方式定位到具体的加载器位置。
- 模块之间的相互依赖:Webpack 打包后的代码中,模块之间可能有层次嵌套,导致逆向时需要按层级逐一提取模块,工作量较大。
- 环境差异:在本地模拟时,可能会遇到浏览器特有的对象(如
window)未定义的问题。需要补充这些环境对象,确保代码能在本地运行。
6. 案例分析
- 在实际操作中,通过抓包获取登录接口数据,分析接口中传递的密码加密逻辑。通过 Webpack 打包后的 JS 文件,提取加密模块,模拟加密过程。
- 在代码中,使用形参传递加密方法(如对称或非对称加密)。通过修改本地加载器的引用,可以在本地还原加密算法,验证输入数据的加密逻辑。
7. 总结
Webpack 逆向的关键难点:
- 定位加载器和模块的具体位置。
- 解析复杂的模块依赖关系。
方法总结:
- 导出加载器后,通过本地代码访问和调试。
- 使用字典方式处理模块可以大大简化查找过程。
通过掌握 Webpack 打包的基本原理和逆向技巧,可以有效地逆向还原复杂的加密算法。
开发者工具检测
1. 问题描述
- 目标:某个网站开始检测是否打开了开发者工具(DevTools)。
- 网站会检测到开发者工具的打开并进行相应的处理,如阻止页面正常加载或播放。
- 症状:当用户打开开发者工具时,页面会自动跳转到特定的页面,或者某些功能会被禁用,如视频播放、抓包等。
2. 开发者工具检测原理
网站检测是否打开了开发者工具通常是通过一些浏览器特性,如:
- 窗口大小检测:开发者工具打开时,浏览器窗口的大小和布局会发生变化,可能通过脚本检查窗口的尺寸。
- 调试模式检测:检测调试器的存在,例如通过 JavaScript 检测特定的浏览器接口是否存在或异常行为。
- 特定的事件检测:如监听
devtools-detect、resize或其他与开发者工具相关的事件。
3. 解决方案与绕过方法
- 修改 JavaScript 代码:通过调试工具或修改源代码,绕过检测的 JavaScript 代码,直接禁用开发者工具的检测逻辑。
- 浏览器插件:使用一些第三方浏览器插件(如
DevTools-detect或NoScript)来阻止页面检测到开发者工具的打开。 - 控制台命令:通过输入特定的控制台命令来绕过页面的 JavaScript 检测,阻止页面响应不必要的行为。
- 模拟环境:在某些情况下,可以通过模拟浏览器环境(例如使用
phantomjs或其他无头浏览器)来避开开发者工具的检测。
4. 步骤总结
- 打开开发者工具时,网站跳转到检测页面:这通常是通过 JavaScript 代码实现的,目的是在检测到调试器后改变页面行为。
- 过检测:通过绕过检测代码(例如通过修改代码或使用插件),可以让页面正常加载并继续抓包。
- 分析和修改:需要分析页面的 JavaScript 代码,找到检测开发者工具的部分,进行修改或禁用。
魔数
文件识别领域的术语——文件魔数(File Magic Number),用来快速判断一段二进制数据或哈希值到底用了哪种算法、哪种编码、甚至哪个库。
一、魔数到底是什么
- 文件开头若干字节(通常 2-8 B)的固定十六进制序列,用来标识文件格式或算法特征。
- 在 Web 逆向场景下,我们把”密文长度 + 固定前缀/后缀“也泛称为”魔数”——肉眼秒认算法的指纹。
二、Web 逆向常见魔数速查表
| 算法 / 格式 | 长度(hex) | 典型魔数(前缀/整例) | 一眼识别口诀 |
|---|---|---|---|
| MD5 | 32 | c4ca4238a0b923820dcc509a6f75849b(明文=”1”) |
32 位必猜 MD5 |
| SHA-1 | 40 | 356a192b7913b04c54574d18c28d46e6395428ab |
40 位 → SHA-1 |
| SHA-256 | 64 | 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b |
64 位 → SHA-256 |
| SHA-512 | 128 | 4dff4ea340f0a823f15d3f4f01ab62eae0e5da579ccb851f8db9dfe84c58b2b37b89903a740e1ee172da793a6e79d560e5f7f9bd058a12a280433ed6fa46510a |
128 位 → SHA-512 |
| HMAC-MD5 | 32 | 与 MD5 等长,但输入需 key → 无法直接比对,先确认长度再跟 key | |
| Base64 | 不定 | 末尾常见 = / ==;字符集 [A-Za-z0-9+/] |
尾等号秒判 Base64 |
| Hex | 偶数位 | 仅 0-9a-fA-F |
先转字节再判算法 |
| UUID/GUID | 36 | 8-4-4-4-12 段格式 |
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx |
| JWT | 不定 | 两段或三段,每段 Base64,首段常=eyJhbGciOi |
点分三段 → JWT |
| AES-CBC 密文 | 16 倍数 | 长度%16==0,随机字节 | 先长度排除,再跟 key/iv |
| RSA 公钥 | 不定 | 30 82 ?? 02 01 00(DER)或 -----BEGIN PUBLIC KEY----- |
固定 PEM/DER 头 |
| Webpack 模块 | 不定 | 0xac 0xe8(wasm 模块魔数) |
文件头两字节 |
三、实战用法(秒认算法)
- 长度过滤 → 32/40/64/128 位直接锁定 MD5/SHA 系列。
- 前缀/整例比对 → 拿
"1"的哈希值当场对照,完全一致即标准算法。 - Base64 先解码 → 看解码后长度再回表。
- 文件/流 → 直接看十六进制头(如
0xAC 0xE8→ wasm)。