用外部符号替换MacOS Mach-O二进制文件中的静态符号 [英] Replace static symbols in MacOS Mach-O binary with external symbols

查看:40
本文介绍了用外部符号替换MacOS Mach-O二进制文件中的静态符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下情况:

  • 一款专有的MacOS游戏,该游戏将图形框架 MoltenVK 静态链接到其主要的Mach-O x86-64位二进制文​​件.
  • 链接的MoltenVK版本太旧了.
  • 我有一个 .dylib 形式的较新版本的MoltenVK(以及较新版本的SPIRV编译器,libVulkan等,如果需要,也可以是dylib形式)./li>
  • 旧版本和较新版本的MoltenVK均兼容ABI,这意味着导出的符号名称和功能签名应与旧版本和新版本的MoltenVK相同.
  • A proprietary MacOS game that statically links a graphics framework MoltenVK into its main Mach-O x86-64 binary.
  • The version of MoltenVK linked in is very old.
  • I have a newer version of MoltenVK in the form of a .dylib (along with newer versions of the SPIRV compiler, libVulkan, etc. if they are needed, also in dylib form).
  • The older and newer version of MoltenVK are ABI compatible, meaning the exported symbol names and function signatures should be identical from the old to the new version of MoltenVK.

这是MacOS链接之旅的根本原因:

And the root cause of this journey into MacOS linkage:

  • 游戏无法在我的macOS版本(10.15 Catalina Beta 3)上正常运行.由于崩溃回溯,我已将问题隔离到MoltenVK.
  • 我想测试更新MoltenVK是否可以解决问题,既可以作为临时解决方法,又可以帮助开发人员隔离问题.

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

Is it possible to force the binary to use a version of the symbols defined in a dynamically loaded .dylib instead of the version defined within the binary itself? I want to patch all symbols available in each of the .dylibs I have, because it would probably break if I only patched some symbols but not others (presumably MoltenVK only works if the code of each symbol in the framework is from the same version of MoltenVK).

注意:由于我没有源代码,因此我无法重新编译游戏的主要Mach-O二进制文件.如果可能的话,我愿意绕过我本地系统上的安全保护措施;无论如何,我都会承受在运行Beta(非生产)操作系统时做危险事情的风险.

Note: I am unable to recompile the main Mach-O binary of the game because I do not have source code. I am willing to bypass security safeguards on my local system to do this if it is possible at all; I accept the risk of doing dangerous things while running a Beta (non-production) OS anyway.

我希望答案和评论都集中在所提出问题的技术解决方案上,但是如果需要进一步的论证,我将尝试尽快隔离该问题,以使游戏开发人员有更多时间来解决问题.在macOS 10.15的最终版本之前对其进行修复.如果我保持沉默,则有可能无法发现问题.然后人们将升级到最终的macOS 10.15,并注意到该游戏无法正常工作.这对任何人都不是一件好事,因为那样的话我们要么呆在Mojave上,等待游戏开发者更新他们的游戏,要么就停止游戏长达数周或数月.

I'd prefer if answers and comments focus on the technical solution to the question asked, but if further justification is needed, I am trying to isolate this problem as quickly as possible to give the game's developers as much time as possible to fix it before the final release of macOS 10.15. If I stay silent, the problem has a chance that it won't be detected; then folks will upgrade to the final macOS 10.15 and notice the game doesn't work. That's not fun for anyone, because then we have to either stay on Mojave and wait for the game developer to update their game, or go without the game for possibly weeks or months.

推荐答案

静态链接表示该库已有效地烘焙到最终的可执行二进制文件中.因此,没有简单的技术来挂接呼叫并将它们重定向到其他地方(例如 DYLD_INTERPOSE DYLD_INSERT_LIBRARIES 允许外部dylib).

Static linking implies the library gets effectively baked into your final executable binary. So there's no easy technical way of hooking the calls and redirecting them somewhere else (like DYLD_INTERPOSE or DYLD_INSERT_LIBRARIES allows for external dylibs).

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

Patching the binary would require going through each MoltenVK call the game makes and doing quite cumbersome post processing. By post processing I mean either:

  1. 使用 dlopen & dlsym 串联.你仍然会需要 dlopen & dlsym 符号已在二进制文件中使用(它们是libSystem aka C std lib,但是您仍然需要专用的dyld操作码才能真正使用它们).最终,您需要将汇编操作码放在二进制文件中的某处,以使所有工作正常进行.这将非常困难.
  2. 启动 lldb 调试器,准备要手动调用的 dlsym 地址,并为每个调用动态修补二进制文件(您可能需要中的写许可权> __ TEXT 段即可,但这很简单).如果您知道自己在做什么,那可能是最可行的方法.主要缺点是它易变,如果您破坏某些内容,则会从头开始.
  3. LC_DYLD_INFO_ONLY 引用的二进制和dyld操作码添加 LC_LOAD_DYLIB 命令,这将是 super hard
  1. writing a dyld call using dlopen & dlsym tandem. You would still need dlopen & dlsym symbols already used in the binary (they're part of libSystem aka C std lib, but you still need the dedicated dyld opcodes to be able to actually use them). Eventually you'd need to put the assembly opcodes somewhere in binary to make everything work. This will be quite hard.
  2. firing lldb debugger, preparing the dlsym addresses to call by hand and patching the binary on the fly for each call (you'd probably need write permissions in __TEXT segment to do it, but that's the easy part). If you know what you're doing this is probably the most feasible approach. The main drawback is it's volatile, if you break something you'd start from scratch.
  3. Add a LC_LOAD_DYLIB command to the binary and dyld opcodes referenced by LC_DYLD_INFO_ONLY , that would be super hard

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

In any case your best friends are Hopper dissassembler and MachOView to inspect the binary.

必须熟练掌握x86(和/或x86-64)组装的基本知识.我认为使用原始源代码可能是一种更可行的选择.

Elementary knowledge of x86 (and/or x86-64) assembly is a must to follow. I think playing with the original source code could be a way more viable option.

这篇关于用外部符号替换MacOS Mach-O二进制文件中的静态符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