2018.05.02 更新
这段时间我在翻备份硬盘,突然找到了之前的分析项目和代码,把之前附件的内容从中提取出来,现在上传给大家,真是又一个村子。 附件包括梦幻手游201703版提取的so文件和一些加密资源文件(包括lua脚本),以及2个斗鱼APK文件,最后打包了解密代码供大家参考。
附件太大了,都快100MB了,无法上传到山顶,所以又放到了百度云盘上……
链接: 密码:ipt3
2018.04.09 更新
实在找不到附件,所以你主要理解一下思路。 很多同学已经下载并保存了百度云盘的附件lua手游dump游戏源码,能否发一份到峰会上传? 谢谢谢谢~
2017.04.15 更新
1、编辑过程中删除了5.1后半部分(披露和反编译),现在添加了。
2、3.3中说的是“修改lua工程中的opcode后,编译生成lua.exe然后替换到反编译目录下,就可以反编译了”,这句话是错误的,正确的是“修改lua项目opcode后,重新编译反编译工具luadec51项目,就可以反编译了”lua手游dump游戏源码,已经被改了。
0. 序言
本文是我在研究android手游安全时总结的一篇关于lua的文章。 不足之处敬请谅解,欢迎大牛前来交流。 本文目录如下:
目录
0. 序言
1、手游中lua脚本的现状
2、lua、luac、luaJIT三个文件的关系
3.Lua脚本保护
3.1 普通对称加密,加载脚本前揭晓
3.2 将lua脚本编译成luaJIT字节码但加密打包
3.3 改变lua虚拟机中opcode的顺序
4.获取lua代码的常用技巧
4.1 静态分析揭示方法
4.2 动态调试:ida+idc+dump
4.3 钩索
4.4 分析lua虚拟机opcode的顺序
5、揭秘三款游戏的lua脚本过程
5.154 钓鱼
5.2 钓鱼大师4
5.3 梦幻西游手游
六、总结
参考文章
主要使用的工具和环境:
1 win7系统一
2quick-cocos2d-x开发环境(一个开发环境方便学习,但是大部分lua手游都使用cocos2d-x框架,还有一个用处,可以在源码的关键函数中查看特征字符串,以及然后在IDA中定位关键函数,非常方便)
3IDA6.8(分析so文件+动态调试so)
4vs2015(编译并展示代码)这里推荐使用vs2013编译运行cocos2d-x,vs2015的坑太多要填了...
5AndroidKiller1.3.1(反编译apk,其中apktool.exe为最新版本)
6luadec51(反编译luac)
7luajit-decomp(反编译luaJIT)
ETC...
1、手游中lua脚本的现状
轻微地。
2、lua、luac、luaJIT三个文件的关系
在学习lua手游的过程中,我遇到的lua文件大部分就是这三种类型。 其中lua是纯文本代码,可以直接用记事本打开,luac是lua编译后的字节码,文件头为0x1B0x4C0x750x610x51,lua虚拟机可以直接解析lua和luac脚本文件,luaJIT是另一种实现lua版本(不是原作者写的),JIT指Just-In-Time(即时解析运行),luaJIT比lua和luac效率更高,文件头为0x1B0x4C0x4A。
卢阿克:
卢吉特:
3.Lua脚本保护
通常有安全意识的游戏厂商不会直接将lua源码脚本打包成APK来发布,所以对lua脚本的保护通常有以下三种:
3.1 普通对称加密,加载脚本前揭晓
这些情况意味着APK中打包的lua代码是加密的,程序在加载lua脚本时泄露了秘密(关键函数luaL_loadbuffer),只有泄露秘密后才能获取lua源代码。 如果泄密后得到了luac字节码,那么通过反编译也可以得到lua源码。 反编译主要使用的工具是unluac和luadec51,接下来会详细分析。
3.2 将lua脚本编译成luaJIT字节码但加密打包
由于反编译的结果不容易查看,这些情况可以更好地保护lua源代码。 这种情况主要是泄密后反编译。 反编译主要是通过luajit-decomp项目,该项目也可以将luajit字节码反编译为伪lua代码。
3.3 改变lua虚拟机中opcode的顺序
这些情况主要是改变lua虚拟机的源代码,然后通过改变后的虚拟机将lua脚本编译成luac字节码,以达到保护的目的。 这些情况下,如果直接使用之前的反编译工具反编译luac,则需要分析短程序中对应的操作码,然后改变操作码在lua工程中的顺序,重新编译生成反编译工具,即可被反编译。 将详细分析。
通常里面的情况也会交叉相遇。
4.获取lua源码的常用技巧
这里主要有4种方法,将在第5节中举例说明。
4.1 静态分析揭示方法
这些技术需要分析揭开秘密的整个过程,费时又费力。 主要方法是通过ida定位到luaL_loadbuffer函数,然后回溯分析泄密的过程。
4.2 动态调试:ida+idc+dump
这里我们主要使用ida来动态调试so文件,然后定位到luaL_loadbuffer地址。 游戏启动时会通过调用luaL_loadbuffer函数加载必要的lua脚本。 通过在luaL_loadbuffer中设置断点,可以运行idc脚本转换lua代码导入(程序调用一次luaL_loadbuffer加载一个lua脚本,如果idc脚本不写,需要自动导入N次...) 。
4.3 钩索
与4.2ÿ原理相同