iOS ARM64 系统调用

2024-02-24

我正在学习更多关于 shellcode 以及在 iOS 设备上使用 arm64 进行系统调用的知识。我测试的设备是 iPhone 6S。

我从此链接获取了系统调用列表(https://github.com/radare/radare2/blob/master/libr/include/sflib/darwin-arm-64/ios-syscalls.txt https://github.com/radare/radare2/blob/master/libr/include/sflib/darwin-arm-64/ios-syscalls.txt).

我从这里了解到x8用于放置arm64的系统调用号(http://arm.ninja/2016/03/07/decoding-syscalls-in-arm64/ http://arm.ninja/2016/03/07/decoding-syscalls-in-arm64/).

我认为用于传递arm64参数的各种寄存器应该与arm相同,所以我参考了这个链接(https://w3challs.com/syscalls/?arch=arm_strong https://w3challs.com/syscalls/?arch=arm_strong), 取自https://azeria-labs.com/writing-arm-shellcode/ https://azeria-labs.com/writing-arm-shellcode/.

我在 Xcode 中编写了内联汇编,这里有一些片段

//exit syscall
__asm__ volatile("mov x8, #1");
__asm__ volatile("mov x0, #0");
__asm__ volatile("svc 0x80");

但是,当我跳过这些代码时,应用程序不会终止。

char write_buffer[]="console_text";
int write_buffer_size = sizeof(write_buffer);

__asm__ volatile("mov x8,#4;"     //arm64 uses x8 for syscall number
                 "mov x0,#1;"     //1 for stdout file descriptor
                 "mov x1,%0;"    //the buffer to display
                 "mov x2,%1;"    //buffer size
                 "svc 0x80;"
                 :
                 :"r"(write_buffer),"r"(write_buffer_size)
                 :"x0","x1","x2","x8"
                 );

如果这个系统调用有效,它应该在 Xcode 的控制台输出屏幕中打印出一些文本。但是,什么也没有打印出来。

网上有很多ARM汇编的文章,有的用svc 0x80和一些使用svc 0等等,所以可能会有一些变化。我尝试了各种方法,但无法使这两个代码片段工作。

有人可以提供一些指导吗?

编辑: 这是当我编写 C 函数系统调用时 Xcode 在其程序集视图中显示的内容int return_value=syscall(1,0);

    mov x1, sp
    mov x30, #0
    str x30, [x1]
    orr w8, wzr, #0x1
    stur    x0, [x29, #-32]         ; 8-byte Folded Spill
    mov x0, x8
    bl  _syscall

我不确定为什么会发出此代码。


用于系统调用的寄存器是任意的,并且您选择的资源对于 XNU 来说肯定是错误的。

据我所知,arm64 的 XNU 系统调用 ABI 是私有的,如有更改,恕不另行通知,因此它没有遵循的发布标准,但您可以通过查看 XNU 源代码来了解它的工作原理(在线查看 https://github.com/apple-oss-distributions/xnu or 下载压缩包 https://github.com/apple-oss-distributions/xnu/tags),特别是handle_svc功能 https://github.com/apple-oss-distributions/xnu/blob/19c3b8c28c31cb8130e034cfb5df6bf9ba342d90/osfmk/arm64/sleh.c#L1634.
我不会详细说明您到底在哪里找到哪些位,但最终结果是:

  • 立即传递给svc被忽略,但标准库使用svc 0x80 (see here https://github.com/apple-oss-distributions/xnu/blob/19c3b8c28c31cb8130e034cfb5df6bf9ba342d90/libsyscall/custom/SYS.h#L453 and here https://github.com/apple-oss-distributions/xnu/blob/19c3b8c28c31cb8130e034cfb5df6bf9ba342d90/osfmk/mach/arm/vm_param.h#L361).
  • x16保存系统调用号
  • x0通过x8最多可容纳 9 个参数*
  • 堆栈上没有参数
  • x0 and x1最多保存 2 个返回值(例如,在fork)
  • 进位位用于报告错误,此时x0保存错误代码

* 这仅在间接系统调用的情况下使用(x16 = 0)有 8 个参数。
* XNU 来源中的评论也提到x9,但似乎写这篇文章的工程师应该温习一下相差一的错误。

然后是实际可用的系统调用号:

  • “UNIX 系统调用”的规范来源是文件bsd/kern/syscalls.master https://github.com/apple-oss-distributions/xnu/blob/main/bsd/kern/syscalls.master在 XNU 源代码树中。那些从系统调用号中获取0高达约540在最新的 iOS 13 测试版中。
  • “Mach syscalls”的规范来源是文件osfmk/kern/syscall_sw.c https://github.com/apple-oss-distributions/xnu/blob/main/osfmk/kern/syscall_sw.c在 XNU 源代码树中。这些系统调用是通过以下方式调用的negative之间的数字-10 and -100 (e.g. -28将会task_self_trap).
  • 与最后一点无关,两个系统调用mach_absolute_time and mach_continuous_time可以用系统调用号调用-3 and -4分别。
  • 一些低级操作可以通过platform_syscall与系统调用号0x80000000.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS ARM64 系统调用 的相关文章

随机推荐