Kernel Syscalls

From The iPhone Wiki
Revision as of 01:02, 31 August 2012 by Morpheus (talk | contribs) (List of system calls from iOS 6.0b3)
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 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.0b3

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 book online appendix]


$ joker ~/Documents/projects/iOS.6.0b3.iPod4.kernel 
This is an ARM binary. Applying iOS kernel signatures
Syscall names are @2780953
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.2.9
Suppressing enosys (0x800b3429)

1. exit                 801d4974 T
2. fork                 801d786c T
3. read                 801eb408 T
4. write                801eb7dc T
5. open                 800b13a4 T
6. close                801cc9b0 T
7. wait4                801d55a8 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               801dc0f8 T
23. setuid               801dc3ac T
24. getuid               801dc17c T
25. geteuid              801dc18c T
26. ptrace               801e7fb0 T
27. recvmsg              8020a780 T
28. sendmsg              8020a2c8 T
29. recvfrom             8020a3ac T
30. accept               80209c80 T
31. getpeername          8020aa4c T
32. getsockname          8020a99c T
33. access               800b24ac T
34. chflags              800b2928 T
35. fchflags             800b29f0 T
36. sync                 800b0320 T
37. kill                 801dfcb8 T
39. getppid              801dc100 T
41. dup                  801caa00 T
42. pipe                 801eda68 T
43. getegid              801dc204 T
46. sigaction            801dedd4 T
47. getgid               801dc1f4 T
48. sigprocmask          801df318 T
49. getlogin             801dcfd4 T
50. setlogin             801dd04c T
51. acct                 801c53e8 T
52. sigpending           801df4bc T
53. sigaltstack          801dfbfc T
54. ioctl                801ebba0 T
55. reboot               801e7f14 T
56. revoke               800b43f8 T
57. symlink              800b1b58 T
58. readlink             800b282c T
59. execve               801d4348 T
60. umask                800b43d0 T
61. chroot               800b0d30 T
65. msync                801d83bc T
66. vfork                801d6f04 T
73. munmap               801d8468 T
74. mprotect             801d849c T
75. madvise              801d8554 T
78. mincore              801d85c0 T
79. getgroups            801dc214 T
80. setgroups            801dcf18 T
81. getpgrp              801dc108 T
82. setpgid              801dc2b4 T
83. setitimer            801e79fc T
85. swapon               8021bd00 T
86. getitimer            801e78b4 T
89. getdtablesize        801ca5d8 T
90. dup2                 801cae50 T
92. fcntl                801cb31c T
93. select               801ebe4c T
95. fsync                800b3238 T
96. setpriority          801dd380 T
97. socket               80209728 T
98. connect              80209ca0 T
100. getpriority          801dd274 T
104. bind                 802097f4 T
105. setsockopt           8020a8b4 T
106. listen               80209960 T
111. sigsuspend           801df4e4 T
116. gettimeofday         801e76c4 T
117. getrusage            801de118 T
118. getsockopt           8020a918 T
120. readv                801eb694 T
121. writev               801eba34 T
122. settimeofday         801e7720 T
123. fchown               800b2dac T
124. fchmod               800b2c70 T
126. setreuid             801dc6f8 T
127. setregid             801dca8c T
128. rename               800b3428 T
131. flock                801ce108 T
132. mkfifo               800b1798 T
133. sendto               80209fec T
134. shutdown             8020a884 T
135. socketpair           80209e90 T
136. mkdir                800b3d1c T
137. rmdir                800b3d5c T
138. utimes               800b2e60 T
139. futimes              800b3034 T
140. adjtime              801e7824 T
142. gethostuuid          801ed528 T
147. setsid               801dc270 T
151. getpgid              801dc110 T
152. setprivexec          801dc0e0 T
153. pread                801eb5f8 T
154. pwrite               801eb954 T
157. statfs               800b03c0 T
158. fstatfs              800b0678 T
159. unmount              800afe88 T
165. quotactl             800b03bc T
167. mount                800af068 T
169. csops                801daebc T
170. 170  old table       801db3a8 T
173. waitid               801d59a0 T
180. kdebug_trace         801c2cb0 T
181. setgid               801dc890 T
182. setegid              801dc99c T
183. seteuid              801dc5fc T
184. sigreturn            8021e67c T
185. chud                 8021d38c T
187. fdatasync            800b32b0 T
188. stat                 800b2588 T
189. fstat                801ccee8 T
190. lstat                800b26d4 T
191. pathconf             800b27c8 T
192. fpathconf            801ccf44 T
194. getrlimit            801ddf60 T
195. setrlimit            801dd828 T
196. getdirentries        800b3f94 T
197. mmap                 801d7eac T
199. lseek                800b2068 T
200. truncate             800b30b4 T
201. ftruncate            800b3174 T
202. __sysctl             801e2364 T
203. mlock                801d870c T
204. munlock              801d8764 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                 801ec5b0 T
231. watchevent           801eced8 T
232. waitevent            801ed07c T
233. modwatch             801ed1ec 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           801dcd94 T
244. posix_spawn          801d341c T
245. ffsctl               800b5474 T
250. minherit             801d851c T
266. shm_open             8020e9a8 T
267. shm_unlink           8020f488 T
268. sem_open             8020de04 T
269. sem_close            8020e59c T
270. sem_unlink           8020e364 T
271. sem_wait             8020e5f0 T
272. sem_trywait          8020e6b8 T
273. sem_post             8020e75c T
274. sem_getvalue         8020e800 T
275. sem_init             8020e7f8 T
276. sem_destroy          8020e7fc T
277. open_extended        800b11d8 T
278. umask_extended       800b4380 T
279. stat_extended        800b2530 T
280. lstat_extended       800b267c T
281. fstat_extended       801ccccc T
282. chmod_extended       800b2a30 T
283. fchmod_extended      800b2b74 T
284. access_extended      800b21a0 T
285. settid               801dcc18 T
286. gettid               801dc19c T
287. setsgroups           801dcf28 T
288. getsgroups           801dc268 T
289. setwgroups           801dcf2c T
290. getwgroups           801dc26c T
291. mkfifo_extended      800b16f4 T
292. mkdir_extended       800b3b30 T
294. shared_region_check_np 8021c23c T
296. vm_pressure_monitor  8021c9a0 T
297. psynch_rw_longrdlock 80215844 T
298. psynch_rw_yieldwrlock 80215af0 T
299. psynch_rw_downgrade  80215af8 T
300. psynch_rw_upgrade    80215af4 T
301. psynch_mutexwait     80212a5c T
302. psynch_mutexdrop     80213a20 T
303. psynch_cvbroad       80213a74 T
304. psynch_cvsignal      80214058 T
305. psynch_cvwait        802144e0 T
306. psynch_rw_rdlock     80214c18 T
307. psynch_rw_wrlock     80215848 T
308. psynch_rw_unlock     80215afc T
309. psynch_rw_unlock2    80215df4 T
310. getsid               801dc140 T
311. settid_with_pid      801dccb8 T
312. psynch_cvclrprepost  80214b18 T
313. aio_fsync            801c5dcc T
314. aio_return           801c5fa4 T
315. aio_suspend          801c622c T
316. aio_cancel           801c5944 T
317. aio_error            801c5d20 T
318. aio_read             801c5f84 T
319. aio_write            801c6440 T
320. lio_listio           801c6460 T
322. iopolicysys          801de30c T
323. 323                  8021a5c4 T
324. mlockall             801d87a0 T
325. munlockall           801d87a4 T
327. issetugid            801dc39c T
328. __pthread_kill       801df930 T
329. __pthread_sigmask    801df990 T
330. __sigwait            801dfa40 T
331. __disable_threadsignal 801df60c T
332. __pthread_markcancel 801df628 T
333. __pthread_canceled   801df670 T
334. __semwait_signal     801df810 T
336. proc_info            802184a8 T
338. stat64               800b25d4 T
339. fstat64              801ccf24 T
340. lstat64              800b2720 T
341. stat64_extended      800b2624 T
342. lstat64_extended     800b2770 T
343. fstat64_extended     801ccf08 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                801c1970 T
351. auditon              801c1974 T
353. getauid              801c1978 T
354. setauid              801c197c T
357. getaudit_addr        801c1980 T
358. setaudit_addr        801c1984 T
359. auditctl             801c1988 T
360. bsdthread_create     80216948 T
361. bsdthread_terminate  80216bc0 T
362. kqueue               801cf494 T
363. kevent               801cf514 T
364. lchown               800b2d94 T
365. stack_snapshot       801c5108 T
366. bsdthread_register   80216c24 T
367. workq_open           80217878 T
368. workq_kernreturn     80217ce0 T
369. kevent64             801cf7ac T
370. __old_semwait_signal 801df6e4 T
371. __old_semwait_signal_nocancel 801df718 T
372. thread_selfid        802181e4 T
373. ledger               801ed590 T
380. __mac_execve         801d4368 T
381. __mac_syscall        8027d008 T
382. __mac_get_file       8027ccb0 T
383. __mac_set_file       8027cef8 T
384. __mac_get_link       8027cdd4 T
385. __mac_set_link       8027cff8 T
386. __mac_get_proc       8027c7a4 T
387. __mac_set_proc       8027c864 T
388. __mac_get_fd         8027cb5c T
389. __mac_set_fd         8027cde4 T
390. __mac_get_pid        8027c6d8 T
391. __mac_get_lcid       8027c918 T
392. __mac_get_lctx       8027c9dc T
393. __mac_set_lctx       8027ca98 T
394. setlcid              801dd114 T
395. getlcid              801dd1fc T
396. read_nocancel        801eb428 T
397. write_nocancel       801eb7fc T
398. open_nocancel        800b1434 T
399. close_nocancel       801cc9cc T
400. wait4_nocancel       801d55c8 T
401. recvmsg_nocancel     8020a7a0 T
402. sendmsg_nocancel     8020a2e8 T
403. recvfrom_nocancel    8020a3cc T
404. accept_nocancel      802099a0 T
405. msync_nocancel       801d83d4 T
406. fcntl_nocancel       801cb33c T
407. select_nocancel      801ebe68 T
408. fsync_nocancel       800b32a8 T
409. connect_nocancel     80209cb8 T
410. sigsuspend_nocancel  801df5a0 T
411. readv_nocancel       801eb6b4 T
412. writev_nocancel      801eba54 T
413. sendto_nocancel      8020a00c T
414. pread_nocancel       801eb618 T
415. pwrite_nocancel      801eb974 T
416. waitid_nocancel      801d59bc T
417. poll_nocancel        801ec5d0 T
420. sem_wait_nocancel    8020e60c T
421. aio_suspend_nocancel 801c624c T
422. __sigwait_nocancel   801dfa78 T
423. __semwait_signal_nocancel 801df844 T
424. __mac_mount          800af08c T
425. __mac_get_mount      8027d200 T
426. __mac_getfsstat      800b08b0 T
427. fsgetpath            800b5ce4 T
428. audit_session_self   801c1964 T
429. audit_session_join   801c1968 T
430. fileport_makeport    801ce1ec T
431. fileport_makefd      801ce390 T
432. audit_session_port   801c196c T
433. pid_suspend          8021c018 T
434. pid_resume           8021c088 T
435. pid_hibernate        8021c100 T
436. pid_shutdown_sockets 8021c158 T
438. shared_region_map_and_slide_np 8021c7ec T
439. kas_info             8021c9e8 T   ; Provides ASLR information to user space 
                                       ; (intentionally crippled in iOS, works in ML)
440. memorystatus_control 801e60f0 T   ; Controls memory status  (JetSam)
441. guarded_open_np      801ce9cc T   ; New in 6b3, maybe b2
442. guarded_close_np     801cead8 T   ; New in 6b3, maybe b2

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