网上各种教程、各种工具用不了,才会有这个文章。
0x00 lua bytecode解密
知己知彼很重要,搜索“cocos2dx lua 加密”大概可以找到类似下面的代码。
我的目标是一个ANDROID游戏,APK文件直接解压。一般情况是libcocos2dlua.so,IDA 打开,函数窗口直接搜索applicationDidFinishLaunching,就能带你飞,可惜只有loadChunksFromZip,没有setXXTEAKeyAndSign,这保存解密KEY的被编译优化了。怎么办?IDA字符串窗口帮你忙,编译器编译代码的时候都是就近原则,只要是差不多地方出现的字符串,都会被放在一起。加密的ZIP文件,文件头几个字符就是setXXTEAKeyAndSign的SIGN参数,加上ZIP文件本身的路径,搜索目标ZIP文件就可以了。如图,IDA显示附近也就几个字符串,剩下的KEY参数是哪个,一个一个试就可以了。
加密的ZIP文件:
IDA中的字符串,第一个黑块是SIGN参数,非常幸运,尝试第二个黑块就是KEY:
https://github.com/cocos2d/cocos2d-x/search?p=1&q=loadChunksFromZip&type=&utf8=%E2%9C%93 找到cocos2dx的loadChunksFromZip的源码
这里我遇到一点困难,cocos2dx的源码项目,没有xxtea的源码!不过还是让我在github搜索出来了,源码在此:
https://github.com/xxtea/xxtea-c
直接写个C++代码,就把加密的ZIP解出来了。顺带一提,Sign就是用来跳过,跟什么PE,MZ是一样的。
de_xxx.zip的头两个字节变成喜闻乐见的PK,解压,搞定。
Luajit ASM
解压出来的文件,都是LuaJIT— a Just-In-Time Compiler for Lua,文件头长这样:
http://luajit.org/download.html 可以下载到LuaJIT的源码,不过兼容性有点糟糕,需要找到正确的版本才有效。回到IDA字符串窗口搜索luajit,可以确认目标APK使用的是2.1.0-beta2。下载源码,编译之后,使用类似下面的命令行:
luajit.exe -bl xxx.lua.bytecode xxx.lua.asm
可以看到LUA的ASM代码了,LUA ASM长这样:
0013 TGETV 4 4 1
0014 CALL 3 4 2
0015 ISNEXT 6 => 0019
0016 => MOV 8 7
0017 MOV 9 2
0018 CALL 8 1 2
0019 => ITERN 6 3 3
0020 ITERL 6 => 0016
0021 RET0 0 1
BYTECODE的定义在http://wiki.luajit.org/Bytecode-2.0 。不过我智商不够,看不懂,
0x01 Luajit decompiler
搜索了无数反编译文章,基本就是https://github.com/NightNord/ljd ,然而这货2014年之后就再没更新了,并不能用,没有选择,只能自己动手改。
1). 由于新Opcode导致的失败
luajit 2.1.0-beta2源码的lj_bc.h里的#define BCDEF,下方就是长长一串Opcode定义。
Ljd源码的bytecode\instructions.py 和 rawdump\code.py的两张Opcode表必须跟luajit 2.1.0-beta2 一一对比,少了的就要补上。
这里不得不吐槽一下luajit,新增Opcode其实并没有人用,Opcode是通过数组维护的,随便加个新的Opcode都会导致原有的Opcode编码改变。。。
2). 由于assert导致的失败,注释掉就好了。虽说有点不负责,但是反编译各种语法处理我也不懂。
LJD改好之后,main.py xxx.lua.bytecode > xxx.lua,终于可以看到正常的代码:
完毕!附件请查看原文下载。
❤ 往期热门内容推荐
更多优秀文章,长按下方二维码,“关注看雪学院公众号”查看!
看雪论坛:http://bbs.pediy.com/
微信公众号 ID:ikanxue
微博:看雪安全
投稿、合作:www.kanxue.com