论js快照还原(rhino,autojs)
# 前言好久没发帖了,在我发布rhino js的dex还原教程之后,autojs官方推出了另一种编译类加密:快照加密,从刚开始我便已开始研究,最近已经有一些人发布了运用AST进行语义还原的视频,甚至快照也有初步的还原,所以也没有什么藏着掖着的必要了,在这做个总结吧。
# 简介
快照加密是一种编译类的加密,将js编译为仅有rhino能够识别的二进制字节码,所有的条件、循环逻辑都被编译为了goto跳转语句,且字节码类型比使用dex编译更为繁多,所以还原难度极大,且直接修改字节码可能导致跳转错位,整个js脚本无法正常运行,运行逻辑抗修改性也极强。迄今为止,我依旧不能还原所有的js。
# 所需工具
* rhino官方文档
* rhino源码一份(可于github获取)
* idea/eclipse
# 具体过程
##鉴别文件类型
刚开始,我拿到快照加密的结果,并不知道是什么类型的文件,所以可以去百度它的文件头。
从文件头可知这是一个java的序列化对象文件,然后再去翻rhino的官方文档。
由此可知使用ScriptableInputStream即可读取这种文件。
## 寻找逻辑代码
读取之后。通过获取这个对象的class可知其为InterpretedFunction,也就是经过解释的函数。
根据英文意义判断,数据都在InterpreterData里面。
根据我的经验,这几个变量对应的含义已经标注在图片里了。
## 解析逻辑代码
这些字节码我们也不知道它的含义,那就得从编译器下手了,编译器类为Interpreter类。打开之后往下翻发现一个特殊的方法。
本来想着不会是编译为字节码了吧,谁知道真特么给我来了个惊喜,这确实就是字节码,全是goto的那种。。。
## rhino内置AST
既然要还原,那肯定是要映射到一个AST上的,自己写一个AST太费劲,其它的解析库又不一定支持rhino的某些语法,最后发现rhino自带了一个js全套AST。
那么直接使用这套AST进行映射就行了。
## 确定还原方式
在各种查找调试之后,最终决定为模拟一个栈,自行解析所有字节码,栈的内容为AST节点,类比Interpreter将数据加载之后从栈里出栈读取拼凑之后再入栈,遇到结束字节码时插入AST作为节点。
遇到函数字节码时,先行解析对应函数的字节码为AST,再将生成的FunctionNode放入栈顶即可
最后从AST根部直接生成源代码即可成为一个完整可运行的js。
# 效果图
左边为源代码,右边为根据字节码还原出来的代码。
可以看到为了正常表达所在作用域,变量都被提前声明了,let被解析为了var,多了几个括号。但是整体逻辑都与源代码别无二致。
# 难点
* 从goto中抽取与运算&&和或运算||
* 从多层if嵌套中正确识别有无else
* 正确区分三元运算?:与if-else
* 正确识别循环中的break与continue语句
* 正确区分let与var
* 使用,分隔的多运算语句
# 结束语
至此,与rhino有关的dex与快照编译类加密都被窥得全貌,虽然不至于完美还原所有js(现在的程度也就还原v6到可运行),但是原理已经被许多人知悉。正所谓能运行那必能被破解,所以没有绝对安全的加密,只有破解成本远大于收益即是真正的安全。
好了,所有内容就这些,研究到后面也没什么意思了,我继续潜水摸鱼去了,下次我再次发帖或许是新加密出现的时候?(手动狗头)
***不要私聊我接不接单!仅限学习交流,不提供任何代码,有需求请自行编写代码!*** digyth 发表于 2021-7-10 18:18
源码丢出去那就乱了,我可不想被集火喷
现在就是等一段时间别人都把加密换得差不多了我再传git ...
不是要源码 我的意思 过程都没有 可以写一个样本作为例子讲解一下如何去还原 这样更好 yiwai2012 发表于 2021-7-11 09:28
不是要源码 我的意思 过程都没有 可以写一个样本作为例子讲解一下如何去还原 这样更好
大概15号我再发好了,缓一下,到时候把整个架构原理都发出来 6666666666666666 收藏备用 代码路上雾茫茫{:301_997:} 楼主你这个太高深了,我还是第一次听说 这是一个AUTO.JS的竟争作品么 牛年看牛人啊。。 感谢分享 学到了666666666 这个可以用来干啥 不明觉厉