Raikaru/Persona4-Decompilation
GitHub: Raikaru/Persona4-Decompilation
该项目是 PS2 游戏《女神异闻录 4》美版的匹配反编译工程,旨在通过逐函数 C 语言还原创建与零售版字节一致的重建可执行文件。
Stars: 1 | Forks: 0
# Persona 4 PS2 反编译
针对 PlayStation 2 平台上的**女神异闻录 4**(美国地区,版本 1.00,`SLUS_217.82`)的初步匹配反编译工作。
[](https://Raikaru.github.io/Persona4-Decompilation/progress/matching.json)
[](https://Raikaru.github.io/Persona4-Decompilation/progress/linked.json)
请参阅 [`ROADMAP.md`](ROADMAP.md) 以了解 P3 的完成顺序以及并行的 P4 同步待办事项。
本仓库特意不包含任何游戏可执行文件、光盘镜像或提取的游戏数据。请提供您合法拥有的游戏副本的光盘镜像。设置工具会根据已确认的 Redump 记录验证光盘,随后仅提取其引导可执行文件及可加载镜像。
## 当前状态
完整的零售版可执行文件已拥有字节级完全一致的汇编基准。当前匹配构建选择了包含 190 个精确匹配函数的 189 个 C 翻译单元;生成的可加载镜像和完整 ELF 均重现了零售版的 SHA-1。恢复的集合涵盖了 runtime、Kernel、Event、Scene、战斗、游戏玩法、CRI、模型和 RenderWare 辅助功能,其中包括从唯一对应且经验证器匹配的 Persona 3 FES 实现中移植的函数。
| 产物 | 验证值 |
| --- | --- |
| 美国 DVD 镜像 | 4,405,952,512 字节;SHA-1 `179381f67a412dc56e9b7ae40dbc1c00a0beea59` |
| 引导可执行文件 | `SLUS_217.82`;8,621,084 字节;SHA-1 `4eeec0360cf2715535d9f7e52eb69d786fb0158c` |
| 可执行文件 PT_LOAD 镜像 | `0x838a00` 字节,位于 VRAM `0x00100000`;SHA-1 `3d1d3d2b9d6ccb60836db239ab49674223025a78` |
| 入口点 / 全局指针 | `0x00100008` / `0x007690f0` |
| 规范化函数窗口 | 13,080 |
| 已反编译且匹配的 | 189 个 C 链接翻译单元中的 190 个函数 |
ELF 注释为 `MW MIPS C Compiler (2.4.1.01)`,但这仅代表链接器的来源,并不能证明 C 编译器就是 MWCC 2.4。直接测试表明,MWCCPS2 3.0.1 的 build 198、205 和 210 版本在测试的 P4 结构中能生成相同的 `-O2` codegen;而 build 151 则不同。默认使用 build 210,但由于测试无法区分 198/205/210,该路径仍然保持可配置。由于 `-O3` 具有调度延迟槽,因此被排除在普通游戏代码之外。
光盘标识:[Redump 记录 5576](http://redump.org/disc/5576/)。
## 前置条件
- Python 3.10 或更高版本。
- [`splat`](https://github.com/ethteck/splat):
`python -m pip install -r requirements-python.txt`
- 支持 R5900 的 GNU `mipsel-linux-gnu-as` 和 `mipsel-linux-gnu-objcopy`。
- 本地可用的 MWCCPS2/MWLDps2 安装。当前的默认配置为 `mwcps2-3.0.1b210-060308 -O2`。
- 您自己的 Persona 4 美区光盘镜像。
无需外部 ISO 提取程序。`tools/setup.py` 包含一个小型只读的 ISO9660 根目录读取器,并且仅使用 Python 的标准库。
## 设置
```
python tools/setup.py "D:/path/to/Shin Megami Tensei - Persona 4 (USA).iso"
```
该命令会验证完整的 4.4 GB 光盘 SHA-1,读取 `SYSTEM.CNF`,检查其是否引导 `SLUS_217.82`,验证 ELF 和 PT_LOAD 布局,并写入:
- `orig/SYSTEM.CNF`
- `orig/SLUS_217.82`
- `image.bin`
这三个输出文件均已通过 gitignore 忽略。
等效的 Make 目标:
```
make setup ISO="D:/path/to/Shin Megami Tensei - Persona 4 (USA).iso"
```
## 拆分与函数映射
```
make split
make reconcile
```
验证过的可执行文件布局如下:
| 区域 | VRAM | 镜像偏移量 |
| --- | --- | --- |
| `code1` | `0x00100000`–`0x0052da00` | `0x000000`–`0x42da00` |
| `data1` | `0x0052da00`–`0x0070c850` | `0x42da00`–`0x60c850` |
| `code2` | `0x0070c850`–`0x0070e140` | `0x60c850`–`0x60e140` |
| `data2` | `0x0070e140`–`0x00764280` | `0x60e140`–`0x664280` |
| 零填充 | `0x00764280`–`0x00938a00` | `0x664280`–`0x838a00` |
`code1` 在 `0x0052d9a0` 处的最后一个统计辅助函数之后立即结束。
`code2` 是一个 `0x18f0` 字节的 PS2 SDK/kernel 数据块,其布局与 Persona 3 FES 的对应区域相同;只有 10 个绝对地址/调用字有所不同。
启动时会在进入游戏前清除最后的零填充范围。
Ghidra 识别出了 11,833 个函数。规范化的 13,080 窗口映射将 Ghidra 与 Splat 的 code1 控制流扫描以及 code2 中独立匹配的 9 函数 SDK 布局进行了协调:
```
python tools/reconcile_function_boundaries.py
```
原始的 Ghidra 导出文件为 `tools/slus21782_functions.ghidra.json`;验证器使用的规范化映射文件为 `tools/slus21782_functions.json`。
## 来自 Persona 3 FES 的共享代码映射
`tools/map_shared_p3.py` 会比较两个规范化函数映射和零售版加载镜像,而无需将任何一个游戏的可执行文件复制到本仓库中。它需要一个单独设置的 Persona 3 FES 反编译检出,该检出必须包含其自身被 gitignore 忽略的 `image.bin`:
```
make shared-p3 P3_ROOT="../Persona3-FES-Decompilation"
```
等效的直接调用方式:
```
python tools/map_shared_p3.py \
--p3-root "../Persona3-FES-Decompilation" \
--with-source-evidence
```
确定性的、被 gitignore 忽略的报告将写入 `build/shared_p3.json`。它包含原始一致和地址归一化的函数匹配、唯一与有歧义的 P3 候选项、解码后的直接调用和重定位地址映射,以及——在使用 `--with-source-evidence` 时——P3 验证器状态和源码路径。
该报告记录了两个镜像、两个函数映射以及 P3 指标输入的 SHA-1 哈希值。
地址归一化仅屏蔽受可执行文件布局控制的 MIPS 字段:J/JAL 目标、LUI 立即数、GP 相对立即数,以及与相邻 LUI 配对的低位部分。操作码、寄存器操作数、普通常量、分支位移量和指令顺序仍必须完全匹配。
## 构建与验证
将本机相关的路径放入被 gitignore 忽略的配置文件中:
```
// tools/verify_config.local.json
{
"mwcc": "D:/mwcps2-3.0.1b210-060308/mwccps2.exe",
"retail_elf": "C:/path/to/SLUS_217.82"
}
```
`tools/build_config.local.json` 接受相同的 `mwcc` 和 `retail_elf` 键,以及一个可选的 `ld_exe`。环境变量 `P4_MWCC`、`P4_RETAIL_ELF`、`P4_AS` 和 `P4_OBJCOPY` 具有最高优先级。
```
make build # assemble/link/splice and verify both retail hashes
make verify # compile and byte-compare every // FUN_ marker
make test # deterministic parser/reconciliation tests
```
当前成功构建的输出报告为:
```
eligible C objects: 189
C objects linked from source: 189
loadable image sha1: 3d1d3d2b9d6ccb60836db239ab49674223025a78 OK
SLUS_217.82 sha1: 4eeec0360cf2715535d9f7e52eb69d786fb0158c OK
```
## 进度端点
已提交的 [`progress/metrics.json`](progress/metrics.json) 是根据 `tools/verify.py --json`(匹配)和成功的 `tools/build.py --progress-report` 运行(C 链接函数)生成的。规范化函数分母来源于 `tools/slus21782_functions.json`;重复的验证器行按地址仅计算一次,并且每个链接的地址也必须匹配。
GitHub Pages 在 `https://Raikaru.github.io/Persona4-Decompilation/progress/` 发布已验证的端点。请在本地使用以下命令验证已提交的快照:
```
make progress-validate
```
## 目录结构
```
config/ target identity, segment layout, symbols, recovered linker symbols
asm/ committed macro support; generated assembly is ignored
include/ shared PS2 C types and decompilation headers
src/ matching C translation units
tools/ ISO setup, Ghidra export, boundary reconciliation, build and verify
tests/ synthetic ISO/ELF and boundary-map tests
orig/ user-supplied/extracted retail files (ignored)
image.bin extracted executable PT_LOAD payload (ignored)
build/ linked objects, ELF and verifier reports (ignored)
```
标签:PlayStation 2, 云资产清单, 女神异闻录4, 游戏解编译, 逆向工具, 逆向工程