逆向|cocos2dx xxtea逆向获取lua脚本和资源文件

第一次写博客,什么格式,排版都很low,大家不要喷我啊。。。
工具准备:

  1. IDA Pro 7,具体大家想用正版还是x版,自行决定。
  2. Android SDK 和 NDK
  3. AndroidEagleEye,链接地址为:AndroidEagleEye
  4. AndroidEagleEye需要XposedInstaller,直接百度下载一个最新的版本。我知道大家懒,所以链接为:XposedInstaller
  5. 一台ROOT之后的Andrid手机 或 雷电模拟器
好了,接下来接入正题。本文以一位网友发给我的一个叫做jjw.apk的【久久玩】的QP游戏。
解压缩APK文件,找到libs/armeabi/libcocos2d.so文件和位于assets目录下的src和res文件夹,这是我们需要解密的东西。我发现这个APK使用了xxtea加密。右击打开一个luac文件显示为:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
luac代码内容 我们在此处看到了lua加密的签名为红色圆圈中的内容,先找个文件记录一下,以后要用。
然后打开任意一张png图片,显示为:
png资源内容 我们同样找到了png资源的签名,找到刚才的文件,记录下来。
启动IDA Pro 7 把libcocos2dlua.so托到工具中。估计这玩意会有点卡,等待IDA分析完毕这个so文件,然后找到functions视图,如果你发现你的IDA上没有这个视图,请点击View->Open SubViews->Functions打开它。如下图:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
IDA Functions View 我们先来处理lua脚本。用过cocos2dxlua的都知道,引擎第一次加载lua脚本会调用cocos2d::LuaStack::executeScriptFile这个方法,所以我们选中Function Name窗口中任意一个方法,然后按下CTRL + F键,进行搜索。你会看到Function Name下方出现了一个输入框,在输入框中输入LuaStack,然后你会得到以下结果,如图所示:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
搜索LuaStack结果
? 我们开始对结果进行分析,最开始的时候我发现了一个很奇怪的乱码一样的方法,就是cocos2d::LuaStack::hfhgjrhrhfxs,上图中有显示,于是我就双击了这个方法。因为cocos2dx作为一个开源的引擎,官方的命名是固定规则的,那么这个方法肯定是一个自定义的方法。
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
hfhgjrhrhfxs方法 这个肯定是看的头大的,所以我们在这里按下F5,就会变成下面的样子:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
反编译之后的hfhgjrhrhfxs方法 看不出来有什么特别的地方,暂时不管他,通过上面的操作,我们暂时学会了,查找方法,类,以及反编译某个方法。接下来我们开始加速。
回到Functions window,双击cocos2d::LuaStack::executeScriptFile这个方法并进行反编译。拖动到最下边的时候发现了我们想找的方法cocos2d::LuaStack::luaLoadBuffer。如下图所示:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
找到luaLoadBuffer方法的调用 双击这个地方的方法进行跟进,我们发现了今天的正主:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
使用了xxtea加密 好了,我们关闭除了Functions window以外的所有窗口,然后搜索xxtea_decrypt方法,并双击,然后回打开以下内容
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
xxtea_decrypt方法汇编 记录下红色框中的内容,这是我们需要的方法的具体名称,我们之后的HOOK中需要用到。
红色框下方有两行绿色的方法,这是显示了,有某些地方调用到了这个方法,双击cocos2d::LuaStack::luaLoadBuffer(lua_State *,char const*,int,char const*)+D0↑p ...进去查看。
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
LuaStack::luaLoadBuffer中调用xxtea_decrypt的地方 我们发现这个方法的参数类型为:unsigned char* ,unsigned int, unsigned char*, unsigned int,unsigned int*,记录下来。
我找了LuaStack中的方法,发现并没有老板本cocos2dx的setxxteaKeyAndSign方法,所以我们只能通过以下方式来强行获取解密的key。
本文章使用的是雷电模拟器。打开雷电模拟器,并安装jjw.apk。
打开下载好的EagleEye,找到EagleEye.apk并安装。
安装Xposed Installer并安装激活Xposed框架,然后重启模拟器。安装完成以后,你应该看到以下界面:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
Xposed安装并激活框架 然后点击左上角的菜单按钮,选择【模块】并勾选EagleEye,重启Xposed。
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
启用EagleEye 找到EagleEye\jni\hooks\hook_apis.c文件并打开进行编辑。
刚才我们已经知道了需要HOOK的方法的所有信息,接下来,我们需要编写我们自己的HOOK API到这个文件的末尾。
unsigned char* eagle_xxtea_decrypt(unsigned char* a,unsigned int a1,unsigned char* b,unsigned int b1,unsigned int* c); HOOK_INFO custom_hook_info_xxtea_decrypt = {{},"libcocos2dlua","_Z13xxtea_decryptPhjS_jPj",eagle_xxtea_decrypt,eagle_xxtea_decrypt}; unsigned char* eagle_xxtea_decrypt(unsigned char* a,unsigned int a1,unsigned char* b,unsigned int b1,unsigned int* c) { unsigned char* (*orig_xxtea_decrypt)(unsigned char* a,unsigned int a1,unsigned char* b,unsigned int b1,unsigned int* c); struct hook_t eph = custom_hook_info_xxtea_decrypt.eph; orig_xxtea_decrypt = (void*)eph.orig; LOGI("###########COMING TO HOOK xxtea_decrypt with key: %s",b); hook_precall(&eph); unsigned char* res = orig_xxtea_decrypt(a,a1,b,b1,c); hook_postcall(&eph); return res; }

