news 2026/10/3 12:51:55

AnyPS5 NID系统揭秘:PS5的SHA-1符号哈希如何在Linux/Windows上被解析与重绑定

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AnyPS5 NID系统揭秘:PS5的SHA-1符号哈希如何在Linux/Windows上被解析与重绑定

AnyPS5 NID系统揭秘:PS5的SHA-1符号哈希如何在Linux/Windows上被解析与重绑定

【免费下载链接】AnyPS5Tool for automatic PS5 executables porting to Linux and Windows项目地址: https://gitcode.com/gh_mirrors/an/AnyPS5

AnyPS5 是一款自动移植 PS5 可执行文件到 Linux 与 Windows 的工具,其核心难点之一是NID 符号哈希系统。PS5 的动态链接并不直接使用普通函数名,而是使用基于SHA-1 摘要生成的短字符串标识,即 NID。AnyPS5 的 NID 模块 会重新计算这些 NID,并将 ELF 或 PE 二进制中的导出、导入符号改写为宿主系统可识别的名称,从而让 PS5 程序在 Linux/Windows 上完成动态链接与重绑定。

为什么 PS5 移植不能直接保留原始符号名?

在常规 Linux 或 Windows 程序中,动态链接器通常通过函数名解析依赖,例如某个共享库导出了某个函数,程序就会按名字找到它。PS5 的许多系统库则使用NID(Named Identifier)作为符号标识。NID 是一串由 SHA-1 摘要派生出的 Base64 风格字符,本质上是一种“符号哈希指纹”。

对移植工具来说,这带来了两个问题:

  • 原始 NID 不能直接作为普通函数名使用,因为宿主系统的动态链接器不认识它;
  • PS5 库导出的符号需要被转换成宿主平台可解析的形式,这样才能与系统 PRX 库重新绑定。

AnyPS5 的 NID 系统就是负责完成这件事:读取符号、计算 NID、识别特殊后缀、改写二进制,并最终让 Linux ELF 或 Windows PE 文件能正常加载。

NID 是如何从函数名计算出来的?

NID 的计算逻辑位于 NidCompute.cpp。整个流程可以概括为四步:

  1. 取原始符号名:例如某个 PS5 系统函数名;
  2. 追加固定 16 字节后缀:项目内置了一组固定字节,用来保证 NID 与特定 PS5 标识空间一致;
  3. 计算 SHA-1 摘要:由 Sha1.cpp 提供实现;
  4. 取摘要前 8 字节并反转编码:最终得到 11 个字符的 NID 字符串。

这里的 SHA-1 并不是用来加密或校验文件,而是作为符号到短标识的单向映射。同一个函数名只要经过相同算法,就会得到稳定的 NID。

关键函数ComputeNid()位于 NidCompute.cpp。它接收符号名和库名,最终返回一个 11 字符的 NID。

特殊后缀:NID 系统里的“免哈希”标记

并不是所有符号都必须通过 SHA-1 重新计算。NID 系统支持一批特殊后缀,用来告诉解析器如何处理当前符号。这些规则集中在 NidPatcherUtils.hpp。

常见的后缀包括:

  • _nid_postfix:表示这是一个已经带有 NID 风格的占位名,需要剥离后再参与计算;
  • _nid_no_patch:表示该符号保持原样,不重新生成 NID;
  • _nid_no_patch_cut:表示保留原始名称的一部分,然后继续解析;
  • _nid_disambig:用于区分重载或重复名称,计算前会去掉消歧义数字;
  • SDL_前缀:某些运行时接口需要直接保留,不进入 NID 计算。

这种设计非常重要。因为如果所有符号都无差别地做哈希重写,一些需要保持名字兼容的接口就会失效。特殊后缀相当于给符号打上了处理策略标签。

解析入口在 NidResolver.cpp,其中的ResolveOneName()会先判断特殊后缀,再决定是否调用ComputeNid()。

Linux 上的重绑定:改写 ELF 导出与导入符号

在 Linux 平台上,PS5 可执行文件最终会被转换为 ELF 格式。动态链接器依赖.dynsym与.dynstr等节区来解析符号。NID 系统的 ELF 补丁器主要工作包括:

  • 扫描.dynsym中所有可导出符号;
  • 调用 NidResolver.cpp 批量生成 NID 映射;
  • 重建.dynstr字符串表;
  • 修正DT_NEEDED、DT_SONAME等动态段字符串偏移;
  • 重建gnu.hash,保证链接器仍能以 O(1) 级别快速查找符号;
  • 修正重定位项中引用的符号索引。

相关实现位于 ElfNidPatcher.cpp。其中PatchNids()是整个 ELF 重绑定的核心入口,它会把原始符号名替换为计算后的 NID,同时维护字符串表偏移一致性。

这一步的意义在于:转换后的 ELF 文件仍然能被 Linux 动态链接器识别,并且导入的 PS5 系统函数能按 NID 找到对应实现。

Windows 上的重绑定:改写 PE 导出表与导入表

