用外部符号替换 MacOS Mach-O 二进制文件中的静态符号

Replace static symbols in MacOS Mach-O binary with external symbols

我有以下场景:

以及本次Mac之旅的根本原因OS联动:

是否可以强制二进制文件使用动态加载 .dylib 中定义的符号版本,而不是二进制文件本身定义的版本?我想修补 all 我拥有的每个 .dylib 符号中可用的符号,因为如果我只修补一些符号而不修补其他符号,它可能会中断(大概 MoltenVK 仅适用于框架中每个符号的代码均来自同一版本的MoltenVK)。

注意:我无法重新编译游戏的主要 Mach-O 二进制文件,因为我没有源代码。如果可能的话,我愿意绕过我本地系统上的安全保护措施来做到这一点;我接受在 运行 测试版(非生产)OS 期间做危险事情的风险。

我希望答案和评论侧重于所问问题的技术解决方案,但如果需要进一步的理由,我会尽快解决这个问题,以便给游戏开发者尽可能多的时间可以在 macOS 10.15 的最终版本之前修复它。如果我保持沉默,问题就有可能不会被发现;然后人们将升级到最终的 macOS 10.15 并注意到游戏无法运行。这对任何人来说都不好玩,因为那样我们要么留在 Mojave 上等待游戏开发者更新他们的游戏,要么可能几周或几个月没有游戏。

静态链接意味着库被有效地嵌入到最终的可执行二进制文件中。因此,没有简单的技术方法来挂钩调用并将它们重定向到其他地方(例如 DYLD_INTERPOSEDYLD_INSERT_LIBRARIES 允许外部动态库)。

修补二进制文件需要遍历游戏进行的每个 MoltenVK 调用并进行相当繁琐的 post 处理。 通过 post 处理,我的意思是:

  1. 使用 dlopendlsym 串联编写 dyld 调用。你还是会 需要 dlopen & dlsym 二进制文件中已经使用的符号(它们是 libSystem aka C std lib,但你仍然需要专用的 dyld 操作码 才能真正使用它们)。最终你需要将汇编操作码以二进制形式放在某个地方才能使一切正常。这将是相当困难
  2. 启动 lldb 调试器,准备 dlsym 地址以手动调用并为每个调用即时修补二进制文件(您可能需要 __TEXT 段中的写入权限去做,但那是最容易的部分)。如果您知道自己在做什么,这可能是 最可行的方法 。主要缺点是它不稳定,如果你破坏了你会从头开始的东西。
  3. LC_LOAD_DYLIB 命令添加到 LC_DYLD_INFO_ONLY 引用的二进制和 dyld 操作码,即 super hard

无论如何,您最好的朋友是 Hopper 反汇编程序和 MachOView 检查二进制文件。

x86 (and/or x86-64) 汇编的基本知识 是必须 遵循的。我认为使用原始源代码可能是一种更可行的选择。