【问题标题】:macOS 64-bit System Call Table [duplicate]macOS 64 位系统调用表 [重复]
【发布时间】:2018-07-28 11:31:03
【问题描述】:

我可以找到一个 Linux 64 位系统调用表,但调用号码在 macOS 上不起作用 - 每当我尝试使用它们时都会收到 Bus Error: 10

sys_write 等操作的 macOS 调用号码是什么?

【问题讨论】:

标签: macos assembly x86-64 system-calls


【解决方案1】:

您可以在 (/usr/include/)sys/syscall.h 中从用户模式获取系统调用号码列表。这些数字与 Linux 中的数字不同。该文件是在 XNU 构建期间从 bsd/kern/syscalls/syscalls.master 自动生成的。

如果您使用 libsystem_kernel 系统调用导出,您可以按原样使用这些数字。如果您使用汇编,则必须添加 0x2000000 以将它们标记为 BSD 层(而不是 0x1000000,这意味着马赫陷阱,或 0x3000000,这意味着机器依赖)。

要查看汇编中系统调用使用的示例,您可以轻松反汇编导出的包装器:x86_64 的 /usr/lib/system/libsystem_kernel.dylib(或 ARM64 使用共享库缓存中的 jtool)。

【讨论】:

  • @MichaelPetch idk... 6 个零在我的机器上工作,但 7 个失败。
【解决方案2】:

正如已经指出的,您需要将 0x2000000 添加到索书号。这个幻数的解释来自osfmk/mach/i386/syscall_sw.h(搜索SYSCALL_CLASS_SHIFT)中的xnu内核源代码。

/*
 * Syscall classes for 64-bit system call entry.
 * For 64-bit users, the 32-bit syscall number is partitioned
 * with the high-order bits representing the class and low-order
 * bits being the syscall number within that class.
 * The high-order 32-bits of the 64-bit syscall number are unused.
 * All system classes enter the kernel via the syscall instruction.

在 OSX 上有多种系统调用。所有系统调用都通过 syscall 指令进入内核。那时有 Mach 系统调用、BSD 系统调用、NONE、诊断和机器相关。

#define SYSCALL_CLASS_NONE  0   /* Invalid */
#define SYSCALL_CLASS_MACH  1   /* Mach */  
#define SYSCALL_CLASS_UNIX  2   /* Unix/BSD */
#define SYSCALL_CLASS_MDEP  3   /* Machine-dependent */
#define SYSCALL_CLASS_DIAG  4   /* Diagnostics */

每个系统调用都用一个左移 24 位的类枚举标记,SYSCALL_CLASS_SHIFT。 BSD 系统调用的枚举为 2,SYSCALL_CLASS_UNIX。所以这个幻数 0x2000000 被构造为:

// 2 << 24
#define SYSCALL_CONSTRUCT_UNIX(syscall_number) \
            ((SYSCALL_CLASS_UNIX << SYSCALL_CLASS_SHIFT) | \
             (SYSCALL_NUMBER_MASK & (syscall_number)))

显然,您可以从内核源代码中获取该幻数,但不能从开发人员的包含文件中获取。我认为这意味着 Apple 真的希望您链接到解决您的系统调用 shim 的库对象文件,而不是使用内联例程:对象兼容性而不是源兼容性。

在 x86_64 上,系统调用本身像 Linux 一样使用 System V ABI(第 A.2.1 节),它使用 syscall 指令(int 0x80 用于 Linux 中的系统调用)。参数在 rdi、rsi、rdx、r10、r8 和 r9 中传递。系统调用号在 rax 寄存器中。

【讨论】:

    【解决方案3】:

    您需要使用syscalls.master 文件将0x2000000 添加到索书号。我正在使用the XNU bds/kern/syscalls.master file。这是我要调用的syscalls.master 文件中的一个函数:

    4   AUE_NULL    ALL { user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte); } 
    

    在向哪些寄存器传递参数方面,它与 64 位 Linux 相同。参数分别通过rdirsirdxr10r8r9 寄存器传递。 write 函数采用三个参数,在以下程序集中进行了描述:

    mov rax, 0x2000004     ; sys_write call identifier
    mov rdi, 1             ; STDOUT file descriptor
    mov rsi, myMessage     ; buffer to print
    mov rdx, myMessageLen  ; length of buffer
    syscall                ; make the system call
    

    【讨论】:

    • 请注意,这通常不起作用。有些电话号码相同,但大多数号码会有所不同。从 Linux 系统调用号推断 OS X 系统调用号是一个非常糟糕的主意。不要那样做!
    • @fuz 实际上,这很有趣。你知道任何 macOS 系统调用表吗?
    • 我不知道它是否准确,但我发现了这个:github.com/dyjakan/osx-syscalls-list
    • 您没有使用 Linux 系统调用表。您想使用 FreeBSD 系统调用表。
    • @Bennett 按照惯例,系统调用号记录在包含文件&lt;sys/syscall.h&gt; 中。我不确定这个文件在 OS X 上的什么位置,但类似的东西应该在某个地方。
    猜你喜欢
    • 2020-04-22
    • 2018-06-06
    • 2011-07-06
    • 1970-01-01
    • 1970-01-01
    • 2018-10-01
    相关资源
    最近更新 更多