Kernel Syscalls

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

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).

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

For example, arm32:

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

And arm64: libsystem_kernel.dylib`chown: 0x1866c6084 <+0>: mov    x16, #0x10 0x1866c6088 <+4>: svc    #0x80

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 exported kdebug symbol, this is unreliable, as the symbol is 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 6.0b1:

List of system calls from iOS 6.0 GM
'''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).

A good reference on these can be found at Wiley's OS X and iOS Internals online appendix. The joker tool (shown below) can be downloaded from the same site.

$ joker -u ~/Documents/projects/iOS.6.0.iPod4.kernel This is an ARM binary. Applying iOS kernel signatures Entry point is 0x80085084....This appears to be XNU 2107.2.33 Syscall names are @2a70f0 Sysent offset in file/memory (for patching purposes): 0x2ef0c0/0x802f00c0

Suppressing enosys (0x800b3429) T = Thumb 1. exit                 801d4a74 T 2. fork                  801d7980 T 3. read                  801eb584 T 4. write                 801eb958 T 5. open                  800b13a4 T 6. close                 801ccab4 T 7. wait4                 801d56bc T 9. link                  800b18e8 T 10. unlink              800b1ff0 T 12. chdir               800b0c60 T 13. fchdir              800b0af0 T 14. mknod               800b14bc T 15. chmod               800b2b40 T 16. chown               800b2c9c T 18. getfsstat           800b088c T 20. getpid              801dc20c T 23. setuid              801dc4c0 T 24. getuid              801dc290 T 25. geteuid             801dc2a0 T 26. ptrace              801e812c T 27. recvmsg             8020a8fc T 28. sendmsg             8020a444 T 29. recvfrom            8020a528 T 30. accept              80209dfc T 31. getpeername         8020abc8 T 32. getsockname         8020ab18 T 33. access              800b24ac T 34. chflags             800b2928 T 35. fchflags            800b29f0 T 36. sync                800b0320 T 37. kill                801dfdcc T 39. getppid             801dc214 T 41. dup                 801cab04 T 42. pipe                801edbe4 T 43. getegid             801dc318 T 46. sigaction           801deee8 T 47. getgid              801dc308 T 48. sigprocmask         801df42c T 49. getlogin            801dd0e8 T 50. setlogin            801dd160 T 51. acct                801c54ec T 52. sigpending          801df5d0 T 53. sigaltstack         801dfd10 T 54. ioctl               801ebd1c T 55. reboot              801e8090 T 56. revoke              800b43f8 T 57. symlink             800b1b58 T 58. readlink            800b282c T 59. execve              801d4448 T 60. umask               800b43d0 T 61. chroot              800b0d30 T 65. msync               801d84d0 T 66. vfork               801d7018 T 73. munmap              801d857c T 74. mprotect            801d85b0 T 75. madvise             801d8668 T 78. mincore             801d86d4 T 79. getgroups           801dc328 T 80. setgroups           801dd02c T 81. getpgrp             801dc21c T 82. setpgid             801dc3c8 T 83. setitimer           801e7b78 T 85. swapon              8021be68 T 86. getitimer           801e7a30 T 89. getdtablesize       801ca6dc T 90. dup2                801caf54 T 92. fcntl               801cb420 T 93. select              801ebfc8 T 95. fsync               800b3238 T 96. setpriority         801dd494 T 97. socket              802098a4 T 98. connect             80209e1c T 100. getpriority         801dd388 T 104. bind                80209970 T 105. setsockopt          8020aa30 T 106. listen              80209adc T 111. sigsuspend          801df5f8 T 116. gettimeofday        801e7840 T 117. getrusage           801de22c T 118. getsockopt          8020aa94 T 120. readv               801eb810 T 121. writev              801ebbb0 T 122. settimeofday        801e789c T 123. fchown              800b2dac T 124. fchmod              800b2c70 T 126. setreuid            801dc80c T 127. setregid            801dcba0 T 128. rename              800b3428 T 131. flock               801ce20c T 132. mkfifo              800b1798 T 133. sendto              8020a168 T 134. shutdown            8020aa00 T 135. socketpair          8020a00c T 136. mkdir               800b3d1c T 137. rmdir               800b3d5c T 138. utimes              800b2e60 T 139. futimes             800b3034 T 140. adjtime             801e79a0 T 142. gethostuuid         801ed6a4 T 147. setsid              801dc384 T 151. getpgid             801dc224 T 152. setprivexec         801dc1f4 T 153. pread               801eb774 T 154. pwrite              801ebad0 T 157. statfs              800b03c0 T 158. fstatfs             800b0678 T 159. unmount             800afe88 T 165. quotactl            800b03bc T 167. mount               800af068 T 169. csops               801dafd0 T 170. 170 old table       801db4bc T 173. waitid              801d5ab4 T 180. kdebug_trace        801c2db4 T 181. setgid              801dc9a4 T 182. setegid             801dcab0 T 183. seteuid             801dc710 T 184. sigreturn           8021e7e4 T 185. chud                8021d4f4 T 187. fdatasync           800b32b0 T 188. stat                800b2588 T 189. fstat               801ccfec T 190. lstat               800b26d4 T 191. pathconf            800b27c8 T 192. fpathconf           801cd048 T 194. getrlimit           801de074 T 195. setrlimit           801dd93c T 196. getdirentries       800b3f94 T 197. mmap                801d7fc0 T 199. lseek               800b2068 T 200. truncate            800b30b4 T 201. ftruncate           800b3174 T 202. __sysctl            801e2478 T 203. mlock               801d8820 T 204. munlock             801d8878 T 205. undelete            800b1cf0 T 216. mkcomplex           800b12c4 T 220. getattrlist         8009b060 T 221. setattrlist         8009b0d8 T 222. getdirentriesattr   800b44e0 T 223. exchangedata        800b469c T 225. searchfs            800b48dc T 226. delete              800b202c T 227. copyfile            800b32cc T 228. fgetattrlist        80098488 T 229. fsetattrlist        8009b7e0 T 230. poll                801ec72c T 231. watchevent          801ed054 T 232. waitevent           801ed1f8 T 233. modwatch            801ed368 T 234. getxattr            800b5550 T 235. fgetxattr           800b568c T 236. setxattr            800b578c T 237. fsetxattr           800b5898 T 238. removexattr         800b5994 T 239. fremovexattr        800b5a5c T 240. listxattr           800b5b1c T 241. flistxattr          800b5c00 T 242. fsctl               800b4dd4 T 243. initgroups          801dcea8 T 244. posix_spawn         801d351c T 245. ffsctl              800b5474 T 250. minherit            801d8630 T 266. shm_open            8020eb24 T 267. shm_unlink          8020f604 T 268. sem_open            8020df80 T 269. sem_close           8020e718 T 270. sem_unlink          8020e4e0 T 271. sem_wait            8020e76c T 272. sem_trywait         8020e834 T 273. sem_post            8020e8d8 T 274. sem_getvalue        8020e97c T 275. sem_init            8020e974 T 276. sem_destroy         8020e978 T 277. open_extended       800b11d8 T 278. umask_extended      800b4380 T 279. stat_extended       800b2530 T 280. lstat_extended      800b267c T 281. fstat_extended      801ccdd0 T 282. chmod_extended      800b2a30 T 283. fchmod_extended     800b2b74 T 284. access_extended     800b21a0 T 285. settid              801dcd2c T 286. gettid              801dc2b0 T 287. setsgroups          801dd03c T 288. getsgroups          801dc37c T 289. setwgroups          801dd040 T 290. getwgroups          801dc380 T 291. mkfifo_extended     800b16f4 T 292. mkdir_extended      800b3b30 T 294. shared_region_check_np 8021c3a4 T 296. vm_pressure_monitor 8021cb08 T 297. psynch_rw_longrdlock 802159ac T 298. psynch_rw_yieldwrlock 80215c60 T 299. psynch_rw_downgrade 80215c68 T 300. psynch_rw_upgrade   80215c64 T 301. psynch_mutexwait    80212bd8 T 302. psynch_mutexdrop    80213b9c T 303. psynch_cvbroad      80213bf0 T 304. psynch_cvsignal     802141c0 T 305. psynch_cvwait       80214648 T 306. psynch_rw_rdlock    80214d7c T 307. psynch_rw_wrlock    802159b0 T 308. psynch_rw_unlock    80215c6c T 309. psynch_rw_unlock2   80215f64 T 310. getsid              801dc254 T 311. settid_with_pid     801dcdcc T 312. psynch_cvclrprepost 80214c7c T 313. aio_fsync           801c5ed0 T 314. aio_return          801c60a8 T 315. aio_suspend         801c6330 T 316. aio_cancel          801c5a48 T 317. aio_error           801c5e24 T 318. aio_read            801c6088 T 319. aio_write           801c6544 T 320. lio_listio          801c6564 T 322. iopolicysys         801de420 T 323. process_policy      8021a72c T 324. mlockall            801d88b4 T 325. munlockall          801d88b8 T 327. issetugid           801dc4b0 T 328. __pthread_kill      801dfa44 T 329. __pthread_sigmask   801dfaa4 T 330. __sigwait           801dfb54 T 331. __disable_threadsignal 801df720 T 332. __pthread_markcancel 801df73c T 333. __pthread_canceled  801df784 T 334. __semwait_signal    801df924 T 336. proc_info           80218618 T 338. stat64              800b25d4 T 339. fstat64             801cd028 T 340. lstat64             800b2720 T 341. stat64_extended     800b2624 T 342. lstat64_extended    800b2770 T 343. fstat64_extended    801cd00c T 344. getdirentries64     800b4340 T 345. statfs64            800b06e0 T 346. fstatfs64           800b0828 T 347. getfsstat64         800b0a38 T 348. __pthread_chdir     800b0d28 T 349. __pthread_fchdir    800b0c58 T 350. audit               801c1a74 T 351. auditon             801c1a78 T 353. getauid             801c1a7c T 354. setauid             801c1a80 T 357. getaudit_addr       801c1a84 T 358. setaudit_addr       801c1a88 T 359. auditctl            801c1a8c T 360. bsdthread_create    80216ab8 T 361. bsdthread_terminate 80216d30 T 362. kqueue              801cf594 T 363. kevent              801cf614 T 364. lchown              800b2d94 T 365. stack_snapshot      801c520c T 366. bsdthread_register  80216d94 T 367. workq_open          802179e8 T 368. workq_kernreturn    80217e50 T 369. kevent64            801cf8ac T 370. __old_semwait_signal 801df7f8 T 371. __old_semwait_signal_nocancel 801df82c T 372. thread_selfid       80218354 T 373. ledger              801ed70c T 380. __mac_execve        801d4468 T 381. __mac_syscall       8027d0a8 T 382. __mac_get_file      8027cd50 T 383. __mac_set_file      8027cf98 T 384. __mac_get_link      8027ce74 T 385. __mac_set_link      8027d098 T 386. __mac_get_proc      8027c844 T 387. __mac_set_proc      8027c904 T 388. __mac_get_fd        8027cbfc T 389. __mac_set_fd        8027ce84 T 390. __mac_get_pid       8027c778 T 391. __mac_get_lcid      8027c9b8 T 392. __mac_get_lctx      8027ca7c T 393. __mac_set_lctx      8027cb38 T 394. setlcid             801dd228 T 395. getlcid             801dd310 T 396. read_nocancel       801eb5a4 T 397. write_nocancel      801eb978 T 398. open_nocancel       800b1434 T 399. close_nocancel      801ccad0 T 400. wait4_nocancel      801d56dc T 401. recvmsg_nocancel    8020a91c T 402. sendmsg_nocancel    8020a464 T 403. recvfrom_nocancel   8020a548 T 404. accept_nocancel     80209b1c T 405. msync_nocancel      801d84e8 T 406. fcntl_nocancel      801cb440 T 407. select_nocancel     801ebfe4 T 408. fsync_nocancel      800b32a8 T 409. connect_nocancel    80209e34 T 410. sigsuspend_nocancel 801df6b4 T 411. readv_nocancel      801eb830 T 412. writev_nocancel     801ebbd0 T 413. sendto_nocancel     8020a188 T 414. pread_nocancel      801eb794 T 415. pwrite_nocancel     801ebaf0 T 416. waitid_nocancel     801d5ad0 T 417. poll_nocancel       801ec74c T 420. sem_wait_nocancel   8020e788 T 421. aio_suspend_nocancel 801c6350 T 422. __sigwait_nocancel  801dfb8c T 423. __semwait_signal_nocancel 801df958 T 424. __mac_mount         800af08c T 425. __mac_get_mount     8027d2a0 T 426. __mac_getfsstat     800b08b0 T 427. fsgetpath           800b5ce4 T 428. audit_session_self  801c1a68 T 429. audit_session_join  801c1a6c T 430. fileport_makeport   801ce2f0 T 431. fileport_makefd     801ce494 T 432. audit_session_port  801c1a70 T 433. pid_suspend         8021c180 T 434. pid_resume          8021c1f0 T 435. pid_hibernate       8021c268 T 436. pid_shutdown_sockets 8021c2c0 T 438. shared_region_map_and_slide_np 8021c954 T 439. kas_info            8021cb50 T   ; Provides ASLR information to user space ; (intentionally crippled in iOS, works in ML) 440. memorystatus_control 801e62a0 T  ;; Controls JetSam - supersedes old sysctl interface 441. guarded_open_np     801cead0 T  442. guarded_close_np    801cebdc 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 joker binary can be used to find the Mach trap table, as well. The following shows iOS 6.0.b1's table:

$ ./joker -ls mach kernel.iPod4.iOS6.0b1 This is an ARM binary. Applying iOS kernel signatures mach_trap_table offset in file (for patching purposes): 3064992 (0x2ec4a0) Kern invalid should be 0x80027ec1. Ignoring those ..This appears to be XNU 2107.1.78 10 _kernelrpc_mach_vm_allocate_trap        80014460 T 12 _kernelrpc_mach_vm_deallocate_trap       800144cc T 14 _kernelrpc_mach_vm_protect_trap          80014510 T 16 _kernelrpc_mach_port_allocate_trap       80014564 T 17 _kernelrpc_mach_port_destroy_trap        800145b4 T 18 _kernelrpc_mach_port_deallocate_trap     800145f0 T 19 _kernelrpc_mach_port_mod_refs_trap       8001462c T 20 _kernelrpc_mach_port_move_member_trap    8001466c T 21 _kernelrpc_mach_port_insert_right_trap   800146b0 T 22 _kernelrpc_mach_port_insert_member_trap  80014710 T 23 _kernelrpc_mach_port_extract_member_trap 80014754 T 26 mach_reply_port                          8001b5b4 T 27 thread_self_trap                         8001b598 T 28 task_self_trap                           8001b578 T 29 host_self_trap                           80019910 T 31 mach_msg_trap                            80014ec0 T 32 mach_msg_overwrite_trap                  80014d20 T 33 semaphore_signal_trap                    80027188 T 34 semaphore_signal_all_trap                8002720c T 35 semaphore_signal_thread_trap             80027114 T 36 semaphore_wait_trap                      800274b0 T 37 semaphore_wait_signal_trap               80027658 T 38 semaphore_timedwait_trap                 80027598 T 39 semaphore_timedwait_signal_trap          8002773c T 44 task_name_for_pid                        8021a838 T 45 task_for_pid                             8021a688 T 46 pid_for_task                             8021a63c T 48 macx_swapon                              8021b414 T 49 macx_swapoff                             8021b668 T 51 macx_triggers                            8021b3f4 T 52 macx_backing_store_suspend               8021b370 T 53 macx_backing_store_recovery              8021b318 T 58 pfz_exit                                 80027818 T 59 swtch_pri                                800278e4 T 60 swtch                                    8002781c T 61 thread_switch                            80027ad4 T 62 clock_sleep_trap                         80017520 T 89 mach_timebase_info_trap                  80016658 T 90 mach_wait_until_trap                     80016d20 T 91 mk_timer_create_trap                     8001f2f4 T 92 mk_timer_destroy_trap                    8001f500 T 93 mk_timer_arm_trap                        8001f544 T 94 mk_timer_cancel_trap                     8001f5c8 T 100 iokit_user_client_trap                   8026c11c T