macOS 64 位系统调用 Table
macOS 64-bit System Call Table
我可以找到一个 Linux 64 位系统调用 table,但调用号码在 macOS 上不起作用 - 我每次尝试使用它们时都会收到 Bus Error: 10
。
sys_write
等操作的 macOS 呼叫号码是多少?
您需要使用 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。参数分别通过 rdi
、rsi
、rdx
、r10
、r8
和 r9
寄存器传递。 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
您可以在(/usr/include/)sys/syscall.h中从用户模式获取系统调用号码列表。这些数字与 Linux 中的数字不同。该文件是在 XNU 构建期间从 bsd/kern/syscalls/syscalls.master.
自动生成的
如果您使用 libsystem_kernel 系统调用导出,您可以按原样使用这些数字。如果您使用汇编,则必须添加 0x2000000 以将它们标记为 BSD 层(而不是 0x1000000,这意味着 Mach 陷阱,或 0x3000000,这意味着机器相关)。
要查看系统调用在汇编中的使用示例,您可以轻松反汇编导出的包装器:x86_64 的 /usr/lib/system/libsystem_kernel.dylib(或 ARM64 使用共享库缓存中的 jtool)。
如前所述,您需要在索书号中添加0x2000000。那个幻数的解释来自 osfmk/mach/i386/syscall_sw.h 中的 xnu 内核源代码(搜索 SYSCALL_CLASS_SHIFT
)。
/*
* 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 上有 class 个系统调用。所有的系统调用都是通过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 */
每个系统调用都带有一个 class 枚举标记,该枚举左移 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 真的希望你 link 反对解析你的 系统调用 shim 的库对象文件,而不是使用内联例程:对象兼容性而不是源兼容性。
在 x86_64 上,系统调用本身像 Linux 一样使用 System V ABI(第 A.2.1 节),并且它使用 syscall
指令(int 0x80
Linux 中的系统调用)。参数在 rdi、rsi、rdx、r10、r8 和 r9 中传递。系统调用号在 rax 寄存器中。
我可以找到一个 Linux 64 位系统调用 table,但调用号码在 macOS 上不起作用 - 我每次尝试使用它们时都会收到 Bus Error: 10
。
sys_write
等操作的 macOS 呼叫号码是多少?
您需要使用 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。参数分别通过 rdi
、rsi
、rdx
、r10
、r8
和 r9
寄存器传递。 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
您可以在(/usr/include/)sys/syscall.h中从用户模式获取系统调用号码列表。这些数字与 Linux 中的数字不同。该文件是在 XNU 构建期间从 bsd/kern/syscalls/syscalls.master.
自动生成的如果您使用 libsystem_kernel 系统调用导出,您可以按原样使用这些数字。如果您使用汇编,则必须添加 0x2000000 以将它们标记为 BSD 层(而不是 0x1000000,这意味着 Mach 陷阱,或 0x3000000,这意味着机器相关)。
要查看系统调用在汇编中的使用示例,您可以轻松反汇编导出的包装器:x86_64 的 /usr/lib/system/libsystem_kernel.dylib(或 ARM64 使用共享库缓存中的 jtool)。
如前所述,您需要在索书号中添加0x2000000。那个幻数的解释来自 osfmk/mach/i386/syscall_sw.h 中的 xnu 内核源代码(搜索 SYSCALL_CLASS_SHIFT
)。
/*
* 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 上有 class 个系统调用。所有的系统调用都是通过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 */
每个系统调用都带有一个 class 枚举标记,该枚举左移 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 真的希望你 link 反对解析你的 系统调用 shim 的库对象文件,而不是使用内联例程:对象兼容性而不是源兼容性。
在 x86_64 上,系统调用本身像 Linux 一样使用 System V ABI(第 A.2.1 节),并且它使用 syscall
指令(int 0x80
Linux 中的系统调用)。参数在 rdi、rsi、rdx、r10、r8 和 r9 中传递。系统调用号在 rax 寄存器中。