参考链接:

https://blog.csdn.net/cjbbdd/article/details/103583764

使用的一些注意点,链接中未提到的:

1.NDK版本:

使用的ndk版本为r9d,下载地址:

  • windows:https://dl.google.com/android/ndk/android-ndk-r9d-windows-x86_64.zip
  • linux:https://dl.google.com/android/ndk/android-ndk-r9d-linux-x86_64.tar.bz2

参考博客有大部分ndk版本下载:Android开发之NDK相关版本下载链接

2.获取包名

参考博客:如何获取Android的apk的包名及其入口

主要使用的指令为:

aapt dump badging <*.apk的完整路径>。(可以直接将.apk文件拖拽到命令行中,可直接获取.apk的完整路径)

3.模拟器

参考博客使用的是雷电模拟器,我使用的是夜神模拟器,博客连接安装的XposedInstaller并不能在夜神模拟器上正常运行,其实一般的模拟器都有XposedInstaller的下载地址,下载对应的版本即可。夜神模拟器在游戏中心,搜索框输入XposedInstaller下载即可。

雷电模拟器的一些问题:

(1)执行adb service 提示报错

adb server version (36) doesn't match this client (41); killing...

从报错信息上看,是由于SDK 的adb与夜神模拟器的adb的版本不匹配导致的。

解决办法

  1. 把AndroidSDK\platform-tools下的adb.exe赋值到桌面上,重命名为nox_adb.exe
  2. 把夜神模拟器下的nox_adb.exe修改为nox_adb_old.exe
  3. 把桌面上的nox_adb.exe拷贝到夜神模拟器下bin路径下
  4. 重启夜神模拟器

参考博客:解决adb server version (36) doesn‘t match this client (41); killing...

(2)AndroidStdio DDMS连接夜神模拟器

AndroidStdio打开DDMS方式:Tools——>Android——>android devices monitor. 
        问题:若打开DDMS后没有显示连接的device。         
        解决办法: 
        ①先启动夜神模拟器

②然后运行cmd命令,cd到夜神安装目录(bin文件夹下),执行命令nox_adb.exe connect  127.0.0.1:62001或直接打开夜神模拟器安装目录(bin文件夹),然后在地址栏输入adb回车,再执行命令nox_adb.exe connect 127.0.0.1:62001或将夜神模拟器安装目录(bin文件夹)路径,配置在环境变量path中,直接执行cmd命令nox_adb.exe connect 127.0.0.1:620010即可连接到模拟器

③如果无法看到夜神模拟器,请adb后,重新启动下夜神模拟器

④注意:不要开启其他模拟器,因为夜神模拟器与其他模拟器不兼容(开启多个不同种类模拟器,会同时开启多个adb.exe进程,而系统只能识别一个adb.exe进行)

参考链接:AndroidStdio DDMS连接夜神模拟器

4.AndroidEagleEye 源码修改:

(1)如果日志报错提示‘cannot read memory map’,可能原因是加载内存map的缓存过小,load_memmap函数需要将raw数组大小,加载的内存map数据可能会超过缓存大小。

static int load_memmap(pid_t pid, struct mm *mm, int *nmmp)
{char raw[80000]; // increase this if needed for larger "maps"// 将80000修改为更大的缓存大小,80000->800000// ...
}

(2) 如果日志报错提示‘cannot read symbol table’,可能是加载libc.so符号集的open函数读取文件失败,实际系统文件是存在的,根据内存map读取的是‘/system/lib/arm/nb/libc.so’,但open函数读取文件失败,调用strerror(errno)错误提示为文件不存在(No such file or directory),具体原因未知,

R11 Plus:/ # ll /system/lib/arm/nb/libc.so
-rw-r--r-- 1 root root 1011828 2021-10-23 01:05 /system/lib/arm/nb/libc.so

查看根目录发现如下链接

