JS逆向教程一:基础入门与实战技巧
本文详细介绍了JS逆向的基础知识、浏览器开发者工具的使用要点、hook代码实现快速定位以及扣JS代码的实战技巧,帮助读者掌握前端逆向分析的核心技能。
JS基础
1. 前置要求
- Python 基本语法
- JS 基本语法(本篇重点)
- Node.js 环境已安装并能正常运行
2. 教程大纲速览
| 阶段 | 内容 |
|---|---|
| 基础 | JS 语法、浏览器调试、扣代码、对称/非对称加密特征 |
| 进阶 | Webpack、OB 混淆、Cookie 反爬、滑块/验证码实战 |
3. 变量声明与作用域
| 关键字 | 作用域 | 可否重复赋值 | 备注 |
|---|---|---|---|
var |
函数级或全局 | ✅ | 存在提升,易污染全局 |
let |
块级 | ✅ | 推荐;无提升 |
const |
块级 | ❌ | 声明常量,引用不可重新赋值 |
函数内部用
let/const声明的变量,函数执行完即销毁,外部访问会ReferenceError: xxx is not defined。
4. 函数三种常见写法
普通命名函数
1
2
3
4function demo1() {
console.log('hello world');
}
demo1(); // 调用匿名函数表达式
1
2
3
4const func = function (x, y) {
return x + y;
};
console.log(func(1, 2)); // 3自执行函数(IIFE)
1
2
3!function () {
console.log(123);
}(); // 立即打印 123
5. 全局导出技巧
在自执行或庞大混淆代码中,把关键函数挂到全局,方便后续 Python 调用:
1 | |
6. 对象(≈ Python dict)
1 | |
7. JSON ↔ 字符串互转
| 方向 | API | 示例 |
|---|---|---|
| 对象 → 字符串 | JSON.stringify(obj) |
方便传输/存储 |
| 字符串 → 对象 | JSON.parse(str) |
拿到数据后还原成对象 |
8. 浏览器调试口诀
- F12 → Sources → 断点 / Step over(F10) / Step into(F11)
- Console 直接试调用、打印变量
- Network 抓包看请求头、参数、Cookie;对照调用栈”扣代码”
9. 下一步预告
- 对称加密(AES/DES)特征与定位
- 非对称加密(RSA)公钥私钥识别
- Webpack 整体打包结构 & 导出口寻找
- OB 混淆还原技巧
- Cookie 反爬与滑块验证码实战
开发者工具使用要点
1. 浏览器开发者工具面板的使用
1.1 打开开发者工具
打开方式:F12键、ctrl+shift+I组合键、点击浏览器右上角的三个点->更多工具->开发者工具。介绍这么多种,是有因为有些网址直接按F12无法打开开发者工具,这时可以采用其他方法。
打开开发者工具后,有一些面板需要重点认识一下(下图框选部分):

Elements面板: 展示html标签的面板,可以用来查看html页面中感兴趣的文本或者图片。
Console面板: 可以执行一些js代码,可以查看加密函数的运行结果、注入hook代码等。
Source面板:这是js调试主要在这个面板进行,重点关注一下调试区。Breakpoints可以查看我们下的断点,XHR/fetch Breakpoints可以下xhr断点,Event Listener Breakpoints可以下事件监听断点,如js加载的断点,到时调试瑞数会用到。这个面板相对而言比较复杂,但是用多了就会认识全了。

Network面板:这里记录了操作浏览器时发送的一些数据包。点击放大镜图标可以搜索我们感兴趣的文字,点击Fetch/XHR可以看到发送的xhr请求,动态数据就在这里查看。

Application面板:查看cookies,遇到cookie反爬则用得较多。
2. 定位数据包
前面简单认识了开发者工具,下一步就是要在Network面板中找到感兴趣的数据包,以方便开发爬虫程序。
最简单的是在Network面板中直接搜索文本内容,如果可以搜到就直接可以定位数据包了。这里搜索”为人父母”,则可以搜到相应的数据包,在左侧面板中点击即可快速定位到目标数据包。