在 Windows 平台上,PS5 程序会被转换成 PE 格式。PE 文件的符号解析依赖导出表和导入表。NID 系统的 PE 补丁器位于 PeNidPatcher.cpp,其工作流程为:

  • 读取 PE 导出目录;
  • 提取所有导出函数名;
  • 通过 NID 解析器生成新的符号名;
  • 将新的名称重新打包进导出字符串区域;
  • 更新导出名称表与序号表;
  • 进一步扫描导入表,把以sce开头或带 NID 后缀的导入名替换为真实 NID。

这里的细节很关键:Windows 导入表中的函数名是按 RVA 引用的,补丁器不能只是“改一个字符串”,还必须同步更新指向该字符串的偏移。PeNidPatcher.cpp 实现了从导出字符串重排到导入 thunk 重写的完整链路。

完成之后,PE 文件就能以宿主 Windows 加载器能理解的方式解析符号,并将 PS5 程序对系统库的调用重绑定到 AnyPS5 提供的实现上。

排除规则:如何避免把某些符号误改成 NID?

有些库或函数并不适合参与 NID 重写,例如:

  • 项目自身需要保留原始名称的导出;
  • 第三方运行时接口;
  • 某些与宿主系统直接交互的符号。

为此,NID 系统支持导出排除列表。该功能会从参考库文件中读取符号表,再把命中的符号从 NID 重写范围中剔除。相关逻辑位于 ExportExclusions.cpp。

它同时支持两种参考文件格式:

  • PE 文件:解析 Windows DLL 的导出表;
  • ELF 文件:解析 Linux 共享库的动态符号表。

这意味着开发者可以提供一个“未补丁库”作为参照,让 NID 系统知道哪些名字必须原样保留。这为自动移植提供了非常重要的安全阀:既保证大部分系统符号被正确重写,又不会误伤需要保持兼容的接口。

从命令行看 NID 重绑定流程

NID 模块的命令行入口在 main.cpp。它接受一个库名、可选的--preserve-exports参考库,以及一个或多个待补丁文件。

典型流程可以理解为:

  1. 读取目标二进制文件;
  2. 根据文件头判断是 ELF 还是 PE;
  3. 调用对应的 NID 补丁器;
  4. 将结果写回文件。

这里体现了 AnyPS5 的设计思想:NID 重绑定不是独立工具,而是整体 relinker 流水线中的一环。整体二进制转换位于 core/relinker,而系统库实现位于 core/libs/prx。NID 系统负责“符号层”的适配,relinker 负责“格式层”的转换,两者结合才让 PS5 程序在 Linux/Windows 上真正可运行。

小结:NID 系统为什么是 AnyPS5 的关键拼图

如果把 PS5 移植到 Linux/Windows 比作一次“语言翻译”,那么 NID 系统就是负责符号翻译规则的核心组件:

  • 它把原始符号名映射成稳定的 SHA-1 短标识;
  • 它根据特殊后缀决定是否改写、保留或裁剪;
  • 它同时支持 ELF 与 PE 两套二进制结构;
  • 它通过排除机制避免误改关键接口;
  • 最终让宿主系统动态链接器能正确完成重绑定。

理解 NID,就理解了 AnyPS5 自动移植能力中最隐秘、也最关键的一环:它不是模拟 PS5 的运行时,而是把 PS5 的符号体系翻译成 Linux 与 Windows 都能理解的语言。

延伸阅读

  • core/libs/nid/:NID 计算、解析与补丁器实现;
  • core/relinker/:ELF/PE 重新链接与格式转换主流程;
  • core/libs/prx/:PS5 系统 PRX 库的宿主端实现;
  • docs/dev/CONVENTIONS.md:项目代码风格与约定;
  • docs/dev/TechnicalDebt.md:项目当前技术债务与改进方向。

【免费下载链接】AnyPS5Tool for automatic PS5 executables porting to Linux and Windows项目地址: https://gitcode.com/gh_mirrors/an/AnyPS5

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 12:49:47

多台服务器日志分散难查?用Promtail+Loki+Grafana搭建集中检索平台

线上服务一旦拆到多台机器,日志查询就会变成一件很烦的事。我维护的几个后端服务分布在四台服务器上,平时排查问题基本靠 ssh 登上去,再 tail -f 或者 grep。单机还好,一旦某个请求跨了多个服务,或者要对比几台机器同一…

作者头像 李华
网站建设 2026/10/3 12:49:32

在1核2G的Linux服务器上部署MySQL 8需要优化哪些参数?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 12:49:28

AI写论文哪个软件最好?云智变AI毕业论文功能实测科普——云智变AI官网www.yunzhibian.cn,微信公众号搜一搜 云智变ai学术

先给一个可能让你意外的答案 打开搜索引擎搜“AI写论文哪个软件最好”,你会看到三种结果:一种把ChatGPT、Claude、DeepSeek挨个夸一遍,最后说“看个人需求”;一种直接甩出十几个工具清单,从图灵论文到笔灵AI一网打尽&…

作者头像 李华
网站建设 2026/10/3 12:47:27

MySQL索引优化实战|千万级数据表查询提速10倍方案

在后端项目开发中,数据库查询缓慢是最常见的性能问题,尤其是数据量达到百万、千万级后,未优化的SQL语句查询耗时可达数秒,直接导致接口超时、页面加载卡顿。大部分数据库性能问题,根源都不是服务器配置不足&#xff0c…

作者头像 李华