Kernel Syscalls

From The iPhone Wiki
Revision as of 08:17, 12 June 2012 by Morpheus (talk | contribs) (List of system calls from iOS 6.0b1 - watch this space for more)
Jump to: navigation, search

Note on these

Args go in their normal registers, like arg1 in R0, as usual. Syscall # goes in IP (that's intra-procedural, not instruction pointer!), a.k.a R12.

As in all ARM (i.e. also on Android) the kernel entry is accomplished by the SVC command (SWI in some debuggers and ARM dialects). On the kernel end, a low level CPU exception handler (fleh_swi) is installed as part of the ExceptionVectorsBase, and - upon issuing a SWI/SVC - control is transferred to that address. This handler can check the syscall number to distinguish between POSIX calls (non negative) and Mach traps (negative).


Unix

Usage

MOV IP, #x // number from following list into Intraprocedural, a.k.a. r12
SVC 0x80   // Formerly, SWI (software interrupt)

For example:


(gdb) disass chown
0x30d2ad54 <chown>:	mov	r12, #16	       ; 0x10, being # of chown
0x30d2ad58 <chown+4>:	svc	0x00000080

Most of these are the same as you would find in the XNU open source kernel, with ARM idiosyncrasies aside (and #372, ledger)

sysent

The system call table in XNU is known as "sysent", and is no longer a public symbol, for obvious reasons (e.g. syscall hooking). It is fairly straightforward, however, to find the sysent and its calls. While i0nic proposes a heuristic of finding the sysent based on the (still) exported kdebug symbol, this is unreliable, as the latter might change in the future (either be moved or no longer exported). A better way is to home in on the pattern of the struct sysent entries itself, i.e - as defined in bsd/sys/sysent.h:


struct sysent {         /* system call table */
        int16_t         sy_narg;        /* number of args */
        int8_t          sy_resv;        /* reserved  */
        int8_t          sy_flags;       /* flags */
        sy_call_t       *sy_call;       /* implementing function */
        sy_munge_t      *sy_arg_munge32; /* system call arguments munger for 32-bit process */
        sy_munge_t      *sy_arg_munge64; /* system call arguments munger for 64-bit process */
        int32_t         sy_return_type; /* system call return types */
        uint16_t        sy_arg_bytes;   /* Total size of arguments in bytes for
                                         * 32-bit system calls
                                         */
};

Because system calls arguments are set in stone, it is straightforward to write code to find the signature of the first few syscalls (syscall, exit, fork..), and from there calculate the other sysent entries. A program to do so reliable on iOS has, in fact, been written, and produces the following output for iOS 5.1:

List of system calls from iOS 5.1

note: Even though a syscall is present in the table, it does not in any way imply it is functional. Auditing, for example, is not enabled in iOS (no CONFIG_AUDIT in the XNU build). Most of these syscalls are the same as those of OS X, with the exception of ledger (which actually makes a comeback in OS X Mountain Lion), and 434+ (CONFIG_EMBEDDED).


$ ./fsysent ~/Documents/projects/iOS.6.0b1.iPod4.kernel 
mach_trap_table offset in file (for patching purposes): 3064992 (0x2ec4a0)
Sysent offset in file (for patching purposes):  3076288 (0x2ef0c0)
This appears to be XNU 2107.1.78

syscall              801e9d5c T
exit                 801d32dc T
fork                 801d61d4 T
read                 801e9d7c T
write                801ea150 T
open                 800b12f0 T
close                801cb904 T
wait4                801d3f10 T
8  old creat         801e9d5c T
link                 800b1804 T
unlink               800b1f0c T
11  old execv        801e9d5c T
chdir                800b0be0 T
fchdir               800b0a70 T
mknod                800b13d8 T
chmod                800b2a5c T
chown                800b2bb8 T
17  old break        801e9d5c T
getfsstat            800b080c T
19  old lseek        801e9d5c T
getpid               801daa60 T
21  old mount        801e9d5c T
22  old umount       801e9d5c T
setuid               801dad14 T
getuid               801daae4 T
geteuid              801daaf4 T
ptrace               801e6924 T
recvmsg              802090f4 T
sendmsg              80208c3c T
recvfrom             80208d20 T
accept               802085f4 T
getpeername          802093c0 T
getsockname          80209310 T
access               800b23c8 T
chflags              800b2844 T
fchflags             800b290c T
sync                 800b02a0 T
kill                 801de620 T
38  old stat         801e9d5c T
getppid              801daa68 T
40  old lstat        801e9d5c T
dup                  801c9a94 T
pipe                 801ec3dc T
getegid              801dab6c T
profil               801e9d5c T
45  old ktrace       801e9d5c T
sigaction            801dd73c T
getgid               801dab5c T
sigprocmask          801ddc80 T
getlogin             801db93c T
setlogin             801db9b4 T
acct                 801c447c T
sigpending           801dde24 T
sigaltstack          801de564 T
ioctl                801ea514 T
reboot               801e6888 T
revoke               800b4320 T
symlink              800b1a74 T
readlink             800b2748 T
execve               801d2cb0 T
umask                800b42f8 T
chroot               800b0cb0 T
62  old fstat        801e9d5c T
63  used internally , reserved 801e9d5c T
64  old getpagesize  801e9d5c T
msync                801d6d24 T
vfork                801d586c T
67  old vread        801e9d5c T
68  old vwrite       801e9d5c T
69  old sbrk         801e9d5c T
70  old sstk         801e9d5c T
71  old mmap         801e9d5c T
72  old vadvise      801e9d5c T
munmap               801d6dd0 T
mprotect             801d6e04 T
madvise              801d6ebc T
76  old vhangup      801e9d5c T
77  old vlimit       801e9d5c T
mincore              801d6f28 T
getgroups            801dab7c T
setgroups            801db880 T
getpgrp              801daa70 T
setpgid              801dac1c T
setitimer            801e6370 T
84  old wait         801e9d5c T
swapon               8021a638 T
getitimer            801e6228 T
87  old gethostname  801e9d5c T
88  old sethostname  801e9d5c T
getdtablesize        801c966c T
dup2                 801c9ec0 T
91  old getdopt      801e9d5c T
fcntl                801ca2d8 T
select               801ea7c0 T
94  old setdopt      801e9d5c T
fsync                800b3154 T
setpriority          801dbce8 T
socket               8020809c T
connect              80208614 T
99  old accept       801e9d5c T
getpriority          801dbbdc T
101  old send        801e9d5c T
102  old recv        801e9d5c T
103  old sigreturn   801e9d5c T
bind                 80208168 T
setsockopt           80209228 T
listen               802082d4 T
107  old vtimes      801e9d5c T
108  old sigvec      801e9d5c T
109  old sigblock    801e9d5c T
110  old sigsetmask  801e9d5c T
sigsuspend           801dde4c T
112  old sigstack    801e9d5c T
113  old recvmsg     801e9d5c T
114  old sendmsg     801e9d5c T
115  old vtrace      801e9d5c T
gettimeofday         801e6038 T
getrusage            801dca80 T
getsockopt           8020928c T
119  old resuba      801e9d5c T
readv                801ea008 T
writev               801ea3a8 T
settimeofday         801e6094 T
fchown               800b2cc8 T
fchmod               800b2b8c T
125  old recvfrom    801e9d5c T
setreuid             801db060 T
setregid             801db3f4 T
rename               800b3344 T
129  old truncate    801e9d5c T
130  old ftruncate   801e9d5c T
flock                801cce8c T
mkfifo               800b16b4 T
sendto               80208960 T
shutdown             802091f8 T
socketpair           80208804 T
mkdir                800b3c38 T
rmdir                800b3c78 T
utimes               800b2d7c T
futimes              800b2f50 T
adjtime              801e6198 T
141  old getpeername 801e9d5c T
gethostuuid          801ebe9c T
143  old sethostid   801e9d5c T
144  old getrlimit   801e9d5c T
145  old setrlimit   801e9d5c T
146  old killpg      801e9d5c T
setsid               801dabd8 T
148  old setquota    801e9d5c T
149  old qquota      801e9d5c T
150  old getsockname 801e9d5c T
getpgid              801daa78 T
setprivexec          801daa48 T
pread                801e9f6c T
pwrite               801ea2c8 T
nfssvc               801e9d5c T
156  old getdirentries 801e9d5c T
statfs               800b0340 T
fstatfs              800b05f8 T
unmount              800afe08 T
160  old async_daemon 801e9d5c T
getfh                801e9d5c T
162  old getdomainname 801e9d5c T
163  old setdomainname 801e9d5c T
164                  801e9d5c T
quotactl             800b033c T
166  old exportfs    801e9d5c T
mount                800aefe8 T
168  old ustat       801e9d5c T
csops                801d9824 T
170  old table       801d9d10 T
171  old wait3       801e9d5c T
172  old rpause      801e9d5c T
waitid               801d4308 T
174  old getdents    801e9d5c T
175  old gc_control  801e9d5c T
add_profil           801e9d5c T
177                  801e9d5c T
178                  801e9d5c T
179                  801e9d5c T
kdebug_trace         801c1d58 T
setgid               801db1f8 T
setegid              801db304 T
seteuid              801daf64 T
sigreturn            8021cfa8 T
chud                 8021bcb8 T
186                  801e9d5c T
fdatasync            800b31cc T
stat                 800b24a4 T
fstat                801cbb98 T
lstat                800b25f0 T
pathconf             800b26e4 T
fpathconf            801cbbf4 T
193                  801e9d5c T
getrlimit            801dc8c8 T
setrlimit            801dc190 T
getdirentries        800b3eb0 T
mmap                 801d6814 T
198  __syscall       801e9d5c T
lseek                800b1f84 T
truncate             800b2fd0 T
ftruncate            800b3090 T
__sysctl             801e0ccc T
mlock                801d7074 T
munlock              801d70cc T
undelete             800b1c0c T
ATsocket             801e9d5c T
ATgetmsg             801e9d5c T
ATputmsg             801e9d5c T
ATPsndreq            801e9d5c T
ATPsndrsp            801e9d5c T
ATPgetreq            801e9d5c T
ATPgetrsp            801e9d5c T
213  Reserved for AppleTalk 801e9d5c T
214                  801e9d5c T
215                  801e9d5c T
mkcomplex            800b1224 T
statv                801e9d5c T
lstatv               801e9d5c T
fstatv               801e9d5c T
getattrlist          8009afe0 T
setattrlist          8009b058 T
getdirentriesattr    800b4408 T
exchangedata         800b45c4 T
224  old checkuseraccess / fsgetpath ( which moved to 427 ) 801e9d5c T
searchfs             800b4804 T
delete               800b1f48 T
copyfile             800b31e8 T
fgetattrlist         80098408 T
fsetattrlist         8009b760 T
poll                 801eaf24 T
watchevent           801eb84c T
waitevent            801eb9f0 T
modwatch             801ebb60 T
getxattr             800b5478 T
fgetxattr            800b55b4 T
setxattr             800b56b4 T
fsetxattr            800b57c0 T
removexattr          800b58bc T
fremovexattr         800b5984 T
listxattr            800b5a44 T
flistxattr           800b5b28 T
fsctl                800b4cfc T
initgroups           801db6fc T
posix_spawn          801d1d74 T
ffsctl               800b539c T
246                  801e9d5c T
nfsclnt              801e9d5c T
fhopen               801e9d5c T
249                  801e9d5c T
minherit             801d6e84 T
semsys               801e9d5c T
msgsys               801e9d5c T
shmsys               801e9d5c T
semctl               801e9d5c T
semget               801e9d5c T
semop                801e9d5c T
257                  801e9d5c T
msgctl               801e9d5c T
msgget               801e9d5c T
msgsnd               801e9d5c T
msgrcv               801e9d5c T
shmat                801e9d5c T
shmctl               801e9d5c T
shmdt                801e9d5c T
shmget               801e9d5c T
shm_open             8020d2c0 T
shm_unlink           8020dda0 T
sem_open             8020c718 T
sem_close            8020ceb0 T
sem_unlink           8020cc78 T
sem_wait             8020cf08 T
sem_trywait          8020cfd0 T
sem_post             8020d074 T
sem_getvalue         8020d118 T
sem_init             8020d110 T
sem_destroy          8020d114 T
open_extended        800b1144 T
umask_extended       800b42a8 T
stat_extended        800b244c T
lstat_extended       800b2598 T
fstat_extended       801cb97c T
chmod_extended       800b294c T
fchmod_extended      800b2a90 T
access_extended      800b20bc T
settid               801db580 T
gettid               801dab04 T
setsgroups           801db890 T
getsgroups           801dabd0 T
setwgroups           801db894 T
getwgroups           801dabd4 T
mkfifo_extended      800b1610 T
mkdir_extended       800b3a4c T
identitysvc          801e9d5c T
shared_region_check_np 8021ab68 T
shared_region_map_np 801e9d5c T
vm_pressure_monitor  8021b2cc T
psynch_rw_longrdlock 8021415c T
psynch_rw_yieldwrlock 80214408 T
psynch_rw_downgrade  80214410 T
psynch_rw_upgrade    8021440c T
psynch_mutexwait     80211374 T
psynch_mutexdrop     80212338 T
psynch_cvbroad       8021238c T
psynch_cvsignal      80212970 T
psynch_cvwait        80212df8 T
psynch_rw_rdlock     80213530 T
psynch_rw_wrlock     80214160 T
psynch_rw_unlock     80214414 T
psynch_rw_unlock2    8021470c T
getsid               801daaa8 T
settid_with_pid      801db620 T
312  old __pthread_cond_timedwait 80213430 T
aio_fsync            801c4e60 T
aio_return           801c5038 T
aio_suspend          801c52c0 T
aio_cancel           801c49d8 T
aio_error            801c4db4 T
aio_read             801c5018 T
aio_write            801c54d4 T
lio_listio           801c54f4 T
321  old __pthread_cond_wait 801e9d5c T
iopolicysys          801dcc74 T
323                  80218edc T
mlockall             801d7108 T
munlockall           801d710c T
326                  801e9d5c T
issetugid            801dad04 T
__pthread_kill       801de298 T
__pthread_sigmask    801de2f8 T
__sigwait            801de3a8 T
__disable_threadsignal 801ddf74 T
__pthread_markcancel 801ddf90 T
__pthread_canceled   801ddfd8 T
__semwait_signal     801de178 T
335  old utrace      801e9d5c T
proc_info            80216dc0 T
sendfile             801e9d5c T
stat64               800b24f0 T
fstat64              801cbbd4 T
lstat64              800b263c T
stat64_extended      800b2540 T
lstat64_extended     800b268c T
fstat64_extended     801cbbb8 T
getdirentries64      800b4268 T
statfs64             800b0660 T
fstatfs64            800b07a8 T
getfsstat64          800b09b8 T
__pthread_chdir      800b0ca8 T
__pthread_fchdir     800b0bd8 T
audit                801c0a18 T
auditon              801c0a1c T
352                  801e9d5c T
getauid              801c0a20 T
setauid              801c0a24 T
getaudit             801e9d5c T
setaudit             801e9d5c T
getaudit_addr        801c0a28 T
setaudit_addr        801c0a2c T
auditctl             801c0a30 T
bsdthread_create     80215260 T
bsdthread_terminate  802154d8 T
kqueue               801cddec T
kevent               801cde6c T
lchown               800b2cb0 T
stack_snapshot       801c41a0 T
bsdthread_register   8021553c T
workq_open           80216190 T
workq_kernreturn     802165f8 T
kevent64             801ce104 T
__old_semwait_signal 801de04c T
__old_semwait_signal_nocancel 801de080 T
thread_selfid        80216afc T
ledger               801ebf04 T
374                  801e9d5c T
375                  801e9d5c T
376                  801e9d5c T
377                  801e9d5c T
378                  801e9d5c T
379                  801e9d5c T
__mac_execve         801d2cd0 T
__mac_syscall        8027b874 T
__mac_get_file       8027b51c T
__mac_set_file       8027b764 T
__mac_get_link       8027b640 T
__mac_set_link       8027b864 T
__mac_get_proc       8027b010 T
__mac_set_proc       8027b0d0 T
__mac_get_fd         8027b3c8 T
__mac_set_fd         8027b650 T
__mac_get_pid        8027af44 T
__mac_get_lcid       8027b184 T
__mac_get_lctx       8027b248 T
__mac_set_lctx       8027b304 T
setlcid              801dba7c T
getlcid              801dbb64 T
read_nocancel        801e9d9c T
write_nocancel       801ea170 T
open_nocancel        800b1368 T
close_nocancel       801cb920 T
wait4_nocancel       801d3f30 T
recvmsg_nocancel     80209114 T
sendmsg_nocancel     80208c5c T
recvfrom_nocancel    80208d40 T
accept_nocancel      80208314 T
msync_nocancel       801d6d3c T
fcntl_nocancel       801ca2f8 T
select_nocancel      801ea7dc T
fsync_nocancel       800b31c4 T
connect_nocancel     8020862c T
select_nocancel      801ea7dc T
fsync_nocancel       800b31c4 T
connect_nocancel     8020862c T
sigsuspend_nocancel  801ddf08 T
readv_nocancel       801ea028 T
writev_nocancel      801ea3c8 T
sendto_nocancel      80208980 T
pread_nocancel       801e9f8c T
pwrite_nocancel      801ea2e8 T
waitid_nocancel      801d4324 T
poll_nocancel        801eaf44 T
msgsnd_nocancel      801e9d5c T
msgrcv_nocancel      801e9d5c T
sem_wait_nocancel    8020cf24 T
aio_suspend_nocancel 801c52e0 T
__sigwait_nocancel   801de3e0 T
__semwait_signal_nocancel 801de1ac T
__mac_mount          800af00c T
__mac_get_mount      8027ba6c T
__mac_getfsstat      800b0830 T
fsgetpath            800b5c0c T
audit_session_self   801c0a0c T
audit_session_join   801c0a10 T
fileport_makeport    801ccf70 T
fileport_makefd      801cd0f4 T
audit_session_port   801c0a14 T
pid_suspend          8021a950 T
pid_resume           8021a9c0 T
pid_hibernate        8021aa2c T
pid_shutdown_sockets 8021aa84 T
437  old shared_region_slide_np 801e9d5c T
shared_region_map_and_slide_np 8021b118 T


Mach

XNU also supports the Mach personality, which is distinct from that of the UNIX syscalls discussed above. Mach syscalls (on 32-bit systems like iOS) are encoded as negative numbers, which is clever, since POSIX system calls are all non-negative. For example, consider mach_msg_trap:

_mach_msg_trap:
0001a8b4        e1a0c00d        mov     ip, sp
0001a8b8        e92d0170        push    {r4, r5, r6, r8}
0001a8bc        e89c0070        ldm     ip, {r4, r5, r6}
0001a8c0        e3e0c01e        mvn     ip, #30 @ 0x1e    ; Move NEGATIVE -30 into IP (R12)
0001a8c4        ef000080        svc     0x00000080        ; issue a supervisor call
0001a8c8        e8bd0170        pop     {r4, r5, r6, r8}
0001a8cc        e12fff1e        bx      lr
..
_semaphore_signal_all_trap:
0001a8f8        e3e0c021        mvn     ip, #33 @ 0x21   ; NEGATIVE -33 into IP (R12)
0001a8fc        ef000080        svc     0x00000080
0001a900        e12fff1e        bx      lr


Mach system calls are commonly known as "traps", and are maintained in a Mach Trap table. iOS's fleh_swi handler (the kernel entry point on the other side of the "SWI" or "SVC" command) checks the system call number - if it is negative, it is flipped (2's complement), and interpreted as Mach trap instead.

