macOS 64位系统调用表

Ben*_*ett 4 macos assembly x86-64 system-calls

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

操作的macOS呼叫号码是sys_write什么?

Ben*_*ett 8

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

4   AUE_NULL    ALL { user_ssize_t write(int fd, user_addr_t cbuf, user_size_t nbyte); } 
Run Code Online (Sandbox Code Playgroud)

在向哪些寄存器传递参数方面,它与 64 位 Linux 相同。rdi参数分别通过、rsirdxr10r8寄存器传递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
Run Code Online (Sandbox Code Playgroud)

不过,错误返回与 Linux 不同:出错时,CF=1 且 RAX=errno 代码。(与使用带内信令的 Linux 相比。)请参阅rax=-4095..-1汇编中(进位标志)和系统调用之间的关系是什么(Mac OS 上的 x64 Intel 语法)?-errno

在任何内核代码运行之前, RCX 和 R11 都会被指令本身覆盖syscall,因此该部分必然与 Linux 相同。

  • 请注意,这通常不起作用。有些电话号码相同,但大多数号码会有所不同。从 Linux 系统调用号推断 OS X 系统调用号是一个非常糟糕的主意。不要那样做! (2认同)

Tec*_*eks 6

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

如果使用libsystem_kernel syscall导出,则可以按原样使用数字。如果使用汇编,则必须添加0x2000000来将它们标记为BSD层(而不是0x1000000,这意味着Mach陷阱,或者0x3000000,这意味着取决于机器)。

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


Ols*_*ist 6

正如已经指出的,您需要将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.
Run Code Online (Sandbox Code Playgroud)

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 */
Run Code Online (Sandbox Code Playgroud)

每个系统调用都标有左移 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)))
Run Code Online (Sandbox Code Playgroud)

显然,您可以从内核源代码中获得这个神奇的数字,但不能从开发人员包含文件中获得。我认为这意味着 Apple 确实希望您链接到解析系统调用填充程序的库对象文件,而不是使用内联例程:对象兼容性而不是源兼容性。

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