digyth 发表于 2021-7-18 10:02

[autojs]js反编译还原详解(AST转换,二进制转AST)

本帖最后由 digyth 于 2021-7-18 10:35 编辑

# 简介
  autojs(后面简称aj)是一款基于rhino引擎依赖无障碍进行自动点击操作的安卓APP,类似电脑上的按键精灵,不过功能更加强大,可以打包为独立的APP。因此有许多人在使用它开发一些小程序,免去了AndroidStudio复杂的开发流程。
  但是本来aj对源码的保护并不强,于是很多人为了防止别人获取源码,有了加密的需求,先是出现了庖丁用于编译为dex进行加密,后面aj官方也推出了dex加密与快照加密。
## Dex加密
  将js编译为直接操作rhino运行的java字节码,运行效率高,且不易被还原为js源代码。
## 快照加密
  将js编译为只可被rhino解析运行的二进制字节码,这个加密比较新颖,所以很难找到现成的工具对其进行有效分析还原。
# 前言
  刚开始接触aj的时候是玩游戏,某位好友使用aj去执行一些简单的重复操作,然后知道js可以被编译为dex很是新奇,便开始研究其中的原理。

  在对比了多个js的源代码与编译结果后,发现了一些规律,开始尝试对其进行还原。刚开始并不会AST,在还原了一些dex为等价js,逐渐熟练java与js的AST后,继续攻克了快照的还原。

# 还原过程

## 所需工具

1. rhino(需与autojs内置版本一致,可从apk提取)

2. javaparser

3. rhino源码

4. idea或eclipse

## 创建样本

由于只是说明原理,就不创建过于复杂的了,容易看到眼花。

在这里,分别使用dex与快照进行加密。

### Dex样本提取

将apk内的classes.dex提取出来,用MT打开提取的classes.dex,找到这个包名。

选中这个包名,然后反选删掉多余的类,得到纯粹带js逻辑的dex。

### 快照样本提取

将apk中/assets/project目录整个复制出来。

为了节省时间,使用庖丁的兼容方式对其进行第一层的解密。

## 样本



## Dex加密还原

先使用jadx等反编译器将其反编译为java。

经过分析,call方法为脚本入口点,_c_script_0为脚本根节点,正则表达式被放置在_reInit方法内动态初始化。

分析完毕后,便开始模拟运行过程,缓存全局变量、正则表达式、函数id映射表(多函数时出现,call中将出现大型switch),通过递归解析java的AST同步生成js的AST,即可得到一个完整的js。

## 快照加密还原

如何解析快照,可参考我之前的**[文章](https://www.52pojie.cn/thread-1473361-1-1.html)**

使用dumpICode之后,可以看到如上字节码信息,js被编译之后只有顺序与跳转两种运行逻辑,类似汇编。在与源代码对照之后,可以大概分析出每个语句块的含义(已在图中标注)。

至于如何还原字节码为js代码,首先必定是需要先拼凑出一个完整的AST,最终选定的方法为模拟解释器运行,栈的存储内容改为AST节点。

由此进行不断地入栈出栈,即可拼凑出一个完整的AST,最终生成结果与dex没有任何区别。
# 结束语
  随着变量与函数的增加,实际情况远比样本复杂得多(例如dex会出现大量多余的逻辑,快照会出现很多跳转与偏门的字节码),知道原理之后其实大同小异,只是如何优化的问题。

  由于并不清楚所有指令对应的结构,这两种加密的还原都没法一步到位,只能通过多种js的源码与加密后的指令进行对照一步步完善。(或许有大佬能直接对照rhino的编译部分写)

  ***本人并非专业逆向爱好者,llvm和antlr等汇编工具根本不会,刚开始AST都不会,整个过程都是从零开始瞎鼓捣出来的,恕本人才疏学浅,请各位大佬轻喷。***

digyth 发表于 2021-7-18 20:26

ogli324 发表于 2021-7-18 20:14
有几个疑问,可以解答吗?

1. js可以被编译为dex 是真的吗?


1.是真的,但是仅限于rhino引擎。
2. AST是抽象语法树,具体百科都有,是编译器必要的一个中间处理过程。至于js代码,已经被编译为对解释器的直接操作逻辑了,所以整个运行流程中不再存在js代码,没有解密js代码的过程自然无法dump。

盖世英雄哦哦哦 发表于 2023-12-29 14:15

本帖最后由 盖世英雄哦哦哦 于 2023-12-30 20:27 编辑

请教如何自己维护不同的情况 不知道如何更改字节码对应的指令等关系 哪里有教程或者步骤麻烦告知一下
我现在的报错就是 不知道怎么处理
Exception in thread "main" java.lang.Exception: unknown instruction STRING in 4
        at SnapshotDecompiler$Decompiler.run(SnapshotDecompiler.kt:99)
        at SnapshotDecompiler$Decompiler.decompile(SnapshotDecompiler.kt:32)

芽衣 发表于 2021-7-18 10:32

沙发不留了{:301_1001:}

fdsa123q 发表于 2021-7-18 19:10

来了来了。终于来了。等你发这文章好久了

ogli324 发表于 2021-7-18 20:14

有几个疑问,可以解答吗?

1. js可以被编译为dex 是真的吗?
2. ast的概念是啥?这个js代码, 不是直接dump就好了吗?

yiwai2012 发表于 2021-7-18 22:50

哇哦 终于等到大佬再次发文了 学习学习

atrago 发表于 2021-7-19 12:34

楼主讲的好详细

阿木木不哭 发表于 2021-7-19 13:55

好强,学习了

ywsms 发表于 2021-7-19 15:43

谢谢分享,学习了

173035 发表于 2021-7-19 16:40

请问楼主个问题
是需要解两次嘛,第二层是解auto解完的那次嘛
页: [1] 2 3 4
查看完整版本: [autojs]js反编译还原详解(AST转换,二进制转AST)