可以通过数据包的大小来定位,点一下size列,可以按数据包大小进行排列,有时也能快速定位。
xhr数据,一般涉及逆向的数据包很大概率是xhr接口,因此可以直接在xhr数据包中快速定位。


curl请求转换工具网站:
Hook代码实现快速定位
前面了解了浏览器开发者工具并能快速定位数据包接口,后面就是要分析该接口是不是存在加密点,也就是找到需要逆向的位置。
通常需要逆向的位置一般在Request headers、Payload、Response和Cookie中。下图中数据包的url的查询关键字中有一个analysis的是无法看懂的,这个就是密文,需要着重分析。

Hook方法
hook技术可以改变js函数的执行行为,针对一些加密函数可以去快速定位。Javascript中的JSON.stringnify和JSON.parse两个方法是处理JSON数据常用的方法,某些站点传输响应数据时会用到这两个方法。
1 | |
将上述代码放入Console控制台运行即可。这里将JSON.parse赋值给_parse变量,当调用了JSON.parse方法时则输出相应的JSON字符串并执行debugger语句,会立即断下 ,且不改变原来函数的执行逻辑。其他方法的hook代码可以以此为模板进行编写。
Hook XHR请求
在Javascript中,可以利用XMLHttpRequest.open方法发送xhr请求,因此可以对其进行hook。
1 | |

1 | |
url.indexOf(“analysis”) != -1这行代码表示在url中存在analysis,此时会执行debugger语句,立即断住。此时向上跟栈,可以定位加密位置。通过该方法可以很快地定位加密点。

关于xhr请求,XMLHttpRequest.send, XMLHttpRequest.setRequestHeader和XMLHttpRequest.onreadystatechange这几个方法很重要,需要重点关注。
同时我们也要注意发包的流程,首先初始化javascript>>执行加密逻辑>>发包>>返回相应>>解密响应体。执行加密逻辑可能会在请求Interceptors (拦截器)中进行。
Hook Cookie
对于一些cookie反爬,则可以hook相应的cookie来进行定位。**hook cookie的代码是固定的,可以直接拿来使用。**
练习网址:aHR0cHM6Ly93d3cuMTBqcWthLmNvbS5jbi8=

cookie是以键值对的形式存储的,其中键名为v的值是需要逆向分析的。可以使用以下代码进行hook。
1 | |
当document.cookie中含有键名为v时,则会执行debugger语句。此时可以快速定位加密位置。
扣JS代码
1. 分析目标
- 场景:网页翻译接口返回「密文」,前端展示「明文」→ 需本地还原「加密/解密」逻辑。
- 突破口:
- 表单参数
sn(加密) - 响应体密文 → 前端明文(解密)
- 表单参数
2. 定位加密/解密函数通用套路
| 步骤 | 操作 | 工具/技巧 |
|---|---|---|
| ① 抓包 | 确认「密文字段」与「时间戳」等关联字段 | Network 面板 |
| ② 搜关键字 | 字段名 + 冒号(英文) sn: → 缩小到 44 个 → 再叠加其他表单字段 → 个位数 |
Sources - Search |
| ③ 下断点 | 所有疑似赋值处全部打断点 | Ctrl+F 局部搜索 |
| ④ 触发请求 | 重新输入、点击发送 | 让代码跑进断点 |
| ⑤ 单步跟栈 | 观察局部变量、参数来源 | Call Stack / Scope |
3. 加密案例复盘(sn 生成)
- 函数链:
固定值 e+时间戳 a→ 经s()→ 内部调用_.md5(e.toString()) - 扣代码原则:
缺什么补什么,按依赖链从底向上复制;遇到大型对象I先打印,对比官方库特征 → 直接用require('crypto')或crypto-js替换,省去逆向整套库。
4. 解密案例复盘(密文 → 明文)
- Hook 点选择:
前端必调JSON.parse(解密后字符串)→ 在控制台注入JSON.parse = function(x){ debugger; return orig(x); } - 两次断点:
第一次断到「密文」,第二次断到「明文」→ 两次调用栈之间即为 解密函数。 - 算法识别:
参数出现key,iv,decodeData→ 典型 AES 特征,直接抠decode()函数即可。
5. 扣代码实操口诀
- 复制顺序:从最里层被调用函数→向外层展开,保证依赖已定义。
- 全局冲突:把大对象改名再
require,如const crypto = require('crypto-js'); - 常量写死:固定密钥/盐值直接硬编码,方便后续 Python 直调。
- 验证一致:浏览器 Network 里拿到的
sn值 vs 本地运行结果必须 完全一致(包括大小写、长度)。
6. 常用 Hook 模板(收藏)
1 | |
7. 工具链速查
| 任务 | 推荐 |
|---|---|
| 静态搜索 | Sources - Search(正则/冒号过滤) |
| 动态调试 | Chrome DevTools、Fiddler/Charles |
| 本地运行 | Node.js + crypto-js / axios |
| 代码美化 | Prettier、js-beautify |
| 混淆对抗 | AST 解混淆(babel-parser)、动态执行 |
在定位好要逆向的接口后,快速浏览请求头、请求载荷、响应和cookie等位置,看到类似密文的字段需要特别注意,当然像uuid和csrf-token这类密文是不需要逆向的。
1. JS定位的几种方式
案例网址:aHR0cHM6Ly9mYW55aS55b3VkYW8uY29tL2luZGV4Lmh0bWwjLw==
查找逆向参数:payload中有sign签名加密

