当我们了解了 JavaScript 的压缩,混淆技术后,那么就需要对这些技术进行逆向
示例网站:https://spa2.scrape.center/
开发者面板工具介绍
Elements : 元素面板, 用于查看或修改当前网页 HTML 节点的属性,CSS属性,监听事件等 HTML 和 CSS 都可以即时修改和即时显示
Console: 控制台面板, 用于查看调试日志或异常信息。另外,我们还可以在控制台输入 JavaScript 代码,方便调试
Sources: 源代码面板, 用于查看 HTML 文件源代码, JavaScript 源代码, CSS 源代码。此外,还可以在此面板对 JavaScript 代码进行调试, 比如添加和修改 JavaScript 断点,观察 JavaScript 变量的变化等
Network: 网络面板, 用于查看页面加载过程中的各个网络请求,包括请求和响应等
Performance: 性能面板, 用于记录和分析页面在运行时的多有活动,比如 CPU 占用情况,呈现页面的性能分析结果
Menory: 内存面板, 用于记录和分析页面内存的占用情况,如查看内存的占用变化,查看 JavaScript 对象和HTML 节点的内存分配
Application: 应用面板,用于记录网站加载的所有资源信息,如存储,缓存,字体,图片等,同时也可以对一些资源进行修改和删除
Lighthouse:审核面板,用于分析网络应用和网页,收集现在性能指标并提供对开发人员最佳实践的意见
查看节点事件
在 Elements 面板,点击右侧 Styles选项卡,可以看到对应节点的 CSS 样式,我们可以在这里自行增删,实时查看效果
在 Computed 选项卡中,可以看到当前盒子模型
在 Event Listeners 选项卡 , 这里可以显示各个节点当前已经绑定的事件,都是 JavaScript 原生支持的
change: HTML 元素改变时会触发的事件
click: 用户点击 HTML 元素会触发的事件
mouseover: 用户在 HTML 元素上移动鼠标时会触发的事件
mouseout: 用户从一个元素上移开鼠标时触发的事件
keydown: 用户按下键盘时会触发的事件
load: 浏览器加载完页面时会触发的事件
例如:
我们选中切换到第二页的节点, 右侧的 Event Listeners 选项卡就会看到它绑定的事件,这里有对应事件的代码位置,内容为一个 js 文件名称, 后面跟着 冒号, 接着跟一个数字 7 ,。 所以对应事件处理函数定义在 这个 JS 文件的第 7行, 我们点击这个代码的位置,便会自动跳转到 Sources 面板, 打开对应的文件位置
代码美化
前面我们到了 JS 文件的代码位置,但是这里代码似乎被压缩了,可读性很差, Sources 提供了一个代码美化的功能
之后的代码相对可读性大大提高
断点调试
我们可以在需要的位置打上断点,当对应事件触发时,浏览器会自动停在断点的位置等待调试,此时我们可以选择单步调试,在面板中观察调用栈,变量值,以更好的追踪对应位置的执行逻辑
单击需要加断点的位置,出现一个蓝色箭头,这样断点就添加好了。同时右侧的 Breakpoints 选项卡会出现我们添加断点的列表,我们知道
因为我们知道这个事件,是点击翻页事件,所以这里我们点击一下翻页,上面就出现了 Paused in debugger ,说明浏览器执行到我们断点位置就不在执行了,等待调试
回调参数 e 作为点击事件, 在右侧 Scope 面板处,可以看到各个参数的值,
在下面的 Closure(Jr) 中还有一个 o 方法,点开之后,会看到源码位置
如果我们需要特别关注某个方法可以在 Watch 的 + 里添加 例如 添加 o.apply
此时我们还可以打开 Console 面板输入任意 JS 代码执行,例如 我们想要查看 arguments 的第一个元素是什么可以直接输入 arguments[0]
这里的警告是 不让直接粘贴,可以手动输入 allow pasting 回车之后,就可以粘贴了
此时我们还可以选择单步调试,这里有三个重要的按钮,鼠标放上去会有提示
Step Over Next Function Call : 逐句执行
Step Over Next Function Call : 进入方法内部执行
Step Out of Current Function : 跳出当前方法
例如我们点击 Step Over Next Function Call 就会执行到下一行代码
观察调用栈
有时我们执行到了某个方法的内部,这时我们不知道发生了什么,那要怎么跳出来呢?
我们可以看右边的 Call Stack 面板,就可以看到全部的调试过程,我们可以点击对应的位置跳转到指定代码位置,这样我们就可以回溯某个逻辑的执行流程
恢复 JavaScript 执行
在调试过程中,如果想要快速跳到下一个断点或者让 JS 代码运行下去, 可以点击 Resume script execution 按钮, 这时浏览器就会直接执行到下一个断点位置,从而避免无穷尽的调试中,如果没有下一个断点,浏览器则会恢复到正常
Ajax 断点
如果我们需要在发生 Ajax 请求的时候触发断点,从而找到 Ajax 请求时的逻辑,找出加密参数是怎么构造的。首先,我们取消前面的所有断点,右键 2 翻页按钮, 切换到 Network 面板,找到翻页对应的页面, 查看 请求 URL
可以看到里面包含 /api/movie 这样的内容,然后点击 Sources , 然后点击右侧 XHR 选项卡 的 + 在输入框中输入 /api/movie
这时我们在点击 翻页按钮 3 ,触发第 3 页的Ajax 请求
这里似乎看不到 构造 Ajax 的请求逻辑,这时我们可以使用 Call Stack 选项,一层一层的向下看,最后会看到一个叫做 onFetchData 的方法,切换到这个方法,然后格式化代码。
这里可以看到可能使用了 axios 库发起了一个 Ajax 请求,还有limit, offset , token 等参数。具体分析后面会有,这里知识作为一个寻找突破口的方法
取消断点,在 XHR 选项卡 取消勾选即可
改写 JS 文件
我们知道,一个网页里面的 JS 是从对应的服务器上下载并在浏览器上执行的。有时候我们会需要对 JS 进行一些更改方便调试,例如
发现 JS 文件包含很多阻挠调试代码或无效代码,干扰代码,想要将其删除
调试到某处,想要加一行 console.log 输出一些内容, 以便观察某个变量或方法在页面加载过程中的调用情况。在某些情况下,这种方法比打断点更方便
在调试过程中遇到某个局部变量或方法,想要把它赋值给 window 对象以便全局可以调用或访问
在调试的时候,得到的某个变量中可能包含一些关键的结果,想要加一些逻辑将这些结果转发到对应的目标服务器
这时候我们可以尝试在 Sources 面板对 JS 进行更改,但这种并不能长久生效,一旦刷新页面,更改就全部消失了。这时候就需要一些插件来实现。 例如 ReRes, 还有一些代理服务器也可以实现,例如 Charles , Fiddler ,借助它们可以在加载 JS 文件时修改对应 URL 的响应内容,以实现对 JS 的修改
首先找到需要修改的 JS 文件。例如前面找到的翻页 文件
步骤:
右键 2 ----检查----Network
复制: /api/movie ---点击 Sources ---右侧 点击 XHR/fetch Breakpoints 旁边的 + -----输入 /api/movie -----勾选上两个选项
此时断点已经生成, 点击 翻页 3 进入调试模式-----找到右侧 Call Stack ---- 下面的 onFetchData 点击 --- 就到了需要修改的地方
如果是第一次使用,则需要先在本地需要保存 JS 文件的地方新建一个文件夹 例如 ChromeOverrides -------然后在左边找到 Overrides 选项,如果没有,在 >> 里面找到-----
点击 + -----选择到刚刚新建的文件夹-----如果有提示选择允许---没有提示点击下面的 learn more ---选择允许,这样就指定了后面 JS 文件保存的位置
此时切换到刚刚找到的需要更改的 JS 文件
右键需要修改的 JS 文件 ---选择 Oerrides content---就会在刚刚新建的文件夹里生成一个和当前JS 文件同步的 JS 文件----在生成的新文件中修改----这里打印一下 a 的值
保存之后,结束当前的调试模式
然后取消断点
刷新页面,在 Console 页面就会打印出 a 的值
这里有些不一样的地方,是因为我是第二次使用