gpt4 book ai didi

mach-o - 加载 Mach-O 可执行文件需要什么?

转载 作者:行者123 更新时间:2023-12-02 05:50:55 31 4
gpt4 key购买 nike

我正在尝试手写 Mach-O 可执行文件。加载命令共有三个:

  • LC_SEGMENT_64正在加载__PAGEZERO
  • LC_SEGMENT_64 加载 __TEXT,带有单个 __text 部分
  • LC_UNIXTHREAD 带有适当设置的 rip

每个命令都与 mach/loader.h 和相关 header 中的结构匹配。 otool -l 按预期列出信息,并且不报告任何错误。从各方面来看,它都是一个格式良好的目标文件——但 OS X 10.10.5 终止了该任务 (SIGKILL)。

在 OS X 加载 Mach-O 可执行文件之前,会检查它的哪些功能?该信息位于何处?这些功能会随着版本的不同而变化吗? (经常被引用的“OS X ABI Mach-O 引用”显然丢失了。)

<小时/>

这是一个partially annotated hexdump二进制文件。

otool 健全性检查(摘录):

$ otool -l machtest
machtest:
Load command 0
cmd LC_SEGMENT_64
cmdsize 72
segname __PAGEZERO

Load command 1
cmd LC_SEGMENT_64
cmdsize 152
segname __TEXT

Section
sectname __text
segname __TEXT

Load command 2
cmd LC_UNIXTHREAD

最佳答案

自 10.10.5 Yosemite 起,可执行文件的长度必须至少为 4096 字节 ( PAGE_SIZE ),否则将立即被终止。 @Siguza在XNU内核exec_activate_image函数https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/bsd/kern/kern_exec.c#L1456

中找到的相关代码

没有 dyld

假设您想要一个仅使用系统调用的 64 位 macOS 可执行文件,您需要:

  • Mach-O 64 位 header
  • LC_SEGMENT_64 __PAGEZERO(大小非零,名称可以是任何内容)
  • LC_SEGMENT_64 __TEXT(名称可以是任何内容;必须可读且可执行;部分是可选的)
  • LC_UNIXTHREAD

这是本案例的 my example

与 dyld

如果没有 dyld,你就不能做很多事情,所以如果你想使用它,最小集是:

  • Mach-O 64 位 header
  • LC_SEGMENT_64 __PAGEZERO(大小非零)
  • LC_SEGMENT_64 __TEXT(名称可以是任何内容;必须可读且可执行;部分是可选的)
  • LC_SEGMENT_64 __LINKEDIT (必须是可写的,因为 dyld 需要可写段,在 ld 链接的二进制文件中,可写段通常为 __DATA)
  • LC_DYLD_INFO_ONLY(指定实际 dyld 加载命令在可执行文件中的物理位置,通常可以在 __LINKEDIT 中找到它们,但没有限制这个)或有趣的是 LC_SYMTAB 相反,这将使实际的 dyld 在没有 LC_DYLD_INFO_ONLY 的情况下无法使用。
  • LC_DYSYMTAB(可以为空)
  • LC_LOAD_DYLINKER
  • LC_MAINLC_UNIXTHREAD
  • LC_LOAD_DYLIB(至少要加载一个实际的 dylib,最终依赖于 libSystem 或 libSystem 本身才能使 LC_MAIN 正常工作)

此外,自 MacOS Monterey 12.3 起:

  • LC_SYMTAB(如果使用LC_DYSYMTAB,则现在需要)

LC_UNIXTHREADLC_MAIN

在现代可执行文件中(自 10.7 Mountain Lion 起),LC_UNIXTHREADLC_MAIN 取代,后者需要 dyld — 但 LC_UNIXTHREAD<从 10.12 Sierra 开始,任何可执行文件仍然支持/code>(并且应该在未来的 MacOS 版本中,因为它由 dyld 可执行文件本身用来实际启动)。

要使 dyld 正常工作,额外的步骤取决于绑定(bind)类型:
加载时绑定(bind)是最省力的方法,其中LC_DYLD_INFO_ONLY指向指向可写段的有效dyld加载命令就可以了。
延迟绑定(bind)还需要__TEXT中额外的平台特定代码,该代码在加载时利用绑定(bind)dyld_stub_binder来延迟加载dyld的地址
加载的函数。
还有其他类型的 dyld 绑定(bind),我在此不予介绍。

更多详细信息可以在这里找到:https://github.com/opensource-apple/dyld/blob/master/src/ImageLoaderMachO.cpp

关于mach-o - 加载 Mach-O 可执行文件需要什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39863112/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com