我正在尝试手写一个Mach-O可执行文件。有三个加载命令:
LC_SEGMENT_64
正在加载__PAGEZERO
LC_SEGMENT_64
正在加载__TEXT
,只有一个__text
部分LC_UNIXTHREAD
并设置了适当的rip
每个命令都匹配mach/loader.h
和相关标头中的结构。 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
…
答案 0 :(得分:4)
自10.10.5 Yosemite以来,可执行文件必须至少 4096 字节长(PAGE_SIZE
),否则它将立即被杀死。 @Siguza在XNU kernel
exec_activate_image
函数https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/bsd/kern/kern_exec.c#L1456
假设您只想使用系统调用来获得64位macOS可执行文件,则需要:
LC_SEGMENT_64
__PAGEZERO
(非零大小,名称可以是任何内容)LC_SEGMENT_64
__TEXT
(名称可以是任何内容;必须是可读且可执行的;部分是可选的)LC_UNIXTHREAD
对于这种情况,这是my example。
如果没有dyld,你不能做太多,所以如果你想使用它,最小的设置是:
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_MAIN
或LC_UNIXTHREAD
LC_LOAD_DYLIB
(至少有一个实际的dylib加载LC_MAIN
才能工作)LC_UNIXTHREAD
和LC_MAIN
在现代可执行文件中(自10.7 Mountain Lion起),LC_UNIXTHREAD
被LC_MAIN
取代,后者需要dyld
- 但从10.12开始,任何可执行文件仍支持LC_UNIXTHREAD
Sierra(它应该是未来的MacOS版本,因为dyld
可执行文件本身实际启动它。)
要使dyld
工作,额外的步骤取决于绑定类型:
bind at load
是最省力的方法,其中LC_DYLD_INFO_ONLY
指向指向可写段的有效dyld load commands
将起作用。
lazy binding
还需要__TEXT
中额外的特定于平台的代码,该代码在加载时dyld_stub_binder
使用绑定到dyld
加载函数的延迟加载地址。
我还没有其他类型的dyld binding
。
可在此处找到更多详细信息:https://github.com/opensource-apple/dyld/blob/master/src/ImageLoaderMachO.cpp
答案 1 :(得分:0)
不是100%肯定,但您需要LC_LOAD_DYLINKER
加载命令才能在可执行文件之前运行dyld,我很确定 OSX 如果加载,则不会自动映射到/usr/lib/dyld
命令不可用。
您是否需要使用/usr/lib/libSystem.B.dylib
加载命令LC_LOAD_DYLIB
?我不这么认为,但这样做既不好又不花钱。