nid_names.py工具实战:如何解码AnyPS5的NID符号名
【免费下载链接】AnyPS5Tool for automatic PS5 executables porting to Linux and Windows项目地址: https://gitcode.com/GitHub_Trending/an/AnyPS5
AnyPS5 是一个自动将 PS5 可执行程序移植到 Linux 和 Windows 的开源工具。它的 tools/nid_names.py 脚本能扫描整个代码库,把一堆难以辨认的 NID 符号(如+2KpvixvL6E)批量解码成真实的系统函数名,是参与项目开发时最实用的入门工具之一。
1️⃣ 背景:NID 符号是什么?
PS5 的系统库在动态链接时并不按字符串名字绑定函数,而是使用一串 11 位字符的NID(数字 ID 标识)来匹配。你在 core/libs/prx/ 目录下会看到大量这样的导出声明:
APS5_EXPORT("+2KpvixvL6E", scePsmlUnknown__P2KpvixvL6E); APS5_EXPORT("ArakEpzsZo0", scePsmlUnknown_ArakEpzsZo0);NID 本质上是函数名经过 SHA1 哈希、再按特殊字符集编码得到的 11 位"密文"。算法实现在 tools/nid_names.py 的compute_nid函数中,C++ 侧对应 core/libs/nid/src/NidCompute.cpp:
函数名 + 16 字节固定后缀 → SHA1 摘要 → 取 8 个字节反转 → 按
A-Z a-z 0-9 + -字符集每 6 位一组编码 → 输出 11 个字符
当开发者不知道某个 NID 对应哪个真实 API 时,就只能先给它起个Unknown占位名。nid_names.py 的作用就是把这些占位符"破译"出来。
📦 安装准备
先获取项目源码:
git clone https://gitcode.com/GitHub_Trending/an/AnyPS5 cd AnyPS5运行nid_names.py只需要Python 3,无其他依赖。首次运行时它会自动下载 NID 数据库(一个 CSV 文件)并缓存到系统的临时目录anyps5-nid-db/下,之后离线也能用。
🚀 一键扫描:最简使用方式
在项目根目录直接执行:
python3 tools/nid_names.py脚本会自动扫描 core/libs/prx/ 下所有APS5_EXPORT("<nid>", ...Unknown...)形式的未知导出,然后输出一个对照表:
NID STUB STATUS SUGGESTION +2KpvixvL6E core/libs/prx/libScePsml_debug/Exp.. rename-ready scePsmlSomeFunction ArakEpzsZo0 core/libs/prx/libScePsml_debug/Exp.. unknown ... 128 unknowns, 96 suggestions (12 already implemented)四列输出各自含义:
| 列名 | 含义 |
|---|---|
| NID | 11 位密文标识,即导出函数的真实链接名 |
| STUB | 当前代码中的占位位置(文件路径:符号名) |
| STATUS | 解码状态,见下表 |
| SUGGESTION | 数据库中查到的真实函数名 |
状态(STATUS)解读
rename-ready:数据库中有名字,且代码里还没实现 ——这就是你接下来可以认领的任务already-implemented:名字已知且已有实现,无需处理MISMATCH:数据库给的名字反算出的 NID 对不上,数据库该条目不可信,需要人工核实unknown:数据库里没有记录,只能保持占位名
脚本结束时会在底部汇总:共多少未知项、多少条建议、多少已实现。若出现MISMATCH,退出码为 1,方便在自动化流程中做校验。
🎯 进阶用法:指定 NID 查询与 JSON 输出
只解码特定的 NID
当你手头只有某个 NID(比如从游戏日志或技术文档中看到的),可以用--nid直接查询,无需扫描整个代码库:
python3 tools/nid_names.py --nid +2KpvixvL6E ArakEpzsZo0输出 JSON 供脚本处理
加--json可以拿到机器可读的结果(包含数据库总条目数),方便接入自己的统计工具:
python3 tools/nid_names.py --json使用自定义 NID 数据库
默认数据库来自项目内置的下载地址,缓存于临时目录。如果你有更新的 CSV,可以用--db参数或环境变量ANYPS5_NID_DB指定自己的文件:
python3 tools/nid_names.py --db /path/to/my-nid-list.csv这三个参数的组合方式都定义在 tools/nid_names.py 的参数解析部分。
🔍 NID 是怎么算出来的?
看懂算法后你甚至可以手动验证。以compute_nid函数为例(见 tools/nid_names.py):
- 把函数名和一段 16 字节的固定后缀拼接;
- 计算 SHA1,取摘要的第 8 到 15 字节并反转;
- 按 3 字节一组(最后一组 2 字节)做位运算,从 64 字符集里取码;
- 最终输出 11 个字符的 NID。
这个逻辑与 core/libs/nid/ 下 C++ 模块的Nid::ComputeNid完全一致——构建时 nid_patcher 会用它把所有导出的符号名改写成 NID,这样 OS 加载器就能按 NID 完成绑定(架构说明见 docs/dev/ARCHITECTURE.md)。
💡 拿到建议后如何落地?
解码只是第一步。一个典型的贡献流程是:
- 跑
python3 tools/nid_names.py,挑一个rename-ready的 NID; - 在对应库(如 core/libs/prx/libSceRandom/Export.cpp)中把
Unknown占位函数改成真实函数名; - 根据文档注释补齐参数签名——部分 NID 的参数签名仍不明确,会记录在 docs/dev/TechnicalDebt.md 中;
- 用 docs/user/COMPATIBILITY.md 里列出的游戏验证你的修改。
总结
| 命令 | 用途 |
|---|---|
python3 tools/nid_names.py | 全库扫描未知 NID 并给出真实名建议 |
--nid <NID...> | 只查询指定的 NID |
--json | 输出 JSON 格式结果 |
--db <path> | 指定自定义 NID 数据库 |
nid_names.py 用不到 130 行代码就打通了"扫描 → 查库 → 校验 → 建议"的完整链路,是新成员了解 AnyPS5 系统库实现进度的最佳入口。想深入 NID 计算原理,可以继续阅读 core/libs/nid/ 模块及其测试用例 test_dynamic_strings.py。
【免费下载链接】AnyPS5Tool for automatic PS5 executables porting to Linux and Windows项目地址: https://gitcode.com/GitHub_Trending/an/AnyPS5
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考