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://img.shields.io/endpoint?url=https%3A%2F%2FRaikaru.github.io%2FPersona4-Decompilation%2Fprogress%2Fmatching.json)](https://Raikaru.github.io/Persona4-Decompilation/progress/matching.json) [![C 链接进度](https://img.shields.io/endpoint?url=https%3A%2F%2FRaikaru.github.io%2FPersona4-Decompilation%2Fprogress%2Flinked.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, 游戏解编译, 逆向工具, 逆向工程