dabai996 发表于 2021-1-11 16:19

问X手游中anglescript脚本引擎学习与研究

# 前言

该手游使用的脚本引擎为anglescript和lua。不同于lua,anglescript脚本引擎在google和baidu上基本找不到资料,抱着学习的目的,写下这篇文章。

关键的加密算法在anglescript的as脚本中,名称为data.cas,是一个编译后的字节码文件。关于(https://www.angelcode.com/angelscript/)的介绍请浏览官网。

## 学习与研究

拿到这款手游apk后,先看看是否加固,用了哪个脚本引擎。搜索一下字符串查找游戏发包位置,从so里面了解到,发包函数有可能在lua中或者anglescript中。具体在哪里还不好确定,我们可以dump出脚本。

先别急着动态调试,往往在收集信息的过程中有意想不到的惊喜。我们看下ios版本,用frida-ios-dump工具砸壳。解压出来发现了大量没有加密的lua脚本,从lua脚本分析结果来看发包函数在lua中,数据包的加密算法在anglescript中,加密函数为`gfParseK`和`gfParseK`。

通过简单的分析,基本上确定了加密算法的位置,还需要动态调试验证一下。

接下来我们从官网下载anglescript的sdk,随便下载一个版本,主要用来学习,找找有用的函数。因为我们还无法确定其中是用了哪一个版本的anglescript。

- 学习anglescript

从[官网](https://www.angelcode.com/angelscript/downloads.html)下载sdk,导入到clion中。简单的浏览源码,发现了几个关键的函数

```c
// 配置engine,用来配置anglescript用到的函数签名、模版类型等等。
// 也就是说在so里面也会用到这个函数配置engine。这真的是个好消息,距离成功又近了一步。
int ConfigureEngine(asIScriptEngine *engine, const char *configFile);

// as脚本加载之后会编译成cas字节码文件,下面的函数就是用来加载字节码文件。这对我们来说很有用,因为我们可以dump出解密后的cas字节码文件,用下面的函数自己加载。
int LoadScript(asIScriptEngine *engine, const char *scriptFile);
```

接下来我们继续分析anglescript汇编指令的执行细节,从as_restore.cpp中了解到,指令+参数的总长度4字节对齐,其中指令的长度为2字节。as_bytecode.cpp中的DebugOutput函数会打印执行的汇编指令。要打印data.cas中所有的函数签名则可以调用以下流程`engine->GetModule()->GetFunctionByIndex()->GetDeclaration()`

从打印的函数签名中,我们找到了`gfParseK`和`gfParseK`函数,证明了上面的分析没有错,接下来我们需要做一个测试验证我们的猜想:加载data.cas,调用gfParseK函数。

前面我们提到了,加载data.as脚本,调用脚本中的函数。需要注册大量的C++函数。重新实现这些函数,很麻烦。

## 漫漫长征路

我们用到了以下工具:

1. frida
2. ida
3. android studio

从so里面dump出解密后的data.cas

- 从anglescript sdk中我们学习到一个函数`CScriptBuilder::LoadByteCode`,该函数从内存中加载字节码文件。所有我们用frida进行hook,成功导出了data.cas。

dump出config文件

- 同样我们用frida 调用函数`WriteConfigToFile`,实验中发现无法调用。 所以采用android inline hook的方式进行调用,先hook`CScriptBuilder::StartNewModule`获取到engine,然后hook`CScriptBuilder::LoadByteCode`,在这里调用`WriteConfigToFile`函数成功输出config文件

到这里我们的准备工作算是做完了,剩下就差将字节码反汇编成汇编指令了。要完成转译工作,仍然是学习anglescript sdk源码。具体过程如下:

1. 创建engine`asIScriptEngine *engine = asCreateScriptEngine()`
2. 配置config`ConfigureEngine(engine, "config.txt");`
3. 开启一个module`builder.StartNewModule(engine, "mymodule");`
4. 加载字节码`module->LoadByteCode()`
5. 通过module打印所有函数签名`module->GetFunctionCount()`,`module->GetFunctionByIndex(i)->GetDeclaration`

`asIScriptFunction`保存了一个函数的所有信息。通过这个结构可以获取到该函数的所有汇编指令,指令同样用一个结构体保存`asSBCInfo`。

从`as_context.cpp`的`execute`函数中我们找到了最终汇编指令执行的过程,并且`DebugOutput`中也存在字节码转译汇编指令的过程。

编写代码翻译函数中的所有`asSBCInfo`,我们很轻松的得到了`gfParseK`和`gfParseK`函数的汇编指令,然后参考官方的文档还原出了这两个函数的C语言版本。

## 讨论

在整个过程中,很清晰能体会到的问题是脚本引擎的代码保护强度非常薄弱,lua脚本在ios中直接就是明文了,虽然anglescript进行了加密,但是并不能很好的隐藏关键代码,反而是协议部分相对复杂,有种舍本逐末的感觉。

## 最后

附上两个函数的汇编指令:

```c
uint gfParseM(uint m, uint a)
Variables:
- uint m
- uint a
- uint8 i1
- uint8 i2
- uint8 m1
- uint8 m2
- uint r
Code:
@0x0000 SUSPEND
@0x0001 SetV4 v2, 0xff0000          (i:16711680, f:16711680)
@0x0003 BAND v2, v65535, v2
@0x0005 SetV4 v3, 0x10          (i:16, f:16)
@0x0007 BSRL v2, v2, v3
@0x0009 iTOb v2
@0x000a CpyVtoV4 v1, v2
@0x000c SUSPEND
@0x000d SetV4 v3, 0xff          (i:255, f:255)
@0x000f BAND v2, v65535, v3
@0x0011 iTOb v2
@0x0012 CpyVtoV4 v4, v2
@0x0014 SUSPEND
@0x0015 SetV4 v3, 0xff00          (i:65280, f:65280)
@0x0017 BAND v2, v0, v3
@0x0019 SetV4 v6, 0x8          (i:8, f:8)
@0x001b BSRL v3, v2, v6
@0x001d iTOb v3
@0x001e CpyVtoV4 v5, v3
@0x0020 SUSPEND
@0x0021 SetV4 v6, 0xff          (i:255, f:255)
@0x0023 BAND v3, v0, v6
@0x0025 iTOb v3
@0x0026 CpyVtoV4 v7, v3
@0x0028 SUSPEND
@0x0029 CpyVtoV4 v6, v5
@0x002b ubTOi v6
@0x002c CpyVtoV4 v3, v1
@0x002e ubTOi v3
@0x002f BXOR v2, v6, v3
@0x0031 CpyVtoV4 v8, v4
@0x0033 ubTOi v8
@0x0034 BXOR v3, v2, v8
@0x0036 iTOb v3
@0x0037 CpyVtoV4 v5, v3
@0x0039 SUSPEND
@0x003a CpyVtoV4 v8, v7
@0x003c ubTOi v8
@0x003d CpyVtoV4 v3, v4
@0x003f ubTOi v3
@0x0040 BXOR v2, v8, v3
@0x0042 iTOb v2
@0x0043 CpyVtoV4 v7, v2
@0x0045 SUSPEND
@0x0046 CpyVtoV4 v3, v5
@0x0048 ubTOi v3
@0x0049 CpyVtoV4 v9, v3
@0x004b SUSPEND
@0x004c SetV4 v2, 0x8          (i:8, f:8)
@0x004e BSLL v3, v9, v2
@0x0050 CpyVtoV4 v6, v7
@0x0052 ubTOi v6
@0x0053 BOR v2, v3, v6
@0x0055 CpyVtoR4 v2
@0x0056 RET 2


uint gfParseK(uint k, uint a)
Variables:
- uint k
- uint a
- uint8 i1
- uint8 i2
- uint8 i3
- uint8 i4
Code:
@0x0000 SUSPEND
@0x0001 SetV4 v2, 0x18          (i:24, f:24)
@0x0003 BSRL v2, v0, v2
@0x0005 iTOb v2
@0x0006 CpyVtoV4 v1, v2
@0x0008 SUSPEND
@0x0009 SetV4 v2, 0xff0000          (i:16711680, f:16711680)
@0x000b BAND v2, v0, v2
@0x000d SetV4 v4, 0x10          (i:16, f:16)
@0x000f BSRL v2, v2, v4
@0x0011 iTOb v2
@0x0012 CpyVtoV4 v3, v2
@0x0014 SUSPEND
@0x0015 SetV4 v4, 0xff00          (i:65280, f:65280)
@0x0017 BAND v2, v0, v4
@0x0019 SetV4 v6, 0x8          (i:8, f:8)
@0x001b BSRL v4, v2, v6
@0x001d iTOb v4
@0x001e CpyVtoV4 v5, v4
@0x0020 SUSPEND
@0x0021 SetV4 v6, 0xff          (i:255, f:255)
@0x0023 BAND v4, v0, v6
@0x0025 iTOb v4
@0x0026 CpyVtoV4 v7, v4
@0x0028 SUSPEND
@0x0029 CpyVtoV4 v6, v3
@0x002b ubTOi v6
@0x002c CpyVtoV4 v4, v7
@0x002e ubTOi v4
@0x002f BOR v65535, v6, v4
@0x0031 SUSPEND
@0x0032 SetV4 v4, 0x8          (i:8, f:8)
@0x0034 BSLL v2, v65535, v4
@0x0036 CpyVtoV4 v6, v1
@0x0038 ubTOi v6
@0x0039 BOR v4, v2, v6
@0x003b CpyVtoV4 v8, v7
@0x003d ubTOi v8
@0x003e BOR v65535, v4, v8
@0x0040 SUSPEND
@0x0041 SetV4 v8, 0x8          (i:8, f:8)
@0x0043 BSLL v6, v65535, v8
@0x0045 CpyVtoV4 v2, v1
@0x0047 ubTOi v2
@0x0048 BOR v8, v6, v2
@0x004a CpyVtoV4 v4, v3
@0x004c ubTOi v4
@0x004d BOR v65535, v8, v4
@0x004f SUSPEND
@0x0050 SetV4 v4, 0x8          (i:8, f:8)
@0x0052 BSLL v2, v65535, v4
@0x0054 CpyVtoV4 v4, v1
@0x0056 ubTOi v4
@0x0057 CpyVtoV4 v8, v3
@0x0059 ubTOi v8
@0x005a BXOR v6, v4, v8
@0x005c BOR v65535, v2, v6
@0x005e SUSPEND
@0x005f CpyVtoR4 v65535
@0x0060 RET 2
```

dabai996 发表于 2021-1-11 19:42

豆虫 发表于 2021-1-11 19:12
楼主对那种三端的H5页游有研究不?望指点一二. 应该往哪个方向研究,谢谢!
因为像这种游戏,app也才5M, ...

看看资源文件,判断用了哪个h5游戏引擎。然后去搜索相关的引擎逆向资料。

一片小朵朵 发表于 2021-1-11 19:40

豆虫 发表于 2021-1-11 19:12
楼主对那种三端的H5页游有研究不?望指点一二. 应该往哪个方向研究,谢谢!
因为像这种游戏,app也才5M, ...
这只是封装了一个首页入口,加载游戏的时候需要从cdn上下载图片 声音 其他资源文件。你可以把所有的资源文件路径获取到,自己写个脚本去爬取

豆虫 发表于 2021-1-11 19:12

楼主对那种三端的H5页游有研究不?望指点一二. 应该往哪个方向研究,谢谢!
因为像这种游戏,app也才5M,接收的json也都是一些图片的点位。
网上找了很多也只是关于图片,文字识别类的教程。

stefankuok 发表于 2021-1-12 10:30

不明觉厉

addqcx 发表于 2021-1-12 12:07

知道了,谢谢

丿昶灬雨 发表于 2021-1-12 13:32

知道了,谢谢

dollm 发表于 2021-1-12 14:13

尝试多种方式解决问题,学习了

奶爸老虎 发表于 2021-1-12 14:25

这个有大用了!!!!

wswgy315 发表于 2021-1-12 16:19

不明觉厉
页: [1] 2
查看完整版本: 问X手游中anglescript脚本引擎学习与研究