游戏名为Terminus Zombie Survivors, 使用pygame游戏引擎制作(python37)
- 游戏中的数据Cheat Engine无法搜索, 因为每次数据变动都会重新分配内存, 没有固定地址
- 语言包解压, 用关键字搜索游戏文件夹, 无法搜索到, 搜索游戏进程可以搜索到, 数据应该被压缩
- 主资源文件改名再运行, 关键字还是可以搜索到, 说明核心脚本在其他位置
- 检查主exe文件, 发现尾部有压缩数据
- 跟踪数据读取过程找到 PyMarshal_ReadObjectFromString
- 对PyMarshal_ReadObjectFromString Hook然后提起数据
@file.python37.dll#PyMarshal_ReadObjectFromString
$dat = $Param1;
$size = $Param2;
LogFileFormat("V:\\python.log", "%6d size: %6d\r\n", $RunId, $size);
OutputString("%6d size: %6d\r\n", $RunId, $size);
$filename = "V:\\pythonHook\\" + $RunId + "_" + $size + ".dat";
WriteFile($filename, 0, $dat, $size);
- 提取后的数据并不完整, 只有部分脚本, 找到其他函数 PyImport_ExecCodeModuleObject, PyEval_EvalCodeWithName等都不合适
- 在PyMarshal_ReadObjectFromString 调用的一个核心解释函数, 在这个函数Hook
@file.python37.dll#0x20186EED
$class = $ecx
$start = ReadMem($class+0x0c, 4);
$end = ReadMem($class+0x10, 4);
$dat = $start;
$size = $end-$start;
LogFileFormat("V:\\python.log", "%6d size: %6d\r\n", $RunId, $size);
OutputString("%6d size: %6d\r\n", $RunId, $size);
$filename = "V:\\pythonHook\\" + $RunId + "_" + $size + ".dat";
WriteFile($filename, 0, $dat, $size);
- 脚本基本提取完成, 600多个文件左右, 格式为pyc
- 安装python3.7 安装uncompyle6
python3.7必须使用安装版本, 并安装上pip, 安装uncompyle6时就会自动下载安装依赖库
uncompyle6 无法直接py文件使用, 必须使用库的安装方式并使用, 另外无法对整个文件夹反编译 - Hook提取的文件为pyc格式, 但是没有包含头, 需要从其他文件复制一个头过去(16byte)
- 找到需要修改的pyc文件反编译, uncompyle6参数-a可以看到指令, 但是没有16进制代码, 可以查看表 python3.x 虚拟机指令表
- 固化修改可以修改dll的代码 20186EED
20186EED E87EEFFFFF call 20185E70
20186EF2 8BF0 mov esi, eax
20186EF4 85F6 test esi, esi
修改
20186EED /E9F8690300 jmp 201BD8EA
201BD8E4 - FF25C0E31B20 jmp dword ptr [201BE3C0]
000000000000
修改
201BD8E4 - FF25C0E31B20 jmp dword ptr [201BE3C0]
201BD8EA EB0A jmp 201BD8F6
201BD8EC E87F85FCFF call 20185E70
201BD8F1 ^ E9FC95FCFF jmp 20186EF2
201BD8F6 8B4110 mov eax, dword ptr [ecx+10]
201BD8F9 8B510C mov edx, dword ptr [ecx+0C]
201BD8FC 2BC2 sub eax, edx
201BD8FE 3D00AE0000 cmp eax, 0AE00
201BD903 ^ 75E7 jnz 201BD8EC
201BD905 81C29B290000 add edx, 299B
201BD90B 813A64036E02 cmp dword ptr [edx], 26E0364
201BD911 ^ 75D9 jnz 201BD8EC
201BD913 C6420503 mov byte ptr [edx+05], 03
201BD917 C64264C8 mov byte ptr [edx+64], 0C8
201BD91B 90 nop
201BD91C ^ EBCE jmp 201BD8EC