☰
nid_names.py工具实战:如何解码AnyPS5的NID符号名
2026/10/8 12:19:51 网站建设 项目流程

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)

四列输出各自含义:

列名含义
NID11 位密文标识,即导出函数的真实链接名
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):

  1. 把函数名和一段 16 字节的固定后缀拼接;
  2. 计算 SHA1,取摘要的第 8 到 15 字节并反转;
  3. 按 3 字节一组(最后一组 2 字节)做位运算,从 64 字符集里取码;
  4. 最终输出 11 个字符的 NID。

这个逻辑与 core/libs/nid/ 下 C++ 模块的Nid::ComputeNid完全一致——构建时 nid_patcher 会用它把所有导出的符号名改写成 NID,这样 OS 加载器就能按 NID 完成绑定(架构说明见 docs/dev/ARCHITECTURE.md)。

💡 拿到建议后如何落地?

解码只是第一步。一个典型的贡献流程是:

  1. 跑python3 tools/nid_names.py,挑一个rename-ready的 NID;
  2. 在对应库(如 core/libs/prx/libSceRandom/Export.cpp)中把Unknown占位函数改成真实函数名;
  3. 根据文档注释补齐参数签名——部分 NID 的参数签名仍不明确,会记录在 docs/dev/TechnicalDebt.md 中;
  4. 用 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询