mach_trap_table

In iOS 5.x, the mach_trap_table is not far from the page_size export, and right next to the trap names. kern_invalid is the equivalent of ENOSYS. All the traps are ARM Thumb. The fsysent binary can be used to find the Mach trap table, as well.

$ ./fsysent -m ~/Documents/projects/iOS.5.1.iPod4.kernel 
This is an ARM binary. Applying iOS kernel signatures
mach_trap_table offset in file (for patching purposes): 2855556 (0x2b9284)
Kern invalid detected at 0x80025f50 (+1). Ignoring those.
..This appears to be XNU 1878.11.8
 // -- New in iOS 5 (and expect these in Mountain Lion)
 10 _kernelrpc_mach_vm_allocate_trap         800132ac T
 11 _kernelrpc_vm_allocate_trap              80013318 T
 12 _kernelrpc_mach_vm_deallocate_trap       800133b4 T
 13 _kernelrpc_vm_deallocate_trap            80013374 T
 14 _kernelrpc_mach_vm_protect_trap          8001343c T
 15 _kernelrpc_vm_protect_trap               800133f8 T
 16 _kernelrpc_mach_port_allocate_trap       80013494 T
 17 _kernelrpc_mach_port_destroy_trap        800134e4 T
 18 _kernelrpc_mach_port_deallocate_trap     80013520 T
 19 _kernelrpc_mach_port_mod_refs_trap       8001355c T
 20 _kernelrpc_mach_port_move_member_trap    8001359c T
 21 _kernelrpc_mach_port_insert_right_trap   800135e0 T
 22 _kernelrpc_mach_port_insert_member_trap  8001363c T
 23 _kernelrpc_mach_port_extract_member_trap 80013680 T
 // -----------------------------------------
 26 mach_reply_port                          800198ac T
 27 thread_self_trap                         80019890 T
 28 task_self_trap                           80019870 T
 29 host_self_trap                           80017db8 T
 31 mach_msg_trap                            80013c1c T
 32 mach_msg_overwrite_trap                  80013ae4 T
 33 semaphore_signal_trap                    800252d4 T
 34 semaphore_signal_all_trap                80025354 T
 35 semaphore_signal_thread_trap             80025260 T
 36 semaphore_wait_trap                      800255e8 T
 37 semaphore_wait_signal_trap               8002578c T
 38 semaphore_timedwait_trap                 800256c8 T
 39 semaphore_timedwait_signal_trap          8002586c T
 44 task_name_for_pid                        801e0734 T
 45 task_for_pid                             801e0598 T
 46 pid_for_task                             801e054c T
 48 macx_swapon                              801e127c T
 49 macx_swapoff                             801e14cc T
 51 macx_triggers                            801e1260 T
 52 macx_backing_store_suspend               801e11f0 T
 53 macx_backing_store_recovery              801e1198 T
 58 pfz_exit                                 80025944 T
 59 swtch_pri                                800259f4 T
 60 swtch                                    80025948 T
 61 thread_switch                            80025bb8 T
 62 clock_sleep_trap                         800160f0 T
 89 mach_timebase_info_trap                  80015318 T
 90 mach_wait_until_trap                     80015934 T
 91 mk_timer_create_trap                     8001d238 T
 92 mk_timer_destroy_trap                    8001d428 T
 93 mk_timer_arm_trap                        8001d46c T
 94 mk_timer_cancel_trap                     8001d4f0 T
100 iokit_user_client_trap (probably)        80234aa0 T