macos - 为什么 macOS 会杀死由 clang 创建的静态可执行文件?

标签 macos clang mach-o otool osx-gatekeeper

我有一个返回 42 的 m1 arm cpu 的最小 c 程序:

void _start() {
    asm("mov x0, #42;");
    asm("mov x16, #1;");
    asm("svc 0x80;");
}

此代码在告诉 clang 使用 _start 符号并返回正确值后编译。

clang -Wl,-e, -Wl,__start test.c -o dyn.out
./dyn.out ; echo $?
42

但是根据 otool,这个二进制文件仍然有动态链接:

otool -L ./dyn.out 
./dyn.out:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)

在告诉 clang 生成未签名的静态二进制文件后,macOS 会在尝试运行时立即终止二进制文件。

clang -Wl,-e, -Wl,__start -static -nostdlib test.c -o static_no_sign.out
zsh: killed     ./static_no_sign.out

在运行前对二进制文件进行签名也会产生同样的问题。

clang -Wl,-e, -Wl,__start -static -nostdlib test.c -o static_sign.out 
codesign -s - static_sign.out 
./static_sign.out 
zsh: killed     ./static_sign.out

以下消息在控制台中生成:

taskgated: UNIX error exception: 3
taskgated: no signature for pid=93166 (cannot make code: UNIX[No such process])

但是codesign可以验证签名

codesign -v -v static_sign.out 
static_sign.out: valid on disk
static_sign.out: satisfies its Designated Requirement

谁能澄清为什么 macOS 决定终止 clang 生成的二进制文件?

最佳答案

因为除了 x86_64 之外的任何架构都明确不允许使用静态二进制文件。
XNU 包含 this code piece在 Mach-O 加载器中:

case MH_EXECUTE:
    if (depth != 1 && depth != 3) {
        return LOAD_FAILURE;
    }
    if (header->flags & MH_DYLDLINK) {
        /* Check properties of dynamic executables */
        if (!(header->flags & MH_PIE) && pie_required(header->cputype, header->cpusubtype & ~CPU_SUBTYPE_MASK)) {
            return LOAD_FAILURE;
        }
        result->needs_dynlinker = TRUE;
    } else if (header->cputype == CPU_TYPE_X86_64) {
        /* x86_64 static binaries allowed */
    } else {
        /* Check properties of static executables (disallowed except for development) */
#if !(DEVELOPMENT || DEBUG)
        return LOAD_FAILURE;
#endif
    }
    break;

如果您在 x86_64 上执行完全相同的操作,它会起作用:

void _start()
{
    __asm__ volatile
    (
        ".intel_syntax noprefix\n"
        "mov eax, 0x2000001\n"
        "mov edi, 42\n"
        "syscall"
    );
}
% clang -Wl,-e,__start -static -nostdlib t.c -o t -arch x86_64
% ./t
% echo $?
42

关于macos - 为什么 macOS 会杀死由 clang 创建的静态可执行文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71723764/

相关文章:

Python 从线程更新 Matplotlib

macos - 在 OS X 上停止 hg 服务

ios - 如何在iOS上为Clang生成链接映射文件?

c - 链接到 OSX 上的可执行文件

c - Mac OS X 10.7 (Lion) 中的 Nano 语法突出显示?

macos - 如何让 IntelliJ UE 和 Tomcat 9 运行我的 Web 应用程序? (苹果系统)

c++ - C++ 中公共(public)子表达式消除的局限性

c++ - 类模板非依赖成员变量中是否需要模板限定符?

swift - 从 Swift 调用 getsectiondata

c - C中的汇编代码是什么?