应该是有点懵逼的,没有关系,如果看不懂,就看看EagleEye的中文文档吧。这个代码的目的就是在Android的控制台打印出我需要的解密的key。
进入到EagleEye的安卓工程根目录:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
EagleEye的Android工程更目录 然后进入jni目录,ndk-build编译它。
然后在根目录新建配置文件,native_lib.config。这个文件告诉EagleEye,HOOK什么so文件。内容为:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
native_lib.config
这个so文件的名字就是我们刚才解压的apk里面的so文件名。
然后我们需要把编译好的EagleEye的so文件和native_lib.config这个文件推送到模拟器上。
新建doPush.bat批处理,内容如下:
adb push libs/armeabi/libeagleeyenative.so /data/data/com.mindmac.eagleeye/lib/libeagleeyenative.so adb push native_lib.config /data/data/com.jiujiuwan.jjw/native_lib.config pause

这个操作的目的是将libeagleeyenative.so这个文件推送到已经安装好的EagleEye中,将native_lib.config配置文件推送到需要破解的jjw.apk目录。
至于这个包名怎么来的,我想大家应该都知道吧,我就不说了。
然后打开你的命令行,找到jjw的userId:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
拿到jjw的userId 进入jjw.apk的安装路径,确保native_lib.config属性可读,并设置EagleEye的系统属性:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
设置文件可读性和EagleEye的属性 重启你的EagleEye和Xposed。找打Android SDK根目录->tools->monitor.bat等待Android Device Monitor开启,并检测到模拟器的日志输出。
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
Android Device Monitor 好了,现在启动你的jjw.apk,检查日志输出吧:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
HOOK日志 我们看到了两条不一样的日志输出,没关系。我在这边文章之前多HOOK了一个方法,毕竟这个apk的作者,把luaload过程改了一个遍,让我一顿好找,所以我又遵循之前的轨迹,找到了他修改的lua_loadx方法,于是,我给了一个HOOK:
int eagle_lua_loadx(int a1, int a2, int a3, const char *a4, int a5); HOOK_INFO custom_hook_info_lua_loadx = {{},"libcocos2dlua","lua_loadx",eagle_lua_loadx,eagle_lua_loadx}; int eagle_lua_loadx(int a1, int a2, int a3, const char *a4, int a5){ int (*orig_lua_loadx)(int a1, int a2, int a3, const char *a4, int a5); struct hook_t eph = custom_hook_info_lua_loadx.eph; orig_lua_loadx = (void*)eph.orig; LOGI("###########COMING TO HOOK lua_loadx with string: %s",a4); hook_precall(&eph); int result = orig_lua_loadx(a1,a2,a3,a4,a5); hook_postcall(&eph); return result; }

所以,这才看到了,我把加载的lua文件名给打印了出来。那么下方长的那个就是lua的密钥,短的嘛,肯定是png了啊。
接下来我们要做的就是,打开百度,搜索一个可以解密xxtea文件的玩意儿,我懒,所以我不想去写一堆解密代码了,传送门附带:XXTEA解密工具
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
XXTEA解密工具 好了,给大家看看结果吧:
逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
PNG解密之后 逆向|cocos2dx xxtea逆向获取lua脚本和资源文件
文章图片
解密之后的LUA代码 【逆向|cocos2dx xxtea逆向获取lua脚本和资源文件】以上便是今天的全部教程,感谢大家的观看。

    推荐阅读