R11 Plus:/ # ll /
total 1832
dr-xr-xr-x  17 root   root         0 2023-02-23 18:07 acct
lrwxrwxrwx   1 root   root        50 1970-01-01 08:00 bugreports -> /data/user_de/0/com.android.shell/files/bugreports
drwxrwx---   6 system cache     4096 2021-09-18 10:26 cache
lrwxrwxrwx   1 root   root        13 1970-01-01 08:00 charger -> /sbin/healthd
dr-x------   2 root   root        40 1970-01-01 08:00 config
lrwxrwxrwx   1 root   root        17 1970-01-01 08:00 d -> /sys/kernel/debug
drwxrwx--x  34 system system    4096 2021-09-18 10:26 data
-rw-r--r--   1 root   root       959 1970-01-01 08:00 default.prop
drwxr-xr-x  17 root   root      4020 2023-02-23 18:07 dev
lrwxrwxrwx   1 root   root        11 1970-01-01 08:00 etc -> /system/etc
-rw-r--r--   1 root   root     77090 1970-01-01 08:00 file_contexts.bin
-rw-r-----   1 root   root       396 1970-01-01 08:00 fstab.qcom
-rwxr-x---   1 root   root   1490548 1970-01-01 08:00 init
-rwxr-x---   1 root   root       887 1970-01-01 08:00 init.environ.rc
-rwxr-x---   1 root   root      3689 1970-01-01 08:00 init.qcom.rc
-rwxr-x---   1 root   root     25284 1970-01-01 08:00 init.rc
-rwxr-x---   1 root   root       582 1970-01-01 08:00 init.superuser.rc
-rwxr-x---   1 root   root      9283 1970-01-01 08:00 init.usb.configfs.rc
-rwxr-x---   1 root   root      5716 1970-01-01 08:00 init.usb.rc
-rwxr-x---   1 root   root       411 1970-01-01 08:00 init.zygote32.rc
lrwxrwxrwx   1 root   root        10 2023-02-23 18:07 lib -> system/lib

最下面有一个lib与system/lib的链接,推测应该是android系统与底层linux之间的问题,故此在源代码load_symtab函数中做了路径替换

static symtab_t load_symtab(char *filename)
{int fd;symtab_t symtab;symtab = (symtab_t) xmalloc(sizeof(*symtab));memset(symtab, 0, sizeof(*symtab));// 增加的替换路径代码 开始if (strncmp("/system/lib", filename, 11) == 0) {char strtmp[1024] = "/lib";strncpy(strtmp + 4, filename + 11, strlen(filename) - 11);memset(filename, 0, strlen(filename));strncpy(filename, strtmp, sizeof(strtmp));}// 增加的替换路径代码 结束fd = open(filename, O_RDONLY);if (0 > fd) {return NULL;}if (0 > do_load(fd, symtab)) {log("Error ELF parsing %s\n", filename)free(symtab);symtab = NULL;}close(fd);return symtab;
}

5.参考博客文章,为避免失效,直接复制下来的,如有侵权还请告知删除:

参考链接:cocos2dx xxtea逆向获取lua脚本和资源文件_cjbbdd的博客-CSDN博客_xxtea lua

工具准备:
IDA Pro 7,具体大家想用正版还是x版,自行决定。
Android SDK 和 NDK
AndroidEagleEye,链接地址为:AndroidEagleEye
AndroidEagleEye需要XposedInstaller,直接百度下载一个最新的版本。我知道大家懒,所以链接为:XposedInstaller
一台ROOT之后的Andrid手机 或 雷电模拟器
好了,接下来接入正题。本文以一位网友发给我的一个叫做jjw.apk的【久久玩】的QP游戏。

解压缩APK文件,找到libs/armeabi/libcocos2d.so文件和位于assets目录下的src和res文件夹,这是我们需要解密的东西。我发现这个APK使用了xxtea加密。右击打开一个luac文件显示为:

luac代码内容
我们在此处看到了lua加密的签名为红色圆圈中的内容,先找个文件记录一下,以后要用。

然后打开任意一张png图片,显示为:

