声明
本文仅供学习交流使用, 如侵立删!
目标网址
aHR0cHM6Ly95LnFxLmNvbS8=
JSVMP
JSVMP是一种JS代码虚拟化保护技术
原理是将JS源代码编译成自定义的字节码
这些字节码由操作码和操作数组成
并且这些字节码只能由特定的解释器执行
类比于解释型语言的实现与执行
比如
Java代码编译成Java字节码
由JVM执行
python代码编译成python字节码
由CPython执行
也就是说
JSVMP的本质是自定义字节码 + JS虚拟机的代码保护方案
目标代码
访问QQ音乐网址
使用关键字 P(r.data)
进行搜索
即可找到加密参数sign生成的代码位置
然后查看P函数代码
进入到了一个JSVMP中
这个JSVMP就是反编译的目标代码
JSVMP代码结构
浏览器中的JSVMP主要由两部分组成
加密自定义字节码
自定义虚拟机
JSVMP代码优化
在自定义虚拟机中
会对加密自定义字节码进行解密
并且在自定义虚拟机中
有两个相同的自定义解释器
第一个解释器
第二个解释器
针对自定义虚拟机的代码结构和运行流程
对其进行优化
方便后续反编译与调试
首先对加密自定义字节码进行解密
得到解密后的自定义字节码
然后删除与解密相关函数
最后对两个相同的自定义解释器
进行适当的修改
保留其中一个解释器
自定义虚拟机
自定义虚拟机主要分成三部分
执行环境(VMcontext)
对计算机执行环境的抽象模拟
在执行环境中
最重要的就是存储上下文环境信息的"容器"
根据这个"容器"结构
区分当前虚拟机是栈式虚拟机还是寄存器虚拟机
调度器(Dispatcher)
通过for循环和switch这种分发器结构实现的调度器
控制着程序正确的运行(取指和译码)
在调度器中
最关键的就是程序计数器PC
程序计数器控制着程序的执行流程
程序集(Handlers)
解释程序集由switch语句中的所有case块组成
每个case块对应一种自定义操作码的处理逻辑
反编译
根据程序集中不同case块所对应的处理逻辑
构建出相应的ast节点
从而生成js源代码的ast形式
最后将构建的ast转换成可读的js源代码
便完成了jsvmp的反编译
将JSVMP代码复制到Node环境中
引入Babel库
然后对虚拟机函数进行适当的修改
再创建一个数组变量
保存构建的ast节点
当虚拟机函数执行完后
将数组变量转换成program节点
最后将其转换成对应的js源码
写入到result_code.js文件中
自定义操作码节点构建
在JSVMP中
程序集一共有82个case块
根据执行流程
对执行case块进行相应的ast节点构建
因为case块比较多
这里只挑选其中几个进行讲解
case 2(函数声明)
case 46(函数声明)
case 2与case 46节点构建
case 21(算术运算)
case 21节点构建
反编译结果
对所有执行case块进行相应的节点构建后
运行程序
就得到了一份反编译代码
查看反编译代码
很容易就找到了加密方式
加密结果拼接
还有几个环境检测
运行环境检测
因为反编译后的代码有些难以阅读
同样需要进行优化
这时可以选择手动优化
也可以选择使用AI进行优化
这里我选择使用AI进行优化
优化完成后
就得到了一份程序功能等价
可阅读性和可调试性更高的代码
将优化后的代码替换浏览器的JSVMP代码
然后查看加密结果
最后查看验证请求
成功的通过了验证
说明反编译代码没有问题