e-gleba/airstrike3d-tools
GitHub: e-gleba/airstrike3d-tools
AirStrike 3D 游戏系列的逆向工程工具集,提供加密资源包提取、模型转换、存档解密及引擎内部分析的完整方案。
Stars: 19 | Forks: 4
# AirStrike 3D 逆向工程
**AirStrike 3D 游戏系列逆向工程**

[PCGamingWiki](https://www.pcgamingwiki.com/wiki/AirStrike_2) - [原版游戏](https://en.wikipedia.org/wiki/AirStrike_3D)
## 🎮 关于
我对逆向工程 AirStrike 3D 的怀旧之旅——这是我童年时期第一款让我着迷的 PC 游戏。本仓库包含用于理解游戏内部机制的工具和研究成果。


## 🕵️ 游戏简介
[AirStrike 3D](https://en.wikipedia.org/wiki/AirStrike_3D) 是一款由 **[DivoGames](https://web.archive.org/web/2006/http://divogames.com/)**(俄罗斯下诺夫哥罗德)开发、并由 **[Alawar Entertainment](https://en.wikipedia.org/wiki/Alawar)** 发行的直升机射击游戏系列。游戏引擎和该系列的全部三款游戏均由一个两人团队构建。
### 开发者
| 名字 | 角色 | 链接 |
|------|------|-------|
| **Anton Petrov** | 引擎架构师、CTO 兼联合创始人 | [LinkedIn](https://www.linkedin.com/in/anton-petrov-cto/) |
| **Dmitry Zakharov** | 联合创始人 | — |
这两个名字作为字符串字面量(`{Anton Petrov}`、`{Dmitry Zakharov}`)嵌在 Gulf Thunder 可执行文件的制作人数据中。Petrov 在 LinkedIn 上这样描述该引擎:*“我的第一款游戏引擎,具有自定义脚本语言和硬件加速 3D 图形功能——为 Air Strike 3D 系列的三款游戏提供动力。”*
在离开 DivoGames 之后,Petrov 成为 **Game Insight** 的 CTO(2012–2019,下诺夫哥罗德部门),随后于 2020 年在塞浦路斯联合创立了 **Colossi Games** 并运营至今(2020–至今)。
### deaddybear → divogames
在 DivoGames 正式成立(约 2004 年)之前,AirStrike 的早期章节是在一个名为 **Deaddybear** 的团队下开发的。社区在 [r/airstrike3d 上的研究](https://www.reddit.com/r/airstrike3d/comments/16k254c/about_divogames_earlier_development_projects/) 发现,Deaddybear 早期的游戏 _Treasure Mole_ 使用了几乎相同的 `.pak` 压缩包格式——证实了它们共享代码库的血缘关系。Deaddybear 还发行了 _Bomberman vs Digger_(2002 年)。
### 系列年表
| 年份 | 标题 | 发行商 | 类型 | 引擎 | 已知别名 |
|------|-------|-----------|-------|--------|-------------|
| 2002 | AirStrike 3D: Operation W.A.T. | Alawar | 直升机射击 | v1.x (OpenGL, Deaddybear 时代) | *Air Assault 3D*, *Air Hawk* |
| 2004 | AirStrike 2 | Alawar / 自发行 | 直升机射击 | v2.06 (OpenGL 1.1, MSVC 7.0) | *АвиаНалет 2* (ru) |
| 2005 | AirStrike II: Gulf Thunder | Alawar | 直升机射击 | v2.71 (Direct3D 8, MSVC 8.0) | *Desert Hawk* |
| 2007 | Air Force Missions | MyPlayCity | 直升机射击 | v2.50 (未确认,同引擎系列) | — |
| 2007 | Space Strike | MyPlayCity | 太空射击 | 未知 | *Galaxy Strike*, *Звёздный Удар* |
```
graph TD
%% People
AP["👤 Anton Petrov\nEngine Architect · CTO · Co-founder"]
DZ["👤 Dmitry Zakharov\nCo-founder"]
%% Orgs / Groups
DB["🐻 Deaddybear\n~2000–2004"]
DG["🏢 DivoGames Ltd.\nNizhny Novgorod · 2004–2012"]
GI["🏢 Game Insight NN\nNizhny Novgorod · 2012–2019"]
CG["🏢 Colossi Games\nCyprus · 2020–present"]
AL["📦 Alawar Entertainment\nPublisher"]
MPC["📦 MyPlayCity\nPublisher"]
%% Engine lineage
ENG1["⚙️ Engine v1.x\nOpenGL · Deaddybear era"]
ENG206["⚙️ Engine v2.06\nOpenGL 1.1 · MSVC 7.0\ncompiled 2004-05-15"]
ENG250["⚙️ Engine v2.50\nunconfirmed · same lineage"]
ENG271["⚙️ Engine v2.71\nDirect3D 8 · MSVC 8.0\ncompiled 2007-05-15"]
%% Games
TM["🎮 Treasure Mole\n.pak format — shared codebase"]
BVD["🎮 Bomberman vs Digger\n2002"]
AS1["🎮 AirStrike 3D: Op. W.A.T.\n2002"]
AS2["🎮 AirStrike 2\n2004"]
GT["🎮 AirStrike II: Gulf Thunder\n2005"]
AFM["🎮 Air Force Missions\n2007"]
SS["🎮 Space Strike\n2007"]
%% Aliases
AA["🏷️ Air Assault 3D\nAir Hawk"]
DH["🏷️ Desert Hawk"]
GS["🏷️ Galaxy Strike\nЗвёздный Удар"]
%% Evidence nodes
EV1["🔍 EVIDENCE\nString literals in Gulf.exe:\n{Anton Petrov} {Dmitry Zakharov}"]
EV2["🔍 EVIDENCE\nLinkedIn: 'my first game engine\npowered three titles'"]
EV3["🔍 EVIDENCE\nMSVC RTTI: .?AVIntroPageDivoGames@@\nDivo Master debug string"]
EV4["🔍 EVIDENCE\nr/airstrike3d research:\n.pak format shared with Treasure Mole"]
%% Acquisition
ACQ["📋 Acquisition 2012\nGame Insight buys DivoGames"]
%% People → Orgs
AP --> DB
DZ --> DB
DB -->|"~2004 rebranded/founded"| DG
AP -->|"CTO · co-founder"| DG
DZ -->|"co-founder"| DG
AP -->|"CTO 2012–2019"| GI
AP -->|"co-founded 2020"| CG
DG -->|"acquired by"| ACQ
ACQ --> GI
%% Evidence links
EV1 -.->|"confirms"| AP
EV1 -.->|"confirms"| DZ
EV2 -.->|"confirms"| AP
EV3 -.->|"confirms"| DG
EV4 -.->|"confirms"| DB
%% Engine lineage
ENG1 -->|"evolved to"| ENG206
ENG206 -->|"evolved to"| ENG271
ENG206 -.->|"possible fork"| ENG250
%% Games → Engine
AS1 --> ENG1
AS2 --> ENG206
GT --> ENG271
AFM --> ENG250
SS -.->|"engine unknown"| DG
%% Deaddybear games
DB --> TM
DB --> BVD
DB --> AS1
%% DivoGames games
DG --> AS2
DG --> GT
DG --> AFM
DG --> SS
%% Publishers
AL -->|"published"| AS1
AL -->|"published"| AS2
AL -->|"published"| GT
MPC -->|"published"| AFM
MPC -->|"published"| SS
%% Aliases
AS1 -.->|"rebrand"| AA
GT -.->|"rebrand"| DH
SS -.->|"rebrand"| GS
%% Styling
classDef person fill:#1a3a5c,stroke:#4a9eda,color:#e8f4fd
classDef org fill:#1a2a1a,stroke:#4aaa4a,color:#e8fde8
classDef engine fill:#2a1a3a,stroke:#9a4aed,color:#f0e8fd
classDef game fill:#2a1a1a,stroke:#ed6a4a,color:#fde8e8
classDef alias fill:#1a2a2a,stroke:#4aaaaa,color:#e8fdfd,stroke-dasharray:4 2
classDef evidence fill:#2a2a1a,stroke:#aaa04a,color:#fdfde8,stroke-dasharray:2 2
classDef event fill:#2a1a2a,stroke:#aa4a6a,color:#fde8f0
class AP,DZ person
class DB,DG,GI,CG,AL,MPC org
class ENG1,ENG206,ENG250,ENG271 engine
class TM,BVD,AS1,AS2,GT,AFM,SS game
class AA,DH,GS alias
class EV1,EV2,EV3,EV4 evidence
class ACQ event
```
## 🔬 引擎内部机制
使用自定义 C++ 引擎,无第三方框架。采用类似 Quake 风格的子系统前缀:
| 子系统 | 前缀 | 示例 |
|-----------|--------|----------|
| 游戏逻辑 | `G_` | `G_LoadBin`, `G_LoadLevelList` |
| 渲染器 | `R_` | `R_LoadModel`, `R_RegisterModel`, `R_RegisterShadow` |
| 声音 | `S_` | `S_Init`, `S_RegisterSound` |
| 窗口 | `MW_` | `MW_CreateWindow` |
### 图形 API 演进
| 版本 | API | 编译器 | 编译时间戳 | Rich 头文件 |
|---------|-----|----------|-------------------|-------------|
| v2.06 (`as3d2.exe`) | OpenGL 1.1 (`opengl32.dll`, `glu32.dll`) | MSVC 7.0 (.NET 2002/2003) | `2004-05-15 10:12:58 UTC` | ✅ |
| v2.71 (`Gulf.exe`) | Direct3D 8 (`d3d8.dll`) | MSVC 8.0 (VS2005) | `2007-05-15 13:49:28 UTC` | ✅ |
### 第三方库
- **[BASS](https://www.un4seen.com/)** — 音频库。支持 3D 空间音频、EAX 音效、MO3/Tracker 模块播放。
- **libjpeg** — `Copyright (C) 1996, Thomas G. Lane`(在 Gulf Thunder 可执行文件字符串中找到)。
- **zlib + libpng** — PNG 纹理支持。
- **自定义脚本语言** — 已由 Petrov 在 LinkedIn 上确认,但没有公开的存档文档。
### 资产格式
| 格式 | 扩展名 | 描述 |
|--------|-----------|-------------|
| 压缩包 | `.apk` | 自定义加密容器(XOR 加密,1024 字节密钥表)。**并非** Android APK。 |
| 模型 | `.mdl` | 包含版本检查的自定义 3D 格式(`R_LoadModel: Illegal model version.`) |
| 纹理 | `.tga` | 标准 Targa 格式。按 `gfx/`、`menu/`、`tiles/` 目录分类。 |
| 关卡 | `maps/levels.txt` | 纯文本关卡列表(在 `.apk` 内加密存储) |
| 音频 | `.mo3` | 通过 BASS 库支持的 Tracker 模块 |
| 配置 | `config.ini` | 纯文本格式,与可执行文件存放在同一目录 |
### RTTI / C++ 细节
在 Gulf Thunder 二进制文件中发现了 MSVC RTTI 类型描述符(例如 `.?AVIntroPageDivoGames@@`),证实了使用了启用虚继承和 RTTI 的 C++。`Divo Master` 字符串暗示存在某种内部工具或调试模式。
## 🔒 ASProtect 1.0 分析
v2.06 可执行文件(`as3d2.exe`,199,680 字节)由 Alexey Solodovnikov 开发的 **[ASProtect 1.0](http://asprotect.net)** 加壳。
### 特征识别
| 指标 | 值 | 含义 |
|-----------|-------|---------|
| 入口点 | `.data` 节(`0x1DB3001`) | 壳的存根代码,非原始代码 |
| EP 特征码 | `60 E8 01 00 00 00` | `PUSHAD` + `CALL +1` — 典型的 ASProtect 1.0 特征 |
| 节属性 | 全部为 `0xC0000040` (RWX) | 壳重写了所有节的属性 |
| `.text` 熵值 | **8.00**(最大值) | 完全加密/压缩 |
| 可见的 IAT | 3 个导入:`GetProcAddress`, `GetModuleHandleA`, `LoadLibraryA` | 真正的 IAT 在运行时解析 |
| 压缩方式 | aPLib(LZ77 变体) | 参见 [`scripts/static_exe_unpacker.py`](scripts/static_exe_unpacker.py) |
| 哈希值 | `MD5: 1ba6f0187c43d07587e5212f1cb14190` | `SHA256: bc68bf37...81fb1a` |
### 运行机制
1. **节擦除** — 原始节名称被擦除,所有属性被设置为 `0xC0000040`。追加了两个 `.data` 存根。
2. **aPLib 解压** — 压缩后的 `.text` 存储在超大尺寸的 `.data` 中(虚拟大小 30 MB,原始大小 4 KB)。
3. **OEP 字节窃取** — 原始入口点的前几个字节在存根中执行,然后跳转到 `OEP+N`。
4. **IAT 重定向** — 导入调用通过 ASProtect 内存路由;原地执行真实 API 的前几条指令,然后跳转到函数体中部。
5. **反调试** — `IsDebuggerPresent()`、RDTSC 时间检测、SEH 断点检测、调试器驱动程序的 `CreateFile()` 探测。
6. **校验和** — 代码完整性验证,用于检测运行时补丁。
7. **反汇编** — `CALL` 指令后的垃圾字节会破坏线性扫描反汇编器(如 W32DASM、SOURCER);IDA 则可以正常处理。
### v2.71 — 无保护
Gulf Thunder 完全没有加壳保护:入口点在 `.text` 中,熵值为 6.83,IAT 完整,开发者署名和错误字符串可以直接读取。是进行引擎分析的绝佳目标。
## 🔗 相关资源
- [r/airstrike3d](https://www.reddit.com/r/airstrike3d/) — 社区研究与 Mod 制作
- [Ithamar 的 APK 脚本](https://gist.github.com/Ithamar/85f1f71d179c354fad483a8c48767daf) — 包含文本解密的更新版提取工具
- [QindieGL](https://github.com/nicedrak/QindieGL) — 用于在现代 Windows 上运行的 OpenGL 转 D3D 包装器
- [PCGamingWiki: AirStrike 2](https://www.pcgamingwiki.com/wiki/AirStrike_2) — 兼容性修复
- [xakep.ru: ASProtect 驯服记](https://xakep.ru/2003/07/10/19112/) — 技术层面的加壳分析(俄语)
- [ASProtect 主页](http://asprotect.net) — Alexey Solodovnikov 的官方网站
## 🔧 工具
### APK 压缩包提取
```
# 从加密的 .apk archives 中提取 game assets
python extract_apk.py pak0.apk # Extracts all files
python pack_apk.py extracted_dir/ new.apk # Repack modified assets
```
### mdl 与 obj 互转
```
python mdl_obj_converter.py some_file.mdl
python mdl_obj_converter.py some_file.obj
```
### 存档预览器(+imhex 结构预览)
```
python decrypt_save.py decrypt game.bin -o decrypted.bin
```
### 音频转换
```
# 将 MO3 tracker modules 转换为标准 audio
sudo dnf install libopenmpt openmpt123
openmpt123 --render file.mo3 --output file.wav
```
### 图形查看
```
# 适用于 Linux 的最佳 TGA 纹理查看器
# https://github.com/bluescan/tacentview
tacentview texture.tga
```
## 🐧 Linux 兼容性
### 通过 Steam Proton 运行 (Fedora + AMD GPU)
```
# 修复旧版游戏的 OpenGL extension 问题
MESA_EXTENSION_MAX_YEAR=2003 %command%
```
将此内容添加到 Steam 中游戏的启动选项中。
## 📋 技术说明
- **压缩包格式:** 自定义加密的 APK 容器(不是 Android APK)
- **可执行文件:** 使用 ASProtect v1.0 加壳(通过 YARA 规则检测)
- **资产:** TGA 纹理、MDL 3D 模型、MO3 音频模块
- **加密方式:** 采用 1024 字节密钥表的 XOR 密码
## 🚀 快速开始
1. 克隆本仓库
2. 提取游戏资产:`python extract_pak.py /path/to/pak0.apk`
3. 在创建的目录中浏览提取的文件
4. 根据需要转换音频文件
### 构建
1. 从 下载 llvm-mingw:
- `llvm-mingw-YYYYMMDD-ucrt-ubuntu-20.04-x86_64.tar.xz` 适用于 win10+ (ucrt)
- `llvm-mingw-YYYYMMDD-msvcrt-ubuntu-20.04-x86_64.tar.xz` 适用于 win7+ (旧版 crt)
2. 解压到仓库根目录的 `llvm-mingw` 文件夹中
3. 运行
```
cmake --preset llvm-mingw-i686
cmake --build --preset llvm-mingw-i686
```
## 🏴☠️ Ghidra 项目
🔒 由于该项目使用了 **ASProtect 1.0**,我决定在 Linux 上使用一个简单的调试器,通过步进直到我们遇到某种循环。游戏似乎会自行解包并创建某个线程,因此即使在 `ntdll` 的神奇魔法面前,调试器也会在某个时刻脱离 🪄,所以我们只需在任意时刻暂停,并获取所需函数(循环)的地址即可。
🎯 下一步是使用带有 **DumpEx** 插件的 **x64dbg**——使用主循环函数的地址进行转储。就这样!
📊 **统计信息:**
- 📦 游戏体积:**31.2 MB**
- 🔍 在 Ghidra 项目中,我标记了一些有趣的地方:
- 🎮 模型加载
- 💾 存档处理
- 🔧 核游戏机制
🚀 **用法:**
也许将来的某一天,会有人把它完全逆向出来 😏 🦀⚡
## ⚖️ 法律声明
仅供教育和保存目的。请尊重原作版权。
## 📄 许可证
MIT - 因为知识应当是自由的,就像玩游戏带来的快乐一样。
## 🙏 致谢
献给那台勉强能运行这款游戏,却不知怎的让它变得充满魔力的旧电脑。
标签:AirStrike 3D, APK分析, Bash脚本, C++, DivoGames, Gophish, JARM, 二进制分析, 云安全监控, 云安全运维, 云资产清单, 内存分析, 存档查看, 客户端加密, 射击游戏, 怀旧游戏, 数据提取, 数据擦除, 文件解析, 游戏Modding, 游戏 preservation, 游戏存档修改, 游戏开发历史, 游戏研究, 游戏逆向, 直升机游戏, 脚本语言分析, 自定义引擎, 资产提取, 逆向工具, 逆向工程, 静态分析