gslab2022-安卓初赛
2022-11-17
| 2022-11-17
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
Nov 17, 2022 10:16 AM

外挂分析报告

分析结论

外挂的组成结构

  1. 使用 andlua 编写的界面
  1. 使用 C/C++ 编写的核心可执行文件

外挂程序的储存位置

app将aes解密后随机生成文件名写至 /data/data/com.mycompany.myapp2/files,然后执行并删除源文件

外挂启动逻辑

外挂使用andlua编写,andlua会加载外挂的main.lua并执行
在点击开启外挂按钮后,外挂会将aes解密写出并执行
在aes中,外挂读取游戏内存定位并进行修改,实现作弊功能

资源的加解密

在rc4.lua中解密,可以反编译该lua文件然后直接调用来解密。
在实际中,elf的删除没有做好。
notion image
复现:
  1. 关闭frida,删除frida临时文件
  1. 打开外挂
  1. 打开frida
  1. 点击开启按钮
  1. 外挂提示 find frida 2
  1. 点击确认,外挂闪退
此时解密的二进制文件并未被删除。

反调试、脱壳、解混淆过程

外挂检测ida、frida默认端口,frida临时文件反调试
aes的UPX壳未魔改,使用upx -d可以一键脱壳
未解混淆,在关键函数下断点可以直接分析

外挂原理、外挂的核心函数和外挂访问游戏地址对应的含义

  1. 外挂使用 process_vm_writev 函数修改 MaxWalkSpeed 的值为 9000f 达到人物移动加速的效果
  1. 外挂使用 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
notion image
使用adb调试启动外挂
使用ida附加进程,并F9运行
使用apktool解包外挂,并用Android Studio (安装了smalidea 0.06插件)打开
将smali文件夹标记为Source Root,然后使用Android Studio附加
notion image
notion image
此时,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,查找交叉引用下断可以发现
notion image
检测了 /data/local/tmp 目录下的 re.frida.server 文件夹,关闭frida将其删除后,程序正常运行。
使用strace工具记录程序的syscall调用,程序正常运行,未检测ptrace。
notion image
notion image
notion image
再结合maps文件综合分析可得,该外挂使用 process_vm_writev 系统调用修改了 FirstPersonCharacter_C 下的一个指针指向的对象的一个值,并且使用ptrace修改了libUE4的一处代码。

7. 分析ptrace修改的实现

使用ida调试,在ptrace函数下断
 

8.分析反调试的实现

IDA: Rebasing program to 0x0CF2C000
在 popen 与 strcmp下断,分析可得
在 pthread_create 下断,可以发现反调试线程,可以直接挂起
notion image
notion image

9. 分析外挂原理

  1. 外挂在 0xCED96F2 处调用 popen("pidof com.YourCompany.FPSTest1") 获取游戏进程pid
    1. notion image
  1. 发现外挂直接退出,游戏掉了,重新打开游戏,再次运行
    1. Rebasing program to 0x08499000
  1. 在 0x849D492 打开 /proc/game_pid/maps文件
    1. notion image
      notion image
  1. 人物加速实现
    1. notion image
  1. 修改内存页属性
    1. notion image
      notion image
  1. 实现跳跃飞天
    1. notion image

8. 分析外挂访问游戏地址对应的含义

寻找GWorld与GName,然后使用 UE4Dumper 导出游戏的SDK。
使用IDA打开游戏的 libUE4.so,搜索GWorld和GNameEntryPoolAllocator
GName = GNameEntryPoolAllocator+0x14
结果:
  1. GWorld = 0x4924570
  1. GName = 0x4877034
外挂 0x0849F25A 0x849F2A6 处也可以找到 GName 和 GWorld 的偏移
使用UE4Dumper 导出SDK与actorlist
与 strace 记录中 process_vm_readv 的记录对比可得
修改了:
  1. MaxWalkSpeed = (FirstPersonCharacter_C + 0x2f0) + 0x164
  1. libUE4 + 0x1FD6428
    1. UCharacterMovementComponent::GetGravityZ
      .text:01FD6428 VMOV R0, S0

外挂复现

使用Android Studio开发,process_vm_writev 实现人物加速, ptrace 实现跳跃飞天,核心代码如下。
  • 腾讯游戏安全竞赛
  • gslab2022-安卓决赛博客重建
    • Giscus
    目录