iOS ARM64 系统调用 [英] iOS ARM64 Syscalls
问题描述
我正在学习更多关于 shellcode 和在 iOS 设备上使用 arm64 进行系统调用的知识.我正在测试的设备是 iPhone 6S.
我从这个链接 (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/).
我认为用于为 arm64 传递参数的各种寄存器应该与 arm 相同,因此我参考了此链接 (https://w3challs.com/syscalls/?arch=arm_strong),摘自 https://azeria-labs.com/writing-arm-shellcode/.
我在 Xcode 中编写了内联汇编,这里有一些片段
//退出系统调用__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 使用 x8 作为系统调用号"mov x0,#1;"//1 为标准输出文件描述符"mov x1,%0;"//要显示的缓冲区"mov x2,%1;"//缓冲区大小svc 0x80;"::"r"(write_buffer),"r"(write_buffer_size):"x0","x1","x2","x8");
如果这个系统调用有效,它应该在 Xcode 的控制台输出屏幕中打印出一些文本.但是,没有打印任何内容.
网上有很多关于 ARM 汇编的文章,有些使用 svc 0x80
,有些使用 svc 0
等等,所以可能会有一些变化.我尝试了各种方法,但我无法让这两个代码片段工作.
有人可以提供一些指导吗?
这是我编写 C 函数 syscall int return_value=syscall(1,0);
mov x1, sp移动 x30,#0str x30, [x1]orr w8, wzr, #0x1stur x0, [x29, #-32] ;8 字节折叠溢出移动 x0, x8bl_系统调用
我不确定为什么会发出此代码.
用于系统调用的寄存器完全是任意的,你选择的资源对于 XNU 来说肯定是错误的.
据我所知,arm64 的 XNU 系统调用 ABI 是完全私有的,如有更改,恕不另行通知,因此没有遵循的已发布标准,但您可以通过获取 XNU 的副本来拼凑它的工作原理源(如tarballs,或在线查看(如果您愿意),grep handle_svc
函数,然后按照代码操作.
我不会详细说明您到底在哪里找到哪些位,但最终结果是:
- 忽略传递给
svc
的立即数,但标准库使用svc 0x80
. x16
保存系统调用号x0
到x8
最多可容纳 9 个参数*- 栈上没有参数
x0
和x1
最多保存 2 个返回值(例如在fork
的情况下)- 进位位用于报告错误,在这种情况下
x0
保存错误代码
* 这仅在具有 8 个参数的间接系统调用 (x16 = 0
) 的情况下使用.
* XNU 源代码中的评论也提到了 x9
,但似乎编写该代码的工程师应该纠正一一错误.
然后是可用的实际系统调用号:
- UNIX 系统调用"的规范来源是 XNU 源代码树中的文件
bsd/kern/syscalls.master
.在最新的 iOS 13 测试版中,这些系统调用号从0
到大约540
. - Mach 系统调用"的规范来源是 XNU 源代码树中的文件
osfmk/kern/syscall_sw.c
.这些系统调用使用-10
和-100
之间的 负 数字调用(例如-28
将是task_self_trap
). - 与最后一点无关,可以使用系统调用号
-3
和-4<调用两个系统调用
mach_absolute_time
和mach_continuous_time
分别. - 一些低级操作可通过
platform_syscall
和系统调用号0x80000000
进行.
I am learning more about shellcode and making syscalls in arm64 on iOS devices. The device I am testing on is iPhone 6S.
I got the list of syscalls from this link (https://github.com/radare/radare2/blob/master/libr/include/sflib/darwin-arm-64/ios-syscalls.txt).
I learnt that x8 is used for putting the syscall number for arm64 from here (http://arm.ninja/2016/03/07/decoding-syscalls-in-arm64/).
I figured the various registers used to pass in parameters for arm64 should be the same as arm so I referred to this link (https://w3challs.com/syscalls/?arch=arm_strong), taken from https://azeria-labs.com/writing-arm-shellcode/.
I wrote inline assembly in Xcode and here are some snippets
//exit syscall
__asm__ volatile("mov x8, #1");
__asm__ volatile("mov x0, #0");
__asm__ volatile("svc 0x80");
However, the application does not terminate when I stepped over these codes.
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"
);
If this syscall works, it should print out some text in Xcode's console output screen. However, nothing gets printed.
There are many online articles for ARM assembly, some use svc 0x80
and some use svc 0
etc and so there can be a few variations. I tried various methods but I could not get the two code snippets to work.
Can someone provide some guidance?
EDIT:
This is what Xcode shows in its Assembly view when I wrote a C function syscall 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
I am not sure why this code was emitted.
The registers used for syscalls are completely arbitrary, and the resources you've picked are certainly wrong for XNU.
As far as I'm aware, the XNU syscall ABI for arm64 is entirely private and subject to change without notice so there's no published standard that it follows, but you can scrape together how it works by getting a copy of the XNU source (as tarballs, or viewing it online if you prefer that), grep for the handle_svc
function, and just following the code.
I'm not gonna go into detail on where exactly you find which bits, but the end result is:
- The immediate passed to
svc
is ignored, but the standard library usessvc 0x80
. x16
holds the syscall numberx0
throughx8
hold up to 9 arguments*- There are no arguments on the stack
x0
andx1
hold up to 2 return values (e.g. in the case offork
)- The carry bit is used to report an error, in which case
x0
holds the error code
* This is used only in the case of an indirect syscall (x16 = 0
) with 8 arguments.
* Comments in the XNU source also mention x9
, but it seems the engineer who wrote that should brush up on off-by-one errors.
And then it comes to the actual syscall numbers available:
- The canonical source for "UNIX syscalls" is the file
bsd/kern/syscalls.master
in the XNU source tree. Those take syscall numbers from0
up to about540
in the latest iOS 13 beta. - The canonical source for "Mach syscalls" is the file
osfmk/kern/syscall_sw.c
in the XNU source tree. Those syscalls are invoked with negative numbers between-10
and-100
(e.g.-28
would betask_self_trap
). - Unrelated to the last point, two syscalls
mach_absolute_time
andmach_continuous_time
can be invoked with syscall numbers-3
and-4
respectively. - A few low-level operations are available through
platform_syscall
with the syscall number0x80000000
.
这篇关于iOS ARM64 系统调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!