png资源内容
我们同样找到了png资源的签名,找到刚才的文件,记录下来。

启动IDA Pro 7 把libcocos2dlua.so托到工具中。估计这玩意会有点卡,等待IDA分析完毕这个so文件,然后找到functions视图,如果你发现你的IDA上没有这个视图,请点击View->Open SubViews->Functions打开它。如下图:

IDA Functions View
我们先来处理lua脚本。用过cocos2dxlua的都知道,引擎第一次加载lua脚本会调用cocos2d::LuaStack::executeScriptFile这个方法,所以我们选中Function Name窗口中任意一个方法,然后按下CTRL + F键,进行搜索。你会看到Function Name下方出现了一个输入框,在输入框中输入LuaStack,然后你会得到以下结果,如图所示:

搜索LuaStack结果

我们开始对结果进行分析,最开始的时候我发现了一个很奇怪的乱码一样的方法,就是cocos2d::LuaStack::hfhgjrhrhfxs,上图中有显示,于是我就双击了这个方法。因为cocos2dx作为一个开源的引擎,官方的命名是固定规则的,那么这个方法肯定是一个自定义的方法。

hfhgjrhrhfxs方法
这个肯定是看的头大的,所以我们在这里按下F5,就会变成下面的样子:

反编译之后的hfhgjrhrhfxs方法
看不出来有什么特别的地方,暂时不管他,通过上面的操作,我们暂时学会了,查找方法,类,以及反编译某个方法。接下来我们开始加速。

回到Functions window,双击cocos2d::LuaStack::executeScriptFile这个方法并进行反编译。拖动到最下边的时候发现了我们想找的方法cocos2d::LuaStack::luaLoadBuffer。如下图所示:

找到luaLoadBuffer方法的调用
双击这个地方的方法进行跟进,我们发现了今天的正主:

使用了xxtea加密
好了,我们关闭除了Functions window以外的所有窗口,然后搜索xxtea_decrypt方法,并双击,然后回打开以下内容

xxtea_decrypt方法汇编
记录下红色框中的内容,这是我们需要的方法的具体名称,我们之后的HOOK中需要用到。

红色框下方有两行绿色的方法,这是显示了,有某些地方调用到了这个方法,双击cocos2d::LuaStack::luaLoadBuffer(lua_State *,char const*,int,char const*)+D0↑p ...进去查看。

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框架,然后重启模拟器。安装完成以后,你应该看到以下界面:

Xposed安装并激活框架
然后点击左上角的菜单按钮,选择【模块】并勾选EagleEye,重启Xposed。

启用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的安卓工程根目录:

EagleEye的Android工程更目录
然后进入jni目录,ndk-build编译它。

然后在根目录新建配置文件,native_lib.config。这个文件告诉EagleEye,HOOK什么so文件。内容为:

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:

拿到jjw的userId
进入jjw.apk的安装路径,确保native_lib.config属性可读,并设置EagleEye的系统属性:

设置文件可读性和EagleEye的属性
重启你的EagleEye和Xposed。找打Android SDK根目录->tools->monitor.bat等待Android Device Monitor开启,并检测到模拟器的日志输出。

Android Device Monitor
好了,现在启动你的jjw.apk,检查日志输出吧:

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解密工具

XXTEA解密工具
好了,给大家看看结果吧:

PNG解密之后

解密之后的LUA代码
以上便是今天的全部教程,感谢大家的观看。

【笔记】cocos2dx xxtea逆向获取lua脚本和资源文件相关推荐

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

    第一次写博客,什么格式,排版都很low,大家不要喷我啊... 工具准备: IDA Pro 7,具体大家想用正版还是x版,自行决定. Android SDK 和 NDK AndroidEagleEye, ...

  2. 血族手游Lua脚本及资源文件解密

    之前一直和朋友在玩手游血族.有一天朋友问我能不能把里面某个角色的立绘拿下来.当时没多想就答应了,以为只要解压找到图片就行了.但是万万没想到,图片竟然打不开(被加密了). 快速分析 下载最新的血族apk ...

  3. 在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)

    对于游戏公司而言,采用游戏脚本lua.python等进行开发也很常见,但是很多童鞋对脚本并没有很熟悉的概念,本篇则向大家简单介绍脚本的用途以及在Cocos2dx基础用法: Lua和python这些详细 ...

  4. freeswitch学习笔记:将电话路由到Lua脚本

    在快速测试的情况下,可以直接使用如下的originate命令在FreeSWITCH中外呼一路通话,并在电话的本端执 行Lua脚本: originate user/1000 &lua(test. ...

  5. 【Rainmeter】写Lua脚本遇到的文件读写问题

    在为Rainmeter写lua脚本的时候,如果需要文件读写(io)操作,需要注意的是不管lua脚本是哪个skin或者哪个组件调用的,它的工作目录都不是组件的根目录(即.ini文件所在的位置),而是在R ...

  6. java资源文件获取属性_Java读写资源文件类Properties

    Java中读写资源文件最重要的类是Properties 1) 资源文件要求如下: 1.properties文件是一个文本文件 2.properties文件的语法有两种,一种是注释,一种属性配置. 注  ...

  7. 安卓获取res下的资源文件:string字符串、color颜色、dimen尺寸、array数组、drawable图片和xml、anim/animator动画、raw媒体、assets资源

    全栈工程师开发手册 (作者:栾鹏) 安卓教程全解 安卓获取内部资源并应用. 1.获取res/values文件夹下的string.xml的字符串.color.xml的颜色.dimen.xml的尺寸.ar ...

  8. android apk反编译(获取源码,资源文件等)

    android apk反编译,是让你可以去借鉴别人的应用是怎么开发的,那些漂亮的动画和精致的布局是怎么实现的 一.当然我们也需要借助工具: apktool (资源文件获取,可以提取出图片文件和布局文件 ...

  9. android获取drawable路径,从资源文件中获取drawable

    丑话说前头,本文转自: http://stackoverflow.com/questions/29041027/android-getresources-getdrawable-deprecated- ...

最新文章

  1. 第十四周项目二-两个成员的类模版(1)
  2. POJ3345 Bribing FIPA 【背包类树形dp】
  3. 后现代婚礼机器人显神通_机器人显神通
  4. 并发基础篇(四): java中线程的状态深入浅出
  5. 拓荒会员电商“无人区”,考拉海购能否拿下“新船票”?
  6. Linux学习之系统编程篇:使用条件变量实现“生产者和消费者模型”
  7. ajax二级联动源代码,Ajax二级联动菜单实现原理及代码
  8. java虚拟机读写其他进程的数据
  9. stack overflow--技术问答网站
  10. python控制步进电机驱动器_树莓派操作案例1-使用python GPIO+TB6612驱动步进电机
  11. 智能音箱“好耳朵”的设计奥秘
  12. redis mysql 事务_Mysql与Redis事务
  13. 转载关于星座理论的套路
  14. 后门及持久化访问1----辅助功能镜像劫持
  15. IE安全系列:脚本先锋(IV)—网马中的Shellcode
  16. OpenSees二次开发实例01
  17. Java 1072 开学寄语
  18. 网站logo服务器更换显示以前,网站更换logo
  19. telnet 不是内部或外部命令,也不是可运行的程序解决方案
  20. Android中按钮的点击事件的四种写法

热门文章

  1. ef oracle 双引号,Oracle 数据库中字符串和日期必须使用双引号标识。
  2. 微信视频号怎么变现挣钱?六大变现操作方式。
  3. 学军OJ题解——诸葛的理想
  4. Android购物商城界面
  5. 安卓商城购物车布局案例
  6. 【Scala】Scala 部署和安装
  7. 《短线交易秘诀》读后感
  8. arm服务器虚拟x86,x86服务器与arm
  9. Task 01 强化学习基础
  10. 画像ToB独角兽,怎么做风口下能飞的猪?