type
status
date
slug
summary
tags
category
icon
password
Property
Nov 17, 2022 10:16 AM
外挂分析报告
分析结论
外挂的组成结构
- 使用 andlua 编写的界面
- 使用 C/C++ 编写的核心可执行文件
外挂程序的储存位置
app将aes解密后随机生成文件名写至 /data/data/com.mycompany.myapp2/files,然后执行并删除源文件
外挂启动逻辑
外挂使用andlua编写,andlua会加载外挂的main.lua并执行
在点击开启外挂按钮后,外挂会将aes解密写出并执行
在aes中,外挂读取游戏内存定位并进行修改,实现作弊功能
资源的加解密
在rc4.lua中解密,可以反编译该lua文件然后直接调用来解密。
在实际中,elf的删除没有做好。
复现:
- 关闭frida,删除frida临时文件
- 打开外挂
- 打开frida
- 点击开启按钮
- 外挂提示 find frida 2
- 点击确认,外挂闪退
此时解密的二进制文件并未被删除。
反调试、脱壳、解混淆过程
外挂检测ida、frida默认端口,frida临时文件反调试
aes的UPX壳未魔改,使用upx -d可以一键脱壳
未解混淆,在关键函数下断点可以直接分析
外挂原理、外挂的核心函数和外挂访问游戏地址对应的含义
- 外挂使用 process_vm_writev 函数修改 MaxWalkSpeed 的值为 9000f 达到人物移动加速的效果
- 外挂使用 ptrace 函数修改 UCharacterMovementComponent::GetGravityZ 返回值为 0x10000 达到跳跃飞天的效果
分析过程
1. 判断外挂类型
打开安装包,根据 lib 下的 libluajava.so 可以判断该外挂由 andlua 编写。
一般此类外挂的核心实现逻辑是在elf可执行文件中,而elf文件可能是直接打包在安装包内,也有可能是动态下载。
可以判断asstes文件夹中的aes文件为目标文件,将其拖入010editor中发现其被加密,于是接下来便解密加密的lua脚本文件,再对aes进行解密。
2. lua 解密
使用IDA打开 libluajava.so 在 luaL_loadbufferx 处下断,运行android_server
使用adb调试启动外挂
使用ida附加进程,并F9运行
使用apktool解包外挂,并用Android Studio (安装了smalidea 0.06插件)打开
将smali文件夹标记为Source Root,然后使用Android Studio附加
此时,ida会在断点处断下
使用ida python dump 出 lua
分析发现dump出来的脚本的字符串仍然被加密,怀疑lua环境被魔改,换用andlua官方解密工具解密得到lua字节码文件。
3. lua 反编译
使用 TDecompile_1.2 和 unluac 对lua字节码文件进行反编译
4. 解密aes
反编译rc4.lua并对反编译结果进行修复,调用算法解密aes得到elf文件
5. 脱掉elf的upx壳
使用IDA打开后发现该程序被UPX压缩,尝试使用upx直接脱壳,若脱壳失败则使用ida动态调试脱壳
直接脱壳成功。
6. elf分析
将elf直接push到/data/local/tmp目录下运行,输出 found debugger 3 Killed
将其拖入IDA开始分析,发现有加密,在imports中搜索kill,查找交叉引用下断可以发现
检测了 /data/local/tmp 目录下的 re.frida.server 文件夹,关闭frida将其删除后,程序正常运行。
使用strace工具记录程序的syscall调用,程序正常运行,未检测ptrace。
再结合maps文件综合分析可得,该外挂使用 process_vm_writev 系统调用修改了 FirstPersonCharacter_C 下的一个指针指向的对象的一个值,并且使用ptrace修改了libUE4的一处代码。
7. 分析ptrace修改的实现
使用ida调试,在ptrace函数下断
8.分析反调试的实现
IDA: Rebasing program to 0x0CF2C000
在 popen 与 strcmp下断,分析可得
在 pthread_create 下断,可以发现反调试线程,可以直接挂起
9. 分析外挂原理
- 外挂在 0xCED96F2 处调用 popen("pidof com.YourCompany.FPSTest1") 获取游戏进程pid
- 发现外挂直接退出,游戏掉了,重新打开游戏,再次运行
Rebasing program to 0x08499000
- 在 0x849D492 打开 /proc/game_pid/maps文件
- 人物加速实现
- 修改内存页属性
- 实现跳跃飞天
8. 分析外挂访问游戏地址对应的含义
寻找GWorld与GName,然后使用 UE4Dumper 导出游戏的SDK。
使用IDA打开游戏的 libUE4.so,搜索GWorld和GNameEntryPoolAllocator
GName = GNameEntryPoolAllocator+0x14
结果:
- GWorld = 0x4924570
- GName = 0x4877034
外挂 0x0849F25A 0x849F2A6 处也可以找到 GName 和 GWorld 的偏移
使用UE4Dumper 导出SDK与actorlist
与 strace 记录中 process_vm_readv 的记录对比可得
修改了:
- MaxWalkSpeed = (FirstPersonCharacter_C + 0x2f0) + 0x164
- libUE4 + 0x1FD6428
UCharacterMovementComponent::GetGravityZ
.text:01FD6428 VMOV R0, S0
外挂复现
使用Android Studio开发,process_vm_writev 实现人物加速, ptrace 实现跳跃飞天,核心代码如下。