[THM] THE GAME CHALLENGE 解题笔记
TryHackMe THE GAME CHALLENGE 解题笔记
一、题目信息
- 题目名称:THE GAME CHALLENGE
- 题目文件:
Tetrix.exe-1741979048280.zip - 题目类型:逆向工程 / 游戏逆向 / 文件隐藏分析
题目描述:
Cipher has gone dark, but intel reveals he’s hiding critical secrets inside Tetris, a popular video game. Hack it and uncover the encrypted data buried in its code.
题目提供了一个 Windows 游戏程序,并在描述中提到 Tetris 和隐藏的加密数据。我的分析思路如下:
- 识别附件和可执行文件的基本信息;
- 检查 PE 节区及文件尾部是否存在额外数据;
- 定位并提取嵌入的 Godot PCK 资源包;
- 检查资源包结构和可能的加密特征;
- 使用 Ghidra 复现十六进制编辑器的全文件搜索;
- 排除误命中并定位 flag。
二、使用工具
| 类型 | 工具 / 技术 |
|---|---|
| 操作系统 | Kali Linux |
| 文件识别 | file |
| 压缩包处理 | unzip |
| 哈希校验 | sha256sum |
| PE 结构分析 | objdump |
| 十六进制查看 | xxd、Bless Hex Editor |
| 字符串搜索 | strings、grep |
| 逆向分析 | Ghidra |
| 涉及格式 | PE、Godot PCK |
| 关键知识点 | PE section、overlay、Godot PCK、Raw Binary 导入、ASCII 十六进制搜索 |
三、解压附件
首先识别压缩包类型:
1 | file Tetrix.exe-1741979048280.zip |
输出:
1 | Tetrix.exe-1741979048280.zip: Zip archive data, at least v2.0 to extract, compression method=deflate |
这是一个普通的 ZIP 压缩包,直接解压:
1 | unzip -n Tetrix.exe-1741979048280.zip |
解压后得到:
1 | Tetrix.exe |
__MACOSX 是 macOS 创建压缩包时附带的元数据目录,可以忽略。真正需要分析的是 Tetrix.exe。
四、基础文件信息
4.1 识别文件类型
1 | file Tetrix.exe |
输出:
1 | Tetrix.exe: PE32+ executable for MS Windows 5.02 (GUI), x86-64 (stripped to external PDB), 13 sections |
由此可以判断,它是一个 64 位 Windows GUI 程序,并且包含 13 个 PE 节区。
4.2 计算文件哈希
1 | sha256sum Tetrix.exe |
输出:
1 | 64ba9f8a44b6d28026117497eedac76bf30189a09b5d8b7decf47fbd353ec96f Tetrix.exe |
记录哈希可以确认后续分析过程中样本没有发生变化。
4.3 查看文件大小
1 | ls -lh Tetrix.exe |
输出:
1 | -rw-rw-rw- 1 meng meng 89M 2025年 3月15日 Tetrix.exe |
一个简单的 Tetris 游戏体积接近 89 MB,说明文件中可能包含完整游戏引擎、资源包或其他附加数据。
五、分析 PE 节区
使用 objdump 查看 PE 节区:
1 | objdump -h Tetrix.exe |
关键输出:
1 | Idx Name Size VMA LMA File off |
这里最值得注意的是名为 pck 的节区。结合样本是游戏程序,可以联想到 Godot 引擎使用的 .pck 资源包。
该节区的文件偏移和声明大小分别为:
1 | File offset = 0x05036600 |
声明的节区结束位置为:
1 | 0x05036600 + 0x8 = 0x05036608 |
六、检查文件尾部数据
查看真实文件大小,并将十六进制偏移转换为十进制:
1 | stat -c '%s' Tetrix.exe |
输出:
1 | 93021728 |
文件真实大小明显大于 pck 节声明的结束位置,尾部还存在:
1 | 93021728 - 84108808 = 8912920 bytes |
也就是约 8.5 MiB 的附加数据。
从 PE 结构角度看,pck 节只声明了 8 字节,后续内容属于文件尾部的 overlay;从 Godot 打包结构看,从 0x05036600 开始一直到文件末尾的数据共同组成了嵌入式 PCK 包。
七、定位 Godot PCK 包头
查看 pck 节起始位置附近的数据:
1 | xxd -s $((0x05036600)) -l 32 Tetrix.exe |
输出:
1 | 05036600: 4744 5043 0200 0000 0400 0000 0300 0000 GDPC............ |
其中:
1 | 47 44 50 43 = GDPC |
GDPC 是 Godot PCK 文件的 magic,可以确认 Tetrix.exe 中嵌入了 Godot 游戏资源包。
继续搜索文件中的所有 GDPC:
1 | grep -abo 'GDPC' Tetrix.exe | tail -20 |
部分结果:
1 | 45907339:GDPC |
其中:
1 | 84108800 = 0x05036600 |
这与前面发现的 pck 节起始位置完全一致。文件末尾的 GDPC 则是 PCK 的尾部标记。
八、提取 PCK 资源包
从偏移 0x05036600 开始提取文件剩余内容:
1 | tail -c +$((0x05036600 + 1)) Tetrix.exe > tetrix.pck |
这里的 tail -c +N 从第 N 个字节开始读取,而文件偏移从 0 开始,因此需要加 1。
查看提取后的文件大小:
1 | stat -c '%s' tetrix.pck |
输出:
1 | 8912928 |
查看 PCK 头部:
1 | xxd -l 128 tetrix.pck |
输出:
1 | 00000000: 4744 5043 0200 0000 0400 0000 0300 0000 GDPC............ |
可以初步解析为:
| 字段 | 值 | 含义 |
|---|---|---|
| Magic | GDPC | Godot PCK 标识 |
| PCK format | 2 | PCK 格式版本 |
| Godot version | 4.3.0 | 引擎版本 |
| Flags | 3 | PCK 标志位 |
| File base | 0x1730 | 文件数据区域基址 |
| File count | 0x46 | 共 70 个文件 |
九、检查 PCK 目录区
为了进一步检查 PCK 头部和目录区,我编写了下面的 Python 脚本。
pck_header.py:
1 | from pathlib import Path |
运行脚本:
1 | python3 pck_header.py |
输出:
1 | [+] magic: b'GDPC' |
目录区域的熵值为 7.9702,非常接近理论最大值 8,说明这部分数据具有很强的随机性。
高熵数据可能来自加密或压缩,不能只根据熵值直接下结论。不过结合 PCK 标志位和目录内容不可直接辨认,可以合理怀疑该 PCK 的目录区域经过了加密处理。
十、搜索 Godot 相关字符串
继续使用 strings 搜索 Godot、资源路径和加密相关字符串:
1 | strings -a -n 5 Tetrix.exe \ |
程序中可以找到 Godot 引擎版本:
1 | Godot Engine v4.3.stable.official |
同时还能看到一些资源路径和编译后的 GDScript 文件:
1 | res://GUI.gdc |
这些信息进一步确认了样本是 Godot 游戏,并且包含 .gdc 编译脚本。
十一、尝试搜索明文密钥
Godot PCK 常见的加密密钥长度为 256 bit,也就是 32 字节。如果密钥以十六进制字符串保存,通常会表现为 64 个十六进制字符。
可以使用下面的命令进行初步搜索:
1 | strings -a -n 32 Tetrix.exe \ |
搜索结果主要是:
1 | 0000000000000000000000000000000000000000000000000000000000000000 |
这些内容大多是全 0、全 f、重复字符或年份序列,不像随机生成的有效密钥。
如果要沿着 PCK 解包路线继续分析,就需要逆向程序,寻找以原始二进制形式保存或在运行时生成的密钥。但这道题还有一条更直接的路线:对完整文件搜索 flag 特征。
十二、使用 Ghidra 进行全文件搜索
参考其他解题思路,可以使用 Bless Hex Editor 打开整个文件并搜索 THM。我希望使用 Ghidra 复现相同的搜索方式。
这里需要注意:
- Bless Hex Editor 按原始文件偏移从头到尾显示数据;
- Ghidra 默认按 PE 格式导入时,显示的是经过 PE Loader 映射后的地址空间;
- 如果希望在 Ghidra 中像十六进制编辑器一样查看整个原始文件,应将样本作为 Raw Binary 导入。
重新导入 Tetrix.exe:
- 选择
File -> Import File; - 选择
Tetrix.exe; - 将
Format设置为Raw Binary; - 将
Base Address设置为0x0; - 将
Language设置为x86:LE:64:default。
这样导入后,Ghidra 中显示的地址就等于文件偏移,与 Bless 左侧显示的偏移一致。由于这里的目标只是搜索原始字节,不需要运行自动分析。
十三、搜索 THM 特征
打开 Raw Binary 版本后,选择:
1 | Search -> Memory |
搜索下面的 ASCII 字节:
1 | 54 48 4D |
它对应字符串:
1 | THM |
搜索结果中出现了多个候选地址:
1 | 041567f7 |
这些位置只是包含 THM 字节序列,不一定都是 flag。
13.1 排除误命中
查看第一个搜索结果附近的数据,发现它位于普通字符串:
1 | FEATURE_ARITHMETIC |
其中 ARITHMETIC 恰好包含:
1 | ARI[THM]ETIC |
这只是字符串子串造成的误命中。
TryHackMe flag 通常使用下面的格式:
1 | THM{...} |
其十六进制前缀为:
1 | 54 48 4D 7B |
因此搜索时不仅要检查 THM,还要确认后面是否紧跟 {。
十四、定位最终 flag
继续检查搜索结果,在文件偏移 0x058b159c 附近发现下面的完整字节序列:
1 | 54 48 4D 7B 49 5F 43 41 4E 5F 52 45 41 44 5F 49 54 5F 41 4C 4C 7D |
转换为 ASCII:
1 | T H M { I _ C A N _ R E A D _ I T _ A L L } |
最终得到:
1 | THM{I_CAN_READ_IT_ALL} |
十五、总结
这道题属于游戏逆向和文件隐藏分析题。虽然最终可以通过搜索明文 THM{ 找到 flag,但完整分析过程中涉及了多个值得记录的知识点。
整体分析路线如下:
1 | 解压附件 |
本题的关键经验:
file可以快速判断文件类型和目标架构;objdump -h可以查看 PE 节区布局;- 看到
pck和GDPC时,应联想到 Godot PCK 资源包; - 文件真实大小大于所有节区覆盖范围时,可能存在 overlay 数据;
- 熵值接近 8 说明数据随机性很强,但需要结合格式标志和上下文判断是加密还是压缩;
- Ghidra 默认 PE 导入不等价于十六进制编辑器的全文件视图;
- 若要在 Ghidra 中按原始文件偏移搜索,应使用 Raw Binary 导入,并将 Base Address 设置为
0x0; - 搜索
THM可能出现普通单词子串造成的误报,应进一步确认THM{; - 最终 flag 明文位于原始文件偏移
0x058b159c附近。
最终答案:
1 | THM{I_CAN_READ_IT_ALL} |


![[THM] THE GAME CHALLENGE 解题笔记](https://img.nuyoah.icu/post/defaultcover/1754956169453_d17cf97955885a3d736542981f0eac43.webp)