再看响应,是密文,需要解密处理,因此需要解决sign和解密响应体两个问题。

1.1 直接搜索
关于签名加密sign,可以直接搜索sign,按ctrl+shift+F全局搜索,可以在所有js文件中搜索相应的内容。如下图,搜到了376个,这样搜的话,太多了,很难定位。直接搜其实也是有技巧的。

可以尝试搜sign:,搜索的结果是29个,冒号是要英文的。如下图,结果大大减少。这是在可疑的地方可以下断点,方便调试。

下了断点后,重新触发该接口,可以断住。sign的值是由S函数加密生成的,传入了两个参数,o和e。后续需要对S函数进行分析。

1.2 XHR断点
如果搜索不到,则可以通过xhr断点来定位。同样是该接口,复制路径/webtranslate,到source面板xhr断点处设置断点。

再次触发该接口(随便输入文字即可),会断住,如下图。

此时向上跟栈,定位到加密函数的位置。向上跟到I栈时,发现k(t)的执行结果中生成了sign的值,可以初步判定加密参数是在这里生成的。这样就成功定位了加密参数,逆向已经完成了50%。

1.3 堆栈
这和xhr有点类似,也要向上跟栈,但入口会有不同。最后也是在I栈成功定位。

2. JS代码本地运行
我们通过分析发现,在webtranslate接口中含有sign加密参数,如果用python代码来请求该接口,必须要解决sign的生成算法。通过前面的分析,sign的加密位置已经生成,这个时候就是进一步分析js代码了,逆向还原sign的生成算法。
找到加密函数后,鼠标移到k函数的上方,如下图所示。

点击一下箭头指向的链接,即可跳转到k的函数内部。进去可以看到,sign又是有S函数生成的,传入了o和e两个值生成的,此时需要再去跟一下S函数。相同的方法,鼠标悬停在S函数的上方,点击进入S函数内部。

在S函数中,又嵌套了一个_函数,位置如下。

现在对逆向是不是有了更清晰的认识,说白了,就是一直往上跟js的执行逻辑。现在把这些代码都复制下来,保存成本地js文件,用nodeJs执行。如果成功,则逆向成功。
3. 实战
将上述代码复制到本地,如下图,执行k函数。

结果报错了。

这里提示i没有定义。这里i是啥呢?需要根据网站的js进行分析,像是一个标准库。

如果你比较熟悉nodejs的话,其实很快就知道,i其实是nodejs自带的一个模块crypto。于是可以直接把i替换成crypto,最后执行成功。

到此,sign的逆向过程就全部结束了,是不是很简单呢。