├── LICENSE ├── README.md ├── bins ├── joker.exe └── joker.plw ├── logs └── kernel_2107.7.55.2.2.txt └── src ├── Makefile ├── joker.c ├── joker4ida.c ├── loader.h ├── syscalltbl.c ├── utils.c └── utils.h /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | joker 2 | ===== 3 | 4 | Joker is used to export xnu kernel's syscall symbols. 5 | The original image which running on OSX can be found at "Downloads" of URL: 6 | http://newosxbook.com/ 7 | 8 | This project is just the cloned version for joker, which can works on Windows. 9 | And the IDA plugin is used to free our hand by adding those symbols automatically. 10 | 11 | The code is build on Mingw which IDA SDK 6.6 12 | Relased binarys test on iOS 6.1.6's kernel (aka. xnu-2107.7.55.2.2). 13 | -------------------------------------------------------------------------------- /bins/joker.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryxjtu/joker/9a82cfad2d8a940cacfed8a5ca9e4c83734826de/bins/joker.exe -------------------------------------------------------------------------------- /bins/joker.plw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jerryxjtu/joker/9a82cfad2d8a940cacfed8a5ca9e4c83734826de/bins/joker.plw -------------------------------------------------------------------------------- /logs/kernel_2107.7.55.2.2.txt: -------------------------------------------------------------------------------- 1 | start to process file[./kernel_10b500] 2 | Source Version: 2107.7.55.2.2 3 | mach_trap_table offset in file/memory (for patching purposes) @[0x002ee4a0], addr [0x8032f4a0] 4 | 5 | dump mach_trap_table 6 | Kern invalid should be 80028495. Ignoring those 7 | 10 _kernelrpc_mach_vm_allocate_trap 80014608 T 8 | 12 _kernelrpc_mach_vm_deallocate_trap 80014674 T 9 | 14 _kernelrpc_mach_vm_protect_trap 800146b8 T 10 | 16 _kernelrpc_mach_port_allocate_trap 8001470c T 11 | 17 _kernelrpc_mach_port_destroy_trap 8001475c T 12 | 18 _kernelrpc_mach_port_deallocate_trap 80014798 T 13 | 19 _kernelrpc_mach_port_mod_refs_trap 800147d4 T 14 | 20 _kernelrpc_mach_port_move_member_trap 80014814 T 15 | 21 _kernelrpc_mach_port_insert_right_trap 80014858 T 16 | 22 _kernelrpc_mach_port_insert_member_trap 800148b8 T 17 | 23 _kernelrpc_mach_port_extract_member_trap 800148fc T 18 | 26 mach_reply_port 8001ba90 T 19 | 27 thread_self_trap 8001ba74 T 20 | 28 task_self_trap 8001ba54 T 21 | 29 host_self_trap 80019de0 T 22 | 31 mach_msg_trap 80014f90 T 23 | 32 mach_msg_overwrite_trap 80014e3c T 24 | 33 semaphore_signal_trap 8002775c T 25 | 34 semaphore_signal_all_trap 800277e0 T 26 | 35 semaphore_signal_thread_trap 800276e8 T 27 | 36 semaphore_wait_trap 80027a84 T 28 | 37 semaphore_wait_signal_trap 80027c2c T 29 | 38 semaphore_timedwait_trap 80027b6c T 30 | 39 semaphore_timedwait_signal_trap 80027d10 T 31 | 44 task_name_for_pid 8021d3a8 T 32 | 45 task_for_pid 8021d1f8 T 33 | 46 pid_for_task 8021d1ac T 34 | 48 macx_swapon 8021df90 T 35 | 49 macx_swapoff 8021e1e4 T 36 | 51 macx_triggers 8021df70 T 37 | 52 macx_backing_store_suspend 8021deec T 38 | 53 macx_backing_store_recovery 8021de94 T 39 | 58 pfz_exit 80027dec T 40 | 59 swtch_pri 80027eb8 T 41 | 60 swtch 80027df0 T 42 | 61 thread_switch 800280a8 T 43 | 62 clock_sleep_trap 800179cc T 44 | 89 mach_timebase_info_trap 80016b04 T 45 | 90 mach_wait_until_trap 800171cc T 46 | 91 mk_timer_create_trap 8001fb18 T 47 | 92 mk_timer_destroy_trap 8001fd24 T 48 | 93 mk_timer_arm_trap 8001fd68 T 49 | 94 mk_timer_cancel_trap 8001fdec T 50 | 100 kern_invalid 8026ecc0 T 51 | Sysent offset in file (for patching purposes) @[0x002f10b8], addr [0x803320b8] 52 | ARM Exception Vector is at file offset @[0x4c6000], addr [0x80507000] 53 | 54 | dump posix_syscall_table 55 | Suppressing enosys (0x801ecc71) 56 | 1 exit 801d5c00 T 57 | 2 fork 801d8b0c T 58 | 3 read 801ec89c T 59 | 4 write 801ecc70 T 60 | 5 open 800b23e8 T 61 | 6 close 801cdc40 T 62 | 7 wait4 801d6848 T 63 | 9 link 800b292c T 64 | 10 unlink 800b3034 T 65 | 12 chdir 800b1ca4 T 66 | 13 fchdir 800b1b34 T 67 | 14 mknod 800b2500 T 68 | 15 chmod 800b3b84 T 69 | 16 chown 800b3ce0 T 70 | 18 getfsstat 800b18d0 T 71 | 20 getpid 801dd398 T 72 | 23 setuid 801dd64c T 73 | 24 getuid 801dd41c T 74 | 25 geteuid 801dd42c T 75 | 26 ptrace 801e9444 T 76 | 27 recvmsg 8020bc14 T 77 | 28 sendmsg 8020b75c T 78 | 29 recvfrom 8020b840 T 79 | 30 accept 8020b114 T 80 | 31 getpeername 8020bee0 T 81 | 32 getsockname 8020be30 T 82 | 33 access 800b34f0 T 83 | 34 chflags 800b396c T 84 | 35 fchflags 800b3a34 T 85 | 36 sync 800b1364 T 86 | 37 kill 801e0f58 T 87 | 39 getppid 801dd3a0 T 88 | 41 dup 801cbc90 T 89 | 42 pipe 801eeefc T 90 | 43 getegid 801dd4a4 T 91 | 46 sigaction 801e0074 T 92 | 47 getgid 801dd494 T 93 | 48 sigprocmask 801e05b8 T 94 | 49 getlogin 801de274 T 95 | 50 setlogin 801de2ec T 96 | 51 acct 801c6678 T 97 | 52 sigpending 801e075c T 98 | 53 sigaltstack 801e0e9c T 99 | 54 ioctl 801ed034 T 100 | 55 reboot 801e93a8 T 101 | 56 revoke 800b543c T 102 | 57 symlink 800b2b9c T 103 | 58 readlink 800b3870 T 104 | 59 execve 801d55d4 T 105 | 60 umask 800b5414 T 106 | 61 chroot 800b1d74 T 107 | 65 msync 801d965c T 108 | 66 vfork 801d81a4 T 109 | 73 munmap 801d9708 T 110 | 74 mprotect 801d973c T 111 | 75 madvise 801d97f4 T 112 | 78 mincore 801d9860 T 113 | 79 getgroups 801dd4b4 T 114 | 80 setgroups 801de1b8 T 115 | 81 getpgrp 801dd3a8 T 116 | 82 setpgid 801dd554 T 117 | 83 setitimer 801e8e90 T 118 | 85 swapon 8021d1a8 T 119 | 86 getitimer 801e8d48 T 120 | 89 getdtablesize 801cb868 T 121 | 90 dup2 801cc0e0 T 122 | 92 fcntl 801cc5ac T 123 | 93 select 801ed2e0 T 124 | 95 fsync 800b427c T 125 | 96 setpriority 801de620 T 126 | 97 socket 8020abbc T 127 | 98 connect 8020b134 T 128 | 100 getpriority 801de514 T 129 | 104 bind 8020ac88 T 130 | 105 setsockopt 8020bd48 T 131 | 106 listen 8020adf4 T 132 | 111 sigsuspend 801e0784 T 133 | 116 gettimeofday 801e8b58 T 134 | 117 getrusage 801df3b8 T 135 | 118 getsockopt 8020bdac T 136 | 120 readv 801ecb28 T 137 | 121 writev 801ecec8 T 138 | 122 settimeofday 801e8bb4 T 139 | 123 fchown 800b3df0 T 140 | 124 fchmod 800b3cb4 T 141 | 126 setreuid 801dd998 T 142 | 127 setregid 801ddd2c T 143 | 128 rename 800b446c T 144 | 131 flock 801cf398 T 145 | 132 mkfifo 800b27dc T 146 | 133 sendto 8020b480 T 147 | 134 shutdown 8020bd18 T 148 | 135 socketpair 8020b324 T 149 | 136 mkdir 800b4d60 T 150 | 137 rmdir 800b4da0 T 151 | 138 utimes 800b3ea4 T 152 | 139 futimes 800b4078 T 153 | 140 adjtime 801e8cb8 T 154 | 142 gethostuuid 801ee9bc T 155 | 147 setsid 801dd510 T 156 | 151 getpgid 801dd3b0 T 157 | 152 setprivexec 801dd380 T 158 | 153 pread 801eca8c T 159 | 154 pwrite 801ecde8 T 160 | 157 statfs 800b1404 T 161 | 158 fstatfs 800b16bc T 162 | 159 unmount 800b0ecc T 163 | 165 quotactl 800b1400 T 164 | 167 mount 800b00ac T 165 | 169 csops 801dc15c T 166 | 170 csops_audittoken 801dc648 T 167 | 173 waitid 801d6c40 T 168 | 180 kdebug_trace 801c3f40 T 169 | 181 setgid 801ddb30 T 170 | 182 setegid 801ddc3c T 171 | 183 seteuid 801dd89c T 172 | 184 sigreturn 8021fb24 T 173 | 185 chud 8021e834 T 174 | 187 fdatasync 800b42f4 T 175 | 188 stat 800b35cc T 176 | 189 fstat 801ce178 T 177 | 190 lstat 800b3718 T 178 | 191 pathconf 800b380c T 179 | 192 fpathconf 801ce1d4 T 180 | 194 getrlimit 801df200 T 181 | 195 setrlimit 801deac8 T 182 | 196 getdirentries 800b4fd8 T 183 | 197 mmap 801d914c T 184 | 199 lseek 800b30ac T 185 | 200 truncate 800b40f8 T 186 | 201 ftruncate 800b41b8 T 187 | 202 __sysctl 801e3604 T 188 | 203 mlock 801d99ac T 189 | 204 munlock 801d9a04 T 190 | 205 undelete 800b2d34 T 191 | 216 mkcomplex 800b2308 T 192 | 220 getattrlist 8009c0a4 T 193 | 221 setattrlist 8009c11c T 194 | 222 getdirentriesattr 800b5524 T 195 | 223 exchangedata 800b56e0 T 196 | 225 searchfs 800b5920 T 197 | 226 delete 800b3070 T 198 | 227 copyfile 800b4310 T 199 | 228 fgetattrlist 800994cc T 200 | 229 fsetattrlist 8009c824 T 201 | 230 poll 801eda44 T 202 | 231 watchevent 801ee36c T 203 | 232 waitevent 801ee510 T 204 | 233 modwatch 801ee680 T 205 | 234 getxattr 800b6594 T 206 | 235 fgetxattr 800b66d0 T 207 | 236 setxattr 800b67d0 T 208 | 237 fsetxattr 800b68dc T 209 | 238 removexattr 800b69d8 T 210 | 239 fremovexattr 800b6aa0 T 211 | 240 listxattr 800b6b60 T 212 | 241 flistxattr 800b6c44 T 213 | 242 fsctl 800b5e18 T 214 | 243 initgroups 801de034 T 215 | 244 posix_spawn 801d46a8 T 216 | 245 ffsctl 800b64b8 T 217 | 250 minherit 801d97bc T 218 | 266 shm_open 8020fe3c T 219 | 267 shm_unlink 8021091c T 220 | 268 sem_open 8020f298 T 221 | 269 sem_close 8020fa30 T 222 | 270 sem_unlink 8020f7f8 T 223 | 271 sem_wait 8020fa84 T 224 | 272 sem_trywait 8020fb4c T 225 | 273 sem_post 8020fbf0 T 226 | 274 sem_getvalue 8020fc94 T 227 | 275 sem_init 8020fc8c T 228 | 276 sem_destroy 8020fc90 T 229 | 277 open_extended 800b221c T 230 | 278 umask_extended 800b53c4 T 231 | 279 stat_extended 800b3574 T 232 | 280 lstat_extended 800b36c0 T 233 | 281 fstat_extended 801cdf5c T 234 | 282 chmod_extended 800b3a74 T 235 | 283 fchmod_extended 800b3bb8 T 236 | 284 access_extended 800b31e4 T 237 | 285 settid 801ddeb8 T 238 | 286 gettid 801dd43c T 239 | 287 setsgroups 801de1c8 T 240 | 288 getsgroups 801dd508 T 241 | 289 setwgroups 801de1cc T 242 | 290 getwgroups 801dd50c T 243 | 291 mkfifo_extended 800b2738 T 244 | 292 mkdir_extended 800b4b74 T 245 | 294 shared_region_check_np 8021d6e4 T 246 | 296 vm_pressure_monitor 8021de48 T 247 | 297 psynch_rw_longrdlock 80216cc4 T 248 | 298 psynch_rw_yieldwrlock 80216f78 T 249 | 299 psynch_rw_downgrade 80216f80 T 250 | 300 psynch_rw_upgrade 80216f7c T 251 | 301 psynch_mutexwait 80213ef0 T 252 | 302 psynch_mutexdrop 80214eb4 T 253 | 303 psynch_cvbroad 80214f08 T 254 | 304 psynch_cvsignal 802154d8 T 255 | 305 psynch_cvwait 80215960 T 256 | 306 psynch_rw_rdlock 80216094 T 257 | 307 psynch_rw_wrlock 80216cc8 T 258 | 308 psynch_rw_unlock 80216f84 T 259 | 309 psynch_rw_unlock2 8021727c T 260 | 310 getsid 801dd3e0 T 261 | 311 settid_with_pid 801ddf58 T 262 | 312 psynch_cvclrprepost 80215f94 T 263 | 313 aio_fsync 801c705c T 264 | 314 aio_return 801c7234 T 265 | 315 aio_suspend 801c74bc T 266 | 316 aio_cancel 801c6bd4 T 267 | 317 aio_error 801c6fb0 T 268 | 318 aio_read 801c7214 T 269 | 319 aio_write 801c76d0 T 270 | 320 lio_listio 801c76f0 T 271 | 322 iopolicysys 801df5ac T 272 | 323 process_policy 8021ba6c T 273 | 324 mlockall 801d9a40 T 274 | 325 munlockall 801d9a44 T 275 | 327 issetugid 801dd63c T 276 | 328 __pthread_kill 801e0bd0 T 277 | 329 __pthread_sigmask 801e0c30 T 278 | 330 __sigwait 801e0ce0 T 279 | 331 __disable_threadsignal 801e08ac T 280 | 332 __pthread_markcancel 801e08c8 T 281 | 333 __pthread_canceled 801e0910 T 282 | 334 __semwait_signal 801e0ab0 T 283 | 336 proc_info 80219930 T 284 | 338 stat64 800b3618 T 285 | 339 fstat64 801ce1b4 T 286 | 340 lstat64 800b3764 T 287 | 341 stat64_extended 800b3668 T 288 | 342 lstat64_extended 800b37b4 T 289 | 343 fstat64_extended 801ce198 T 290 | 344 getdirentries64 800b5384 T 291 | 345 statfs64 800b1724 T 292 | 346 fstatfs64 800b186c T 293 | 347 getfsstat64 800b1a7c T 294 | 348 __pthread_chdir 800b1d6c T 295 | 349 __pthread_fchdir 800b1c9c T 296 | 350 audit 801c2c00 T 297 | 351 auditon 801c2c04 T 298 | 353 getauid 801c2c08 T 299 | 354 setauid 801c2c0c T 300 | 357 getaudit_addr 801c2c10 T 301 | 358 setaudit_addr 801c2c14 T 302 | 359 auditctl 801c2c18 T 303 | 360 bsdthread_create 80217dd0 T 304 | 361 bsdthread_terminate 80218048 T 305 | 362 kqueue 801d0720 T 306 | 363 kevent 801d07a0 T 307 | 364 lchown 800b3dd8 T 308 | 365 stack_snapshot 801c6398 T 309 | 366 bsdthread_register 802180ac T 310 | 367 workq_open 80218d00 T 311 | 368 workq_kernreturn 80219168 T 312 | 369 kevent64 801d0a38 T 313 | 370 __old_semwait_signal 801e0984 T 314 | 371 __old_semwait_signal_nocancel 801e09b8 T 315 | 372 thread_selfid 8021966c T 316 | 373 ledger 801eea24 T 317 | 380 __mac_execve 801d55f4 T 318 | 381 __mac_syscall 8027e428 T 319 | 382 __mac_get_file 8027e0d0 T 320 | 383 __mac_set_file 8027e318 T 321 | 384 __mac_get_link 8027e1f4 T 322 | 385 __mac_set_link 8027e418 T 323 | 386 __mac_get_proc 8027dbc4 T 324 | 387 __mac_set_proc 8027dc84 T 325 | 388 __mac_get_fd 8027df7c T 326 | 389 __mac_set_fd 8027e204 T 327 | 390 __mac_get_pid 8027daf8 T 328 | 391 __mac_get_lcid 8027dd38 T 329 | 392 __mac_get_lctx 8027ddfc T 330 | 393 __mac_set_lctx 8027deb8 T 331 | 394 setlcid 801de3b4 T 332 | 395 getlcid 801de49c T 333 | 396 read_nocancel 801ec8bc T 334 | 397 write_nocancel 801ecc90 T 335 | 398 open_nocancel 800b2478 T 336 | 399 close_nocancel 801cdc5c T 337 | 400 wait4_nocancel 801d6868 T 338 | 401 recvmsg_nocancel 8020bc34 T 339 | 402 sendmsg_nocancel 8020b77c T 340 | 403 recvfrom_nocancel 8020b860 T 341 | 404 accept_nocancel 8020ae34 T 342 | 405 msync_nocancel 801d9674 T 343 | 406 fcntl_nocancel 801cc5cc T 344 | 407 select_nocancel 801ed2fc T 345 | 408 fsync_nocancel 800b42ec T 346 | 409 connect_nocancel 8020b14c T 347 | 410 sigsuspend_nocancel 801e0840 T 348 | 411 readv_nocancel 801ecb48 T 349 | 412 writev_nocancel 801ecee8 T 350 | 413 sendto_nocancel 8020b4a0 T 351 | 414 pread_nocancel 801ecaac T 352 | 415 pwrite_nocancel 801ece08 T 353 | 416 waitid_nocancel 801d6c5c T 354 | 417 poll_nocancel 801eda64 T 355 | 420 sem_wait_nocancel 8020faa0 T 356 | 421 aio_suspend_nocancel 801c74dc T 357 | 422 __sigwait_nocancel 801e0d18 T 358 | 423 __semwait_signal_nocancel 801e0ae4 T 359 | 424 __mac_mount 800b00d0 T 360 | 425 __mac_get_mount 8027e620 T 361 | 426 __mac_getfsstat 800b18f4 T 362 | 427 fsgetpath 800b6d28 T 363 | 428 audit_session_self 801c2bf4 T 364 | 429 audit_session_join 801c2bf8 T 365 | 430 fileport_makeport 801cf47c T 366 | 431 fileport_makefd 801cf620 T 367 | 432 audit_session_port 801c2bfc T 368 | 433 pid_suspend 8021d4c0 T 369 | 434 pid_resume 8021d530 T 370 | 435 pid_hibernate 8021d5a8 T 371 | 436 pid_shutdown_sockets 8021d600 T 372 | 438 shared_region_map_and_slide_np 8021dc94 T 373 | 439 kas_info 8021de90 T 374 | 440 memorystatus_control 801e75b8 T 375 | 441 guarded_open_np 801cfc5c T 376 | 442 guarded_close_np 801cfd68 T 377 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | 2 | IDASDK = /d/idasdk66 3 | IDATARGET=joker.plw 4 | OBJS = joker4ida.o 5 | CC = g++ 6 | INC = -I$(IDASDK)/include 7 | 8 | # The suggest CFLGAS should be : 9 | # -DWIN32 -D__NT__ -D__IDP__ -mrtd 10 | # but mrtd will cause link failed (get_segm_by_name for example) on IDASDK6.6 11 | # g++ use CFLAGS used for *.c file extension, and CXXFLAGS for *.cpp 12 | CFLAGS = -DWIN32 -D__NT__ -D__IDP__ -Wno-write-strings $(INC) 13 | LDFLAGS = --static -Wl,--dll -shared 14 | LIBS = $(IDASDK)/lib/x86_win_gcc_32/ida.a 15 | 16 | all:$(IDATARGET) 17 | 18 | joker: 19 | gcc -Wall utils.c joker.c -o joker 20 | 21 | $(IDATARGET):$(OBJS) 22 | $(CC) -o $@ $(OBJS) $(LIBS) $(LDFLAGS) 23 | 24 | install: 25 | cp -af $(IDATARGET) "/c/Program Files/IDA 6.6/plugins" 26 | 27 | clean: 28 | rm joker.exe $(IDATARGET) *.o -------------------------------------------------------------------------------- /src/joker.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "loader.h" 5 | #include "utils.h" 6 | 7 | #include "syscalltbl.c" 8 | 9 | /* 10 | * hardcode the kernel signatures. 11 | * dirty hack. 12 | */ 13 | #define ARMExcVector "\x0E\x00\x00\xEA" "\x18\xF0\x9F\xE5" "\x18\xF0\x9F\xE5" 14 | #define SIG1 "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x01\x00\x00\x00" "\x00\x00\x00\x00" "\x01\x00\x00\x00" 15 | #define SIG1_SUF "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x04\x00\x00\x00" 16 | #define SIG1_2423_ONWARDS "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x01\x00\x00\x00" "\x00\x00\x00\x00" 17 | #define SIG2_2423_ONWARDS "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x01\x00\x04\x00" 18 | 19 | void *sysent = NULL; 20 | void *mach = NULL; 21 | int ios7 = 0; 22 | 23 | void dumpMachTraps(char *mach) 24 | { 25 | int i; 26 | printf("\ndump mach_trap_table\n"); 27 | if (mach) 28 | printf("Kern invalid should be %08x. Ignoring those\n", *((int *) &mach[4])); 29 | for (i = 0; i < 128; i++){ 30 | int thumb = 0; 31 | int addr = * ((int *) (mach + 4 + 8*i)); 32 | if (addr == *((int *) (mach + 4))) continue; 33 | if ((addr % 4) == 1) {addr--; thumb++;} 34 | if ((addr % 4) == -3) {addr--; thumb++;} 35 | if (addr % 4) {thumb = '?';} 36 | printf("%3d %-40s %x %s\n", i, mach_syscall_name_table[i], addr, (thumb? "T": "-")); 37 | } 38 | } 39 | 40 | void dumpPosixSyscall(void) 41 | { 42 | int i; 43 | printf("\ndump posix_syscall_table\n"); 44 | printf ("Suppressing enosys (0x%08x)\n", *(int *)(sysent + 20 + 24*4)); 45 | for (i = 0; i< (ios7 ? SYS_MAXSYSCALL_7 : SYS_MAXSYSCALL); i++){ 46 | int suppress = 0; 47 | int thumb = 0; 48 | int jump = (ios7? 20 : 24); 49 | int addr = * ((int *) (sysent + 20 + jump*i)); 50 | if (addr == *((int *)(sysent + 20 + jump * 8))) 51 | suppress =1; 52 | if ((addr % 4) == 1) { addr--; thumb++; } 53 | if ((addr % 4) == -3) { addr--; thumb++; } 54 | if (!suppress) 55 | printf ("%3d %-40s %x %s\n", i,syscall_names[i], addr, (thumb? "T": "-")); 56 | } 57 | } 58 | 59 | int main(int argc, char *argv[]) 60 | { 61 | u8 *buf; 62 | int filesize, i; 63 | uint32_t magic; 64 | 65 | struct mach_header *phdr; 66 | struct load_command *ploadcmd; 67 | struct source_version_command *svc; 68 | 69 | if(argc < 2){ 70 | printf("useage: %s [mach-o file]\n", argv[0]); 71 | return -1; 72 | } 73 | buf = load_file(argv[1], &filesize); 74 | magic = *(u32 *)(buf); 75 | 76 | if((magic == FAT_MAGIC) || (magic == FAT_CIGAM)){ 77 | printf("Erro: fat image is not support.\n"); 78 | free(buf); 79 | return -1; 80 | } 81 | phdr = (struct mach_header *)buf; 82 | if((MH_MAGIC !=phdr->magic) || (CPU_TYPE_ARM != phdr->cputype)){ 83 | printf("Erro: not vaild arm mach-o file.\n"); 84 | free(buf); 85 | return -1; 86 | } 87 | printf("start to process file[%s]\n", argv[1]); 88 | ploadcmd = (struct load_command *)(buf+sizeof(struct mach_header)); 89 | for(i=0; incmds; i++, ploadcmd =(struct load_command *)((u8 *)ploadcmd+ploadcmd->cmdsize)){ 90 | if(LC_SOURCE_VERSION == ploadcmd->cmd){ 91 | svc = (struct source_version_command *)ploadcmd; 92 | printf("%-25s%ld.%d.%d.%d.%d\n", "Source Version:", (long) ((svc->version) >> 40), 93 | (int) (svc->version >> 30) & 0x000003FF, 94 | (int) (svc->version >> 20) & 0x000003FF, 95 | (int) (svc->version >> 10) & 0x000003FF, 96 | (int) (svc->version) & 0x000003FF); 97 | if (svc && (svc->version >> 40) >= 2423){ 98 | printf("This is iOS 7.x, or later\n"); 99 | ios7 = 1; 100 | } 101 | break; 102 | } 103 | } 104 | 105 | for(i = 0; i < filesize-50; i++){ 106 | if (memcmp(buf+i, ARMExcVector, 12) == 0){ 107 | printf("ARM Exception Vector is at file offset @[0x%x], addr [0x%x]\n", i, 0x80041000+i); 108 | } 109 | if (memcmp(buf+i, SIG1, 20) == 0){ 110 | if (memcmp(buf+i+24, SIG1_SUF, 16) == 0){ 111 | printf ("Sysent offset in file (for patching purposes) @[0x%08x], addr [0x%08x]\n",i-8, 0x80041000+(i -8)); 112 | sysent = buf + i - 24; 113 | } 114 | } 115 | if ((memcmp(buf+i, SIG1_2423_ONWARDS, 16) == 0) && 116 | (memcmp(buf+i, SIG2_2423_ONWARDS, 16) ==0) && 117 | (memcmp(buf+i, SIG1_2423_ONWARDS, 16) ==0)){ 118 | printf ("Sysent offset in file (for patching purposes) @[0x%08x], addr [0x%08x]\n",i-8,0x80041000+(i -8)); 119 | sysent = buf + i - 24 ; 120 | } 121 | if (! mach && (memcmp(buf+i, buf+i+40, 40) == 0) && (memcmp(buf+i, buf+i+32, 32) == 0) && 122 | (memcmp(buf+i, buf+i+24, 24 ) == 0) && (memcmp(buf+i, buf+i+16, 16) == 0) && 123 | (memcmp(buf+i, buf+i+24, 24) == 0) && (memcmp(buf+i, buf+i+8, 8) == 0) && 124 | ( (!*((int *)(buf+i))) && *((int *)(buf+i+4)))){ 125 | printf("mach_trap_table offset in file/memory (for patching purposes) @[0x%08x], addr [0x%08x]\n", i, 0x80041000+i); 126 | mach = buf+i; 127 | dumpMachTraps(mach); 128 | } 129 | } 130 | if(sysent){ 131 | dumpPosixSyscall(); 132 | } 133 | free(buf); 134 | return 0; 135 | } 136 | 137 | -------------------------------------------------------------------------------- /src/joker4ida.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | //#include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "loader.h" 11 | #include "syscalltbl.c" 12 | 13 | /* 14 | * hardcode the kernel signatures. 15 | * dirty hack. 16 | */ 17 | #define ARMExcVector "\x0E\x00\x00\xEA" "\x18\xF0\x9F\xE5" "\x18\xF0\x9F\xE5" 18 | #define SIG1 "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x01\x00\x00\x00" "\x00\x00\x00\x00" "\x01\x00\x00\x00" 19 | #define SIG1_SUF "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x04\x00\x00\x00" 20 | #define SIG1_2423_ONWARDS "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x01\x00\x00\x00" "\x00\x00\x00\x00" 21 | #define SIG2_2423_ONWARDS "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x00\x00\x00\x00" "\x01\x00\x04\x00" 22 | 23 | static const char comment[] = "Find out syscalls from xnu kernel (arm only)"; 24 | void *sysent = NULL; 25 | unsigned char *mach = NULL; 26 | int ios7 = 0; 27 | 28 | static void dumpMachTraps(unsigned char *mach) 29 | { 30 | int i; 31 | msg("\ndump mach_trap_table\n"); 32 | if (mach){ 33 | msg("Kern invalid should be %08x. Ignoring those\n", *((int *) &mach[4])); 34 | set_name((ea_t)(*((int *) &mach[4])), "kern_invalid", SN_NOWARN); 35 | } 36 | for (i = 0; i < 128; i++){ 37 | int thumb = 0; 38 | int addr = * ((int *) (mach + 4 + 8*i)); 39 | if (addr == *((int *) (mach + 4))) continue; 40 | if ((addr % 4) == 1) {addr--; thumb++;} 41 | if ((addr % 4) == -3) {addr--; thumb++;} 42 | if (addr % 4) {thumb = '?';} 43 | msg("%3d %-40s %x %s\n", i, mach_syscall_name_table[i], addr, (thumb? "T": "-")); 44 | set_name((ea_t)addr, mach_syscall_name_table[i], SN_NOWARN); 45 | } 46 | } 47 | 48 | static void dumpPosixSyscall(void) 49 | { 50 | int i; 51 | msg("\ndump posix_syscall_table\n"); 52 | msg("Suppressing enosys (0x%08x)\n", *(int *)((char *)sysent + 20 + 24*4)); 53 | for (i = 0; i< (ios7 ? SYS_MAXSYSCALL_7 : SYS_MAXSYSCALL); i++){ 54 | int suppress = 0; 55 | int thumb = 0; 56 | int jump = (ios7? 20 : 24); 57 | int addr = * ((int *) ((char *)sysent + 20 + jump*i)); 58 | if (addr == *((int *)((char *)sysent + 20 + jump * 8))) 59 | suppress =1; 60 | if ((addr % 4) == 1) { addr--; thumb++; } 61 | if ((addr % 4) == -3) { addr--; thumb++; } 62 | if (!suppress){ 63 | msg("%3d %-40s %x %s\n", i, syscall_names[i], addr, (thumb? "T": "-")); 64 | set_name((ea_t)addr, syscall_names[i], SN_NOWARN); 65 | } 66 | } 67 | } 68 | 69 | int idaapi joker_init(void) 70 | { 71 | if(ph.id != PLFM_ARM) 72 | return PLUGIN_SKIP; 73 | if(inf.filetype != f_MACHO) 74 | return PLUGIN_SKIP; 75 | return PLUGIN_OK; 76 | } 77 | 78 | void idaapi joker_run(int) 79 | { 80 | struct mach_header *phdr; 81 | struct load_command *ploadcmd; 82 | struct source_version_command *svc; 83 | unsigned char *buf; 84 | int i, filesize; 85 | char *kernelfile; 86 | linput_t *li; 87 | 88 | msg("Joker start to run...\n"); 89 | #if 0 90 | segment_t *s; 91 | unsigned char *hdr; 92 | s = get_segm_by_name("HEADER"); 93 | msg("Find header at [%08x] ~ [%08x]\n", s->startEA, s->endEA); 94 | hdr = (unsigned char *)qalloc(s->endEA - s->startEA); 95 | get_many_bytes(s->startEA, hdr, s->endEA - s->startEA); 96 | 97 | phdr = (struct mach_header *)hdr; 98 | ploadcmd = (struct load_command *)(hdr+sizeof(struct mach_header)); 99 | for(i=0; incmds; i++, ploadcmd =(struct load_command *)((unsigned char *)ploadcmd+ploadcmd->cmdsize)){ 100 | if(LC_SOURCE_VERSION == ploadcmd->cmd){ 101 | svc = (struct source_version_command *)ploadcmd; 102 | msg("%-25s%ld.%d.%d.%d.%d\n", "Source Version:", (long) ((svc->version) >> 40), 103 | (int) (svc->version >> 30) & 0x000003FF, 104 | (int) (svc->version >> 20) & 0x000003FF, 105 | (int) (svc->version >> 10) & 0x000003FF, 106 | (int) (svc->version) & 0x000003FF); 107 | if (svc && (svc->version >> 40) >= 2423){ 108 | msg("This is iOS 7.x, or later\n"); 109 | ios7 = 1; 110 | } 111 | break; 112 | } 113 | } 114 | free(hdr); 115 | #endif 116 | kernelfile = askfile_c(0, NULL, "Select orgi kernel mach-o file"); 117 | if ( kernelfile == NULL){ 118 | msg("Quit as NO file selected\n"); 119 | return; 120 | } 121 | li = open_linput(kernelfile, false); 122 | if ( li == NULL ){ 123 | msg("Open kernel file failed\n"); 124 | return; 125 | } 126 | filesize = qlsize(li); 127 | buf = (unsigned char *)qalloc(filesize); 128 | qlread(li, buf, filesize); 129 | close_linput(li); 130 | 131 | phdr = (struct mach_header *)buf; 132 | ploadcmd = (struct load_command *)(buf+sizeof(struct mach_header)); 133 | for(i=0; incmds; i++, ploadcmd =(struct load_command *)((unsigned char *)ploadcmd+ploadcmd->cmdsize)){ 134 | if(LC_SOURCE_VERSION == ploadcmd->cmd){ 135 | svc = (struct source_version_command *)ploadcmd; 136 | msg("%-25s%ld.%d.%d.%d.%d\n", "Source Version:", (long) ((svc->version) >> 40), 137 | (int) (svc->version >> 30) & 0x000003FF, 138 | (int) (svc->version >> 20) & 0x000003FF, 139 | (int) (svc->version >> 10) & 0x000003FF, 140 | (int) (svc->version) & 0x000003FF); 141 | if (svc && (svc->version >> 40) >= 2423){ 142 | msg("This is iOS 7.x, or later\n"); 143 | ios7 = 1; 144 | } 145 | break; 146 | } 147 | } 148 | for(i = 0; i < filesize-50; i++){ 149 | if (memcmp(buf+i, ARMExcVector, 12) == 0){ 150 | msg("ARM Exception Vector is at file offset @[0x%x], addr [0x%x]\n", i, 0x80041000+i); 151 | set_name((ea_t)(0x80041000+i), "_Exception_Vector", SN_NOWARN); 152 | } 153 | if (memcmp(buf+i, SIG1, 20) == 0){ 154 | if (memcmp(buf+i+24, SIG1_SUF, 16) == 0){ 155 | msg("Sysent offset in file (for patching purposes) @[0x%08x], addr [0x%08x]\n",i-8, 0x80041000+(i -8)); 156 | sysent = buf + i - 24; 157 | } 158 | } 159 | if ((memcmp(buf+i, SIG1_2423_ONWARDS, 16) == 0) && 160 | (memcmp(buf+i, SIG2_2423_ONWARDS, 16) ==0) && 161 | (memcmp(buf+i, SIG1_2423_ONWARDS, 16) ==0)){ 162 | msg("Sysent offset in file (for patching purposes) @[0x%08x], addr [0x%08x]\n",i-8,0x80041000+(i -8)); 163 | sysent = buf + i - 24 ; 164 | } 165 | if (! mach && (memcmp(buf+i, buf+i+40, 40) == 0) && (memcmp(buf+i, buf+i+32, 32) == 0) && 166 | (memcmp(buf+i, buf+i+24, 24 ) == 0) && (memcmp(buf+i, buf+i+16, 16) == 0) && 167 | (memcmp(buf+i, buf+i+24, 24) == 0) && (memcmp(buf+i, buf+i+8, 8) == 0) && 168 | ( (!*((int *)(buf+i))) && *((int *)(buf+i+4)))){ 169 | msg("mach_trap_table offset in file/memory (for patching purposes) @[0x%08x], addr [0x%08x]\n", i, 0x80041000+i); 170 | mach = buf+i; 171 | dumpMachTraps(mach); 172 | } 173 | } 174 | if(sysent){ 175 | dumpPosixSyscall(); 176 | } 177 | qfree(buf); 178 | return; 179 | } 180 | 181 | plugin_t PLUGIN = 182 | { 183 | IDP_INTERFACE_VERSION, 184 | PLUGIN_UNL, // plugin flags 185 | joker_init, // initialize 186 | NULL, // terminate. this pointer may be NULL. 187 | joker_run, // invoke plugin 188 | comment, // long comment about the plugin 189 | NULL, // multiline help about the plugin 190 | "Joker (to export xnu syscall)", // the preferred short name of the plugin 191 | NULL // the preferred hotkey to run the plugin 192 | }; 193 | 194 | -------------------------------------------------------------------------------- /src/loader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2010 Apple Inc. All Rights Reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | #ifndef _MACHO_LOADER_H_ 24 | #define _MACHO_LOADER_H_ 25 | 26 | /* 27 | * This file describes the format of mach object files. 28 | */ 29 | #include 30 | 31 | typedef int integer_t; 32 | typedef integer_t cpu_type_t; 33 | typedef integer_t cpu_subtype_t; 34 | typedef int vm_prot_t; 35 | 36 | /* 37 | * The 32-bit mach header appears at the very beginning of the object file for 38 | * 32-bit architectures. 39 | */ 40 | struct mach_header { 41 | uint32_t magic; /* mach magic number identifier */ 42 | cpu_type_t cputype; /* cpu specifier */ 43 | cpu_subtype_t cpusubtype; /* machine specifier */ 44 | uint32_t filetype; /* type of file */ 45 | uint32_t ncmds; /* number of load commands */ 46 | uint32_t sizeofcmds; /* the size of all the load commands */ 47 | uint32_t flags; /* flags */ 48 | }; 49 | 50 | /* Constant for the magic field of the mach_header (32-bit architectures) */ 51 | #define MH_MAGIC 0xfeedface /* the mach magic number */ 52 | #define MH_CIGAM 0xcefaedfe /* NXSwapInt(MH_MAGIC) */ 53 | #define FAT_MAGIC 0xcafebabe 54 | #define FAT_CIGAM 0xbebafeca /* NXSwapLong(FAT_MAGIC) */ 55 | 56 | /* 57 | * The 64-bit mach header appears at the very beginning of object files for 58 | * 64-bit architectures. 59 | */ 60 | struct mach_header_64 { 61 | uint32_t magic; /* mach magic number identifier */ 62 | cpu_type_t cputype; /* cpu specifier */ 63 | cpu_subtype_t cpusubtype; /* machine specifier */ 64 | uint32_t filetype; /* type of file */ 65 | uint32_t ncmds; /* number of load commands */ 66 | uint32_t sizeofcmds; /* the size of all the load commands */ 67 | uint32_t flags; /* flags */ 68 | uint32_t reserved; /* reserved */ 69 | }; 70 | 71 | #define CPU_TYPE_ARM ((cpu_type_t) 12) 72 | 73 | /* Constant for the magic field of the mach_header_64 (64-bit architectures) */ 74 | #define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ 75 | #define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */ 76 | 77 | /* 78 | * The layout of the file depends on the filetype. For all but the MH_OBJECT 79 | * file type the segments are padded out and aligned on a segment alignment 80 | * boundary for efficient demand pageing. The MH_EXECUTE, MH_FVMLIB, MH_DYLIB, 81 | * MH_DYLINKER and MH_BUNDLE file types also have the headers included as part 82 | * of their first segment. 83 | * 84 | * The file type MH_OBJECT is a compact format intended as output of the 85 | * assembler and input (and possibly output) of the link editor (the .o 86 | * format). All sections are in one unnamed segment with no segment padding. 87 | * This format is used as an executable format when the file is so small the 88 | * segment padding greatly increases its size. 89 | * 90 | * The file type MH_PRELOAD is an executable format intended for things that 91 | * are not executed under the kernel (proms, stand alones, kernels, etc). The 92 | * format can be executed under the kernel but may demand paged it and not 93 | * preload it before execution. 94 | * 95 | * A core file is in MH_CORE format and can be any in an arbritray legal 96 | * Mach-O file. 97 | * 98 | * Constants for the filetype field of the mach_header 99 | */ 100 | #define MH_OBJECT 0x1 /* relocatable object file */ 101 | #define MH_EXECUTE 0x2 /* demand paged executable file */ 102 | #define MH_FVMLIB 0x3 /* fixed VM shared library file */ 103 | #define MH_CORE 0x4 /* core file */ 104 | #define MH_PRELOAD 0x5 /* preloaded executable file */ 105 | #define MH_DYLIB 0x6 /* dynamically bound shared library */ 106 | #define MH_DYLINKER 0x7 /* dynamic link editor */ 107 | #define MH_BUNDLE 0x8 /* dynamically bound bundle file */ 108 | #define MH_DYLIB_STUB 0x9 /* shared library stub for static */ 109 | /* linking only, no section contents */ 110 | #define MH_DSYM 0xa /* companion file with only debug */ 111 | /* sections */ 112 | #define MH_KEXT_BUNDLE 0xb /* x86_64 kexts */ 113 | 114 | /* Constants for the flags field of the mach_header */ 115 | #define MH_NOUNDEFS 0x1 /* the object file has no undefined 116 | references */ 117 | #define MH_INCRLINK 0x2 /* the object file is the output of an 118 | incremental link against a base file 119 | and can't be link edited again */ 120 | #define MH_DYLDLINK 0x4 /* the object file is input for the 121 | dynamic linker and can't be staticly 122 | link edited again */ 123 | #define MH_BINDATLOAD 0x8 /* the object file's undefined 124 | references are bound by the dynamic 125 | linker when loaded. */ 126 | #define MH_PREBOUND 0x10 /* the file has its dynamic undefined 127 | references prebound. */ 128 | #define MH_SPLIT_SEGS 0x20 /* the file has its read-only and 129 | read-write segments split */ 130 | #define MH_LAZY_INIT 0x40 /* the shared library init routine is 131 | to be run lazily via catching memory 132 | faults to its writeable segments 133 | (obsolete) */ 134 | #define MH_TWOLEVEL 0x80 /* the image is using two-level name 135 | space bindings */ 136 | #define MH_FORCE_FLAT 0x100 /* the executable is forcing all images 137 | to use flat name space bindings */ 138 | #define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees no multiple 139 | defintions of symbols in its 140 | sub-images so the two-level namespace 141 | hints can always be used. */ 142 | #define MH_NOFIXPREBINDING 0x400 /* do not have dyld notify the 143 | prebinding agent about this 144 | executable */ 145 | #define MH_PREBINDABLE 0x800 /* the binary is not prebound but can 146 | have its prebinding redone. only used 147 | when MH_PREBOUND is not set. */ 148 | #define MH_ALLMODSBOUND 0x1000 /* indicates that this binary binds to 149 | all two-level namespace modules of 150 | its dependent libraries. only used 151 | when MH_PREBINDABLE and MH_TWOLEVEL 152 | are both set. */ 153 | #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000/* safe to divide up the sections into 154 | sub-sections via symbols for dead 155 | code stripping */ 156 | #define MH_CANONICAL 0x4000 /* the binary has been canonicalized 157 | via the unprebind operation */ 158 | #define MH_WEAK_DEFINES 0x8000 /* the final linked image contains 159 | external weak symbols */ 160 | #define MH_BINDS_TO_WEAK 0x10000 /* the final linked image uses 161 | weak symbols */ 162 | 163 | #define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks 164 | in the task will be given stack 165 | execution privilege. Only used in 166 | MH_EXECUTE filetypes. */ 167 | #define MH_ROOT_SAFE 0x40000 /* When this bit is set, the binary 168 | declares it is safe for use in 169 | processes with uid zero */ 170 | 171 | #define MH_SETUID_SAFE 0x80000 /* When this bit is set, the binary 172 | declares it is safe for use in 173 | processes when issetugid() is true */ 174 | 175 | #define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib, 176 | the static linker does not need to 177 | examine dependent dylibs to see 178 | if any are re-exported */ 179 | #define MH_PIE 0x200000 /* When this bit is set, the OS will 180 | load the main executable at a 181 | random address. Only used in 182 | MH_EXECUTE filetypes. */ 183 | #define MH_DEAD_STRIPPABLE_DYLIB 0x400000 /* Only for use on dylibs. When 184 | linking against a dylib that 185 | has this bit set, the static linker 186 | will automatically not create a 187 | LC_LOAD_DYLIB load command to the 188 | dylib if no symbols are being 189 | referenced from the dylib. */ 190 | #define MH_HAS_TLV_DESCRIPTORS 0x800000 /* Contains a section of type 191 | S_THREAD_LOCAL_VARIABLES */ 192 | 193 | #define MH_NO_HEAP_EXECUTION 0x1000000 /* When this bit is set, the OS will 194 | run the main executable with 195 | a non-executable heap even on 196 | platforms (e.g. i386) that don't 197 | require it. Only used in MH_EXECUTE 198 | filetypes. */ 199 | 200 | /* 201 | * The load commands directly follow the mach_header. The total size of all 202 | * of the commands is given by the sizeofcmds field in the mach_header. All 203 | * load commands must have as their first two fields cmd and cmdsize. The cmd 204 | * field is filled in with a constant for that command type. Each command type 205 | * has a structure specifically for it. The cmdsize field is the size in bytes 206 | * of the particular load command structure plus anything that follows it that 207 | * is a part of the load command (i.e. section structures, strings, etc.). To 208 | * advance to the next load command the cmdsize can be added to the offset or 209 | * pointer of the current load command. The cmdsize for 32-bit architectures 210 | * MUST be a multiple of 4 bytes and for 64-bit architectures MUST be a multiple 211 | * of 8 bytes (these are forever the maximum alignment of any load commands). 212 | * The padded bytes must be zero. All tables in the object file must also 213 | * follow these rules so the file can be memory mapped. Otherwise the pointers 214 | * to these tables will not work well or at all on some machines. With all 215 | * padding zeroed like objects will compare byte for byte. 216 | */ 217 | struct load_command { 218 | uint32_t cmd; /* type of load command */ 219 | uint32_t cmdsize; /* total size of command in bytes */ 220 | }; 221 | 222 | /* 223 | * After MacOS X 10.1 when a new load command is added that is required to be 224 | * understood by the dynamic linker for the image to execute properly the 225 | * LC_REQ_DYLD bit will be or'ed into the load command constant. If the dynamic 226 | * linker sees such a load command it it does not understand will issue a 227 | * "unknown load command required for execution" error and refuse to use the 228 | * image. Other load commands without this bit that are not understood will 229 | * simply be ignored. 230 | */ 231 | #define LC_REQ_DYLD 0x80000000 232 | 233 | /* Constants for the cmd field of all load commands, the type */ 234 | #define LC_SEGMENT 0x1 /* segment of this file to be mapped */ 235 | #define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ 236 | #define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ 237 | #define LC_THREAD 0x4 /* thread */ 238 | #define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ 239 | #define LC_LOADFVMLIB 0x6 /* load a specified fixed VM shared library */ 240 | #define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */ 241 | #define LC_IDENT 0x8 /* object identification info (obsolete) */ 242 | #define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ 243 | #define LC_PREPAGE 0xa /* prepage command (internal use) */ 244 | #define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ 245 | #define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ 246 | #define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ 247 | #define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ 248 | #define LC_ID_DYLINKER 0xf /* dynamic linker identification */ 249 | #define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ 250 | /* linked shared library */ 251 | #define LC_ROUTINES 0x11 /* image routines */ 252 | #define LC_SUB_FRAMEWORK 0x12 /* sub framework */ 253 | #define LC_SUB_UMBRELLA 0x13 /* sub umbrella */ 254 | #define LC_SUB_CLIENT 0x14 /* sub client */ 255 | #define LC_SUB_LIBRARY 0x15 /* sub library */ 256 | #define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ 257 | #define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ 258 | 259 | /* 260 | * load a dynamically linked shared library that is allowed to be missing 261 | * (all symbols are weak imported). 262 | */ 263 | #define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) 264 | 265 | #define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be 266 | mapped */ 267 | #define LC_ROUTINES_64 0x1a /* 64-bit image routines */ 268 | #define LC_UUID 0x1b /* the uuid */ 269 | #define LC_RPATH (0x1c | LC_REQ_DYLD) /* runpath additions */ 270 | #define LC_CODE_SIGNATURE 0x1d /* local of code signature */ 271 | #define LC_SEGMENT_SPLIT_INFO 0x1e /* local of info to split segments */ 272 | #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */ 273 | #define LC_LAZY_LOAD_DYLIB 0x20 /* delay load of dylib until first use */ 274 | #define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */ 275 | #define LC_DYLD_INFO 0x22 /* compressed dyld information */ 276 | #define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) /* compressed dyld information only */ 277 | #define LC_LOAD_UPWARD_DYLIB (0x23 | LC_REQ_DYLD) /* load upward dylib */ 278 | #define LC_VERSION_MIN_MACOSX 0x24 /* build for MacOSX min OS version */ 279 | #define LC_VERSION_MIN_IPHONEOS 0x25 /* build for iPhoneOS min OS version */ 280 | #define LC_FUNCTION_STARTS 0x26 /* compressed table of function start addresses */ 281 | #define LC_DYLD_ENVIRONMENT 0x27 /* string for dyld to treat 282 | like environment variable */ 283 | #define LC_MAIN (0x28|LC_REQ_DYLD) /* replacement for LC_UNIXTHREAD */ 284 | #define LC_DATA_IN_CODE 0x29 /* table of non-instructions in __text */ 285 | #define LC_SOURCE_VERSION 0x2A /* source version used to build binary */ 286 | #define LC_DYLIB_CODE_SIGN_DRS 0x2B /* Code signing DRs copied from linked dylibs */ 287 | #define LC_ENCRYPTION_INFO_64 0x2C /* 64-bit encrypted segment information */ 288 | 289 | 290 | /* 291 | * A variable length string in a load command is represented by an lc_str 292 | * union. The strings are stored just after the load command structure and 293 | * the offset is from the start of the load command structure. The size 294 | * of the string is reflected in the cmdsize field of the load command. 295 | * Once again any padded bytes to bring the cmdsize field to a multiple 296 | * of 4 bytes must be zero. 297 | */ 298 | union lc_str { 299 | uint32_t offset; /* offset to the string */ 300 | #ifndef __LP64__ 301 | char *ptr; /* pointer to the string */ 302 | #endif 303 | }; 304 | 305 | /* 306 | * The segment load command indicates that a part of this file is to be 307 | * mapped into the task's address space. The size of this segment in memory, 308 | * vmsize, maybe equal to or larger than the amount to map from this file, 309 | * filesize. The file is mapped starting at fileoff to the beginning of 310 | * the segment in memory, vmaddr. The rest of the memory of the segment, 311 | * if any, is allocated zero fill on demand. The segment's maximum virtual 312 | * memory protection and initial virtual memory protection are specified 313 | * by the maxprot and initprot fields. If the segment has sections then the 314 | * section structures directly follow the segment command and their size is 315 | * reflected in cmdsize. 316 | */ 317 | struct segment_command { /* for 32-bit architectures */ 318 | uint32_t cmd; /* LC_SEGMENT */ 319 | uint32_t cmdsize; /* includes sizeof section structs */ 320 | char segname[16]; /* segment name */ 321 | uint32_t vmaddr; /* memory address of this segment */ 322 | uint32_t vmsize; /* memory size of this segment */ 323 | uint32_t fileoff; /* file offset of this segment */ 324 | uint32_t filesize; /* amount to map from the file */ 325 | vm_prot_t maxprot; /* maximum VM protection */ 326 | vm_prot_t initprot; /* initial VM protection */ 327 | uint32_t nsects; /* number of sections in segment */ 328 | uint32_t flags; /* flags */ 329 | }; 330 | 331 | /* 332 | * The 64-bit segment load command indicates that a part of this file is to be 333 | * mapped into a 64-bit task's address space. If the 64-bit segment has 334 | * sections then section_64 structures directly follow the 64-bit segment 335 | * command and their size is reflected in cmdsize. 336 | */ 337 | struct segment_command_64 { /* for 64-bit architectures */ 338 | uint32_t cmd; /* LC_SEGMENT_64 */ 339 | uint32_t cmdsize; /* includes sizeof section_64 structs */ 340 | char segname[16]; /* segment name */ 341 | uint64_t vmaddr; /* memory address of this segment */ 342 | uint64_t vmsize; /* memory size of this segment */ 343 | uint64_t fileoff; /* file offset of this segment */ 344 | uint64_t filesize; /* amount to map from the file */ 345 | vm_prot_t maxprot; /* maximum VM protection */ 346 | vm_prot_t initprot; /* initial VM protection */ 347 | uint32_t nsects; /* number of sections in segment */ 348 | uint32_t flags; /* flags */ 349 | }; 350 | 351 | /* Constants for the flags field of the segment_command */ 352 | #define SG_HIGHVM 0x1 /* the file contents for this segment is for 353 | the high part of the VM space, the low part 354 | is zero filled (for stacks in core files) */ 355 | #define SG_FVMLIB 0x2 /* this segment is the VM that is allocated by 356 | a fixed VM library, for overlap checking in 357 | the link editor */ 358 | #define SG_NORELOC 0x4 /* this segment has nothing that was relocated 359 | in it and nothing relocated to it, that is 360 | it maybe safely replaced without relocation*/ 361 | #define SG_PROTECTED_VERSION_1 0x8 /* This segment is protected. If the 362 | segment starts at file offset 0, the 363 | first page of the segment is not 364 | protected. All other pages of the 365 | segment are protected. */ 366 | 367 | /* 368 | * A segment is made up of zero or more sections. Non-MH_OBJECT files have 369 | * all of their segments with the proper sections in each, and padded to the 370 | * specified segment alignment when produced by the link editor. The first 371 | * segment of a MH_EXECUTE and MH_FVMLIB format file contains the mach_header 372 | * and load commands of the object file before its first section. The zero 373 | * fill sections are always last in their segment (in all formats). This 374 | * allows the zeroed segment padding to be mapped into memory where zero fill 375 | * sections might be. The gigabyte zero fill sections, those with the section 376 | * type S_GB_ZEROFILL, can only be in a segment with sections of this type. 377 | * These segments are then placed after all other segments. 378 | * 379 | * The MH_OBJECT format has all of its sections in one segment for 380 | * compactness. There is no padding to a specified segment boundary and the 381 | * mach_header and load commands are not part of the segment. 382 | * 383 | * Sections with the same section name, sectname, going into the same segment, 384 | * segname, are combined by the link editor. The resulting section is aligned 385 | * to the maximum alignment of the combined sections and is the new section's 386 | * alignment. The combined sections are aligned to their original alignment in 387 | * the combined section. Any padded bytes to get the specified alignment are 388 | * zeroed. 389 | * 390 | * The format of the relocation entries referenced by the reloff and nreloc 391 | * fields of the section structure for mach object files is described in the 392 | * header file . 393 | */ 394 | struct section { /* for 32-bit architectures */ 395 | char sectname[16]; /* name of this section */ 396 | char segname[16]; /* segment this section goes in */ 397 | uint32_t addr; /* memory address of this section */ 398 | uint32_t size; /* size in bytes of this section */ 399 | uint32_t offset; /* file offset of this section */ 400 | uint32_t align; /* section alignment (power of 2) */ 401 | uint32_t reloff; /* file offset of relocation entries */ 402 | uint32_t nreloc; /* number of relocation entries */ 403 | uint32_t flags; /* flags (section type and attributes)*/ 404 | uint32_t reserved1; /* reserved (for offset or index) */ 405 | uint32_t reserved2; /* reserved (for count or sizeof) */ 406 | }; 407 | 408 | struct section_64 { /* for 64-bit architectures */ 409 | char sectname[16]; /* name of this section */ 410 | char segname[16]; /* segment this section goes in */ 411 | uint64_t addr; /* memory address of this section */ 412 | uint64_t size; /* size in bytes of this section */ 413 | uint32_t offset; /* file offset of this section */ 414 | uint32_t align; /* section alignment (power of 2) */ 415 | uint32_t reloff; /* file offset of relocation entries */ 416 | uint32_t nreloc; /* number of relocation entries */ 417 | uint32_t flags; /* flags (section type and attributes)*/ 418 | uint32_t reserved1; /* reserved (for offset or index) */ 419 | uint32_t reserved2; /* reserved (for count or sizeof) */ 420 | uint32_t reserved3; /* reserved */ 421 | }; 422 | 423 | /* 424 | * The flags field of a section structure is separated into two parts a section 425 | * type and section attributes. The section types are mutually exclusive (it 426 | * can only have one type) but the section attributes are not (it may have more 427 | * than one attribute). 428 | */ 429 | #define SECTION_TYPE 0x000000ff /* 256 section types */ 430 | #define SECTION_ATTRIBUTES 0xffffff00 /* 24 section attributes */ 431 | 432 | /* Constants for the type of a section */ 433 | #define S_REGULAR 0x0 /* regular section */ 434 | #define S_ZEROFILL 0x1 /* zero fill on demand section */ 435 | #define S_CSTRING_LITERALS 0x2 /* section with only literal C strings*/ 436 | #define S_4BYTE_LITERALS 0x3 /* section with only 4 byte literals */ 437 | #define S_8BYTE_LITERALS 0x4 /* section with only 8 byte literals */ 438 | #define S_LITERAL_POINTERS 0x5 /* section with only pointers to */ 439 | /* literals */ 440 | /* 441 | * For the two types of symbol pointers sections and the symbol stubs section 442 | * they have indirect symbol table entries. For each of the entries in the 443 | * section the indirect symbol table entries, in corresponding order in the 444 | * indirect symbol table, start at the index stored in the reserved1 field 445 | * of the section structure. Since the indirect symbol table entries 446 | * correspond to the entries in the section the number of indirect symbol table 447 | * entries is inferred from the size of the section divided by the size of the 448 | * entries in the section. For symbol pointers sections the size of the entries 449 | * in the section is 4 bytes and for symbol stubs sections the byte size of the 450 | * stubs is stored in the reserved2 field of the section structure. 451 | */ 452 | #define S_NON_LAZY_SYMBOL_POINTERS 0x6 /* section with only non-lazy 453 | symbol pointers */ 454 | #define S_LAZY_SYMBOL_POINTERS 0x7 /* section with only lazy symbol 455 | pointers */ 456 | #define S_SYMBOL_STUBS 0x8 /* section with only symbol 457 | stubs, byte size of stub in 458 | the reserved2 field */ 459 | #define S_MOD_INIT_FUNC_POINTERS 0x9 /* section with only function 460 | pointers for initialization*/ 461 | #define S_MOD_TERM_FUNC_POINTERS 0xa /* section with only function 462 | pointers for termination */ 463 | #define S_COALESCED 0xb /* section contains symbols that 464 | are to be coalesced */ 465 | #define S_GB_ZEROFILL 0xc /* zero fill on demand section 466 | (that can be larger than 4 467 | gigabytes) */ 468 | #define S_INTERPOSING 0xd /* section with only pairs of 469 | function pointers for 470 | interposing */ 471 | #define S_16BYTE_LITERALS 0xe /* section with only 16 byte 472 | literals */ 473 | #define S_DTRACE_DOF 0xf /* section contains 474 | DTrace Object Format */ 475 | #define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 /* section with only lazy 476 | symbol pointers to lazy 477 | loaded dylibs */ 478 | /* 479 | * Section types to support thread local variables 480 | */ 481 | #define S_THREAD_LOCAL_REGULAR 0x11 /* template of initial 482 | values for TLVs */ 483 | #define S_THREAD_LOCAL_ZEROFILL 0x12 /* template of initial 484 | values for TLVs */ 485 | #define S_THREAD_LOCAL_VARIABLES 0x13 /* TLV descriptors */ 486 | #define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14 /* pointers to TLV 487 | descriptors */ 488 | #define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15 /* functions to call 489 | to initialize TLV 490 | values */ 491 | 492 | /* 493 | * Constants for the section attributes part of the flags field of a section 494 | * structure. 495 | */ 496 | #define SECTION_ATTRIBUTES_USR 0xff000000 /* User setable attributes */ 497 | #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section contains only true 498 | machine instructions */ 499 | #define S_ATTR_NO_TOC 0x40000000 /* section contains coalesced 500 | symbols that are not to be 501 | in a ranlib table of 502 | contents */ 503 | #define S_ATTR_STRIP_STATIC_SYMS 0x20000000 /* ok to strip static symbols 504 | in this section in files 505 | with the MH_DYLDLINK flag */ 506 | #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */ 507 | #define S_ATTR_LIVE_SUPPORT 0x08000000 /* blocks are live if they 508 | reference live blocks */ 509 | #define S_ATTR_SELF_MODIFYING_CODE 0x04000000 /* Used with i386 code stubs 510 | written on by dyld */ 511 | /* 512 | * If a segment contains any sections marked with S_ATTR_DEBUG then all 513 | * sections in that segment must have this attribute. No section other than 514 | * a section marked with this attribute may reference the contents of this 515 | * section. A section with this attribute may contain no symbols and must have 516 | * a section type S_REGULAR. The static linker will not copy section contents 517 | * from sections with this attribute into its output file. These sections 518 | * generally contain DWARF debugging info. 519 | */ 520 | #define S_ATTR_DEBUG 0x02000000 /* a debug section */ 521 | #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */ 522 | #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some 523 | machine instructions */ 524 | #define S_ATTR_EXT_RELOC 0x00000200 /* section has external 525 | relocation entries */ 526 | #define S_ATTR_LOC_RELOC 0x00000100 /* section has local 527 | relocation entries */ 528 | 529 | 530 | /* 531 | * The names of segments and sections in them are mostly meaningless to the 532 | * link-editor. But there are few things to support traditional UNIX 533 | * executables that require the link-editor and assembler to use some names 534 | * agreed upon by convention. 535 | * 536 | * The initial protection of the "__TEXT" segment has write protection turned 537 | * off (not writeable). 538 | * 539 | * The link-editor will allocate common symbols at the end of the "__common" 540 | * section in the "__DATA" segment. It will create the section and segment 541 | * if needed. 542 | */ 543 | 544 | /* The currently known segment names and the section names in those segments */ 545 | 546 | #define SEG_PAGEZERO "__PAGEZERO" /* the pagezero segment which has no */ 547 | /* protections and catches NULL */ 548 | /* references for MH_EXECUTE files */ 549 | 550 | 551 | #define SEG_TEXT "__TEXT" /* the tradition UNIX text segment */ 552 | #define SECT_TEXT "__text" /* the real text part of the text */ 553 | /* section no headers, and no padding */ 554 | #define SECT_FVMLIB_INIT0 "__fvmlib_init0" /* the fvmlib initialization */ 555 | /* section */ 556 | #define SECT_FVMLIB_INIT1 "__fvmlib_init1" /* the section following the */ 557 | /* fvmlib initialization */ 558 | /* section */ 559 | 560 | #define SEG_DATA "__DATA" /* the tradition UNIX data segment */ 561 | #define SECT_DATA "__data" /* the real initialized data section */ 562 | /* no padding, no bss overlap */ 563 | #define SECT_BSS "__bss" /* the real uninitialized data section*/ 564 | /* no padding */ 565 | #define SECT_COMMON "__common" /* the section common symbols are */ 566 | /* allocated in by the link editor */ 567 | 568 | #define SEG_OBJC "__OBJC" /* objective-C runtime segment */ 569 | #define SECT_OBJC_SYMBOLS "__symbol_table" /* symbol table */ 570 | #define SECT_OBJC_MODULES "__module_info" /* module information */ 571 | #define SECT_OBJC_STRINGS "__selector_strs" /* string table */ 572 | #define SECT_OBJC_REFS "__selector_refs" /* string table */ 573 | 574 | #define SEG_ICON "__ICON" /* the icon segment */ 575 | #define SECT_ICON_HEADER "__header" /* the icon headers */ 576 | #define SECT_ICON_TIFF "__tiff" /* the icons in tiff format */ 577 | 578 | #define SEG_LINKEDIT "__LINKEDIT" /* the segment containing all structs */ 579 | /* created and maintained by the link */ 580 | /* editor. Created with -seglinkedit */ 581 | /* option to ld(1) for MH_EXECUTE and */ 582 | /* FVMLIB file types only */ 583 | 584 | #define SEG_UNIXSTACK "__UNIXSTACK" /* the unix stack segment */ 585 | 586 | #define SEG_IMPORT "__IMPORT" /* the segment for the self (dyld) */ 587 | /* modifing code stubs that has read, */ 588 | /* write and execute permissions */ 589 | 590 | /* 591 | * Fixed virtual memory shared libraries are identified by two things. The 592 | * target pathname (the name of the library as found for execution), and the 593 | * minor version number. The address of where the headers are loaded is in 594 | * header_addr. (THIS IS OBSOLETE and no longer supported). 595 | */ 596 | struct fvmlib { 597 | union lc_str name; /* library's target pathname */ 598 | uint32_t minor_version; /* library's minor version number */ 599 | uint32_t header_addr; /* library's header address */ 600 | }; 601 | 602 | /* 603 | * A fixed virtual shared library (filetype == MH_FVMLIB in the mach header) 604 | * contains a fvmlib_command (cmd == LC_IDFVMLIB) to identify the library. 605 | * An object that uses a fixed virtual shared library also contains a 606 | * fvmlib_command (cmd == LC_LOADFVMLIB) for each library it uses. 607 | * (THIS IS OBSOLETE and no longer supported). 608 | */ 609 | struct fvmlib_command { 610 | uint32_t cmd; /* LC_IDFVMLIB or LC_LOADFVMLIB */ 611 | uint32_t cmdsize; /* includes pathname string */ 612 | struct fvmlib fvmlib; /* the library identification */ 613 | }; 614 | 615 | /* 616 | * Dynamicly linked shared libraries are identified by two things. The 617 | * pathname (the name of the library as found for execution), and the 618 | * compatibility version number. The pathname must match and the compatibility 619 | * number in the user of the library must be greater than or equal to the 620 | * library being used. The time stamp is used to record the time a library was 621 | * built and copied into user so it can be use to determined if the library used 622 | * at runtime is exactly the same as used to built the program. 623 | */ 624 | struct dylib { 625 | union lc_str name; /* library's path name */ 626 | uint32_t timestamp; /* library's build time stamp */ 627 | uint32_t current_version; /* library's current version number */ 628 | uint32_t compatibility_version; /* library's compatibility vers number*/ 629 | }; 630 | 631 | /* 632 | * A dynamically linked shared library (filetype == MH_DYLIB in the mach header) 633 | * contains a dylib_command (cmd == LC_ID_DYLIB) to identify the library. 634 | * An object that uses a dynamically linked shared library also contains a 635 | * dylib_command (cmd == LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB, or 636 | * LC_REEXPORT_DYLIB) for each library it uses. 637 | */ 638 | struct dylib_command { 639 | uint32_t cmd; /* LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, 640 | LC_REEXPORT_DYLIB */ 641 | uint32_t cmdsize; /* includes pathname string */ 642 | struct dylib dylib; /* the library identification */ 643 | }; 644 | 645 | /* 646 | * A dynamically linked shared library may be a subframework of an umbrella 647 | * framework. If so it will be linked with "-umbrella umbrella_name" where 648 | * Where "umbrella_name" is the name of the umbrella framework. A subframework 649 | * can only be linked against by its umbrella framework or other subframeworks 650 | * that are part of the same umbrella framework. Otherwise the static link 651 | * editor produces an error and states to link against the umbrella framework. 652 | * The name of the umbrella framework for subframeworks is recorded in the 653 | * following structure. 654 | */ 655 | struct sub_framework_command { 656 | uint32_t cmd; /* LC_SUB_FRAMEWORK */ 657 | uint32_t cmdsize; /* includes umbrella string */ 658 | union lc_str umbrella; /* the umbrella framework name */ 659 | }; 660 | 661 | /* 662 | * For dynamically linked shared libraries that are subframework of an umbrella 663 | * framework they can allow clients other than the umbrella framework or other 664 | * subframeworks in the same umbrella framework. To do this the subframework 665 | * is built with "-allowable_client client_name" and an LC_SUB_CLIENT load 666 | * command is created for each -allowable_client flag. The client_name is 667 | * usually a framework name. It can also be a name used for bundles clients 668 | * where the bundle is built with "-client_name client_name". 669 | */ 670 | struct sub_client_command { 671 | uint32_t cmd; /* LC_SUB_CLIENT */ 672 | uint32_t cmdsize; /* includes client string */ 673 | union lc_str client; /* the client name */ 674 | }; 675 | 676 | /* 677 | * A dynamically linked shared library may be a sub_umbrella of an umbrella 678 | * framework. If so it will be linked with "-sub_umbrella umbrella_name" where 679 | * Where "umbrella_name" is the name of the sub_umbrella framework. When 680 | * staticly linking when -twolevel_namespace is in effect a twolevel namespace 681 | * umbrella framework will only cause its subframeworks and those frameworks 682 | * listed as sub_umbrella frameworks to be implicited linked in. Any other 683 | * dependent dynamic libraries will not be linked it when -twolevel_namespace 684 | * is in effect. The primary library recorded by the static linker when 685 | * resolving a symbol in these libraries will be the umbrella framework. 686 | * Zero or more sub_umbrella frameworks may be use by an umbrella framework. 687 | * The name of a sub_umbrella framework is recorded in the following structure. 688 | */ 689 | struct sub_umbrella_command { 690 | uint32_t cmd; /* LC_SUB_UMBRELLA */ 691 | uint32_t cmdsize; /* includes sub_umbrella string */ 692 | union lc_str sub_umbrella; /* the sub_umbrella framework name */ 693 | }; 694 | 695 | /* 696 | * A dynamically linked shared library may be a sub_library of another shared 697 | * library. If so it will be linked with "-sub_library library_name" where 698 | * Where "library_name" is the name of the sub_library shared library. When 699 | * staticly linking when -twolevel_namespace is in effect a twolevel namespace 700 | * shared library will only cause its subframeworks and those frameworks 701 | * listed as sub_umbrella frameworks and libraries listed as sub_libraries to 702 | * be implicited linked in. Any other dependent dynamic libraries will not be 703 | * linked it when -twolevel_namespace is in effect. The primary library 704 | * recorded by the static linker when resolving a symbol in these libraries 705 | * will be the umbrella framework (or dynamic library). Zero or more sub_library 706 | * shared libraries may be use by an umbrella framework or (or dynamic library). 707 | * The name of a sub_library framework is recorded in the following structure. 708 | * For example /usr/lib/libobjc_profile.A.dylib would be recorded as "libobjc". 709 | */ 710 | struct sub_library_command { 711 | uint32_t cmd; /* LC_SUB_LIBRARY */ 712 | uint32_t cmdsize; /* includes sub_library string */ 713 | union lc_str sub_library; /* the sub_library name */ 714 | }; 715 | 716 | /* 717 | * A program (filetype == MH_EXECUTE) that is 718 | * prebound to its dynamic libraries has one of these for each library that 719 | * the static linker used in prebinding. It contains a bit vector for the 720 | * modules in the library. The bits indicate which modules are bound (1) and 721 | * which are not (0) from the library. The bit for module 0 is the low bit 722 | * of the first byte. So the bit for the Nth module is: 723 | * (linked_modules[N/8] >> N%8) & 1 724 | */ 725 | struct prebound_dylib_command { 726 | uint32_t cmd; /* LC_PREBOUND_DYLIB */ 727 | uint32_t cmdsize; /* includes strings */ 728 | union lc_str name; /* library's path name */ 729 | uint32_t nmodules; /* number of modules in library */ 730 | union lc_str linked_modules; /* bit vector of linked modules */ 731 | }; 732 | 733 | /* 734 | * A program that uses a dynamic linker contains a dylinker_command to identify 735 | * the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker 736 | * contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER). 737 | * A file can have at most one of these. 738 | * This struct is also used for the LC_DYLD_ENVIRONMENT load command and 739 | * contains string for dyld to treat like environment variable. 740 | */ 741 | struct dylinker_command { 742 | uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or 743 | LC_DYLD_ENVIRONMENT */ 744 | uint32_t cmdsize; /* includes pathname string */ 745 | union lc_str name; /* dynamic linker's path name */ 746 | }; 747 | 748 | /* 749 | * Thread commands contain machine-specific data structures suitable for 750 | * use in the thread state primitives. The machine specific data structures 751 | * follow the struct thread_command as follows. 752 | * Each flavor of machine specific data structure is preceded by an unsigned 753 | * long constant for the flavor of that data structure, an uint32_t 754 | * that is the count of longs of the size of the state data structure and then 755 | * the state data structure follows. This triple may be repeated for many 756 | * flavors. The constants for the flavors, counts and state data structure 757 | * definitions are expected to be in the header file . 758 | * These machine specific data structures sizes must be multiples of 759 | * 4 bytes The cmdsize reflects the total size of the thread_command 760 | * and all of the sizes of the constants for the flavors, counts and state 761 | * data structures. 762 | * 763 | * For executable objects that are unix processes there will be one 764 | * thread_command (cmd == LC_UNIXTHREAD) created for it by the link-editor. 765 | * This is the same as a LC_THREAD, except that a stack is automatically 766 | * created (based on the shell's limit for the stack size). Command arguments 767 | * and environment variables are copied onto that stack. 768 | */ 769 | struct thread_command { 770 | uint32_t cmd; /* LC_THREAD or LC_UNIXTHREAD */ 771 | uint32_t cmdsize; /* total size of this command */ 772 | /* uint32_t flavor flavor of thread state */ 773 | /* uint32_t count count of longs in thread state */ 774 | /* struct XXX_thread_state state thread state for this flavor */ 775 | /* ... */ 776 | }; 777 | 778 | /* 779 | * The routines command contains the address of the dynamic shared library 780 | * initialization routine and an index into the module table for the module 781 | * that defines the routine. Before any modules are used from the library the 782 | * dynamic linker fully binds the module that defines the initialization routine 783 | * and then calls it. This gets called before any module initialization 784 | * routines (used for C++ static constructors) in the library. 785 | */ 786 | struct routines_command { /* for 32-bit architectures */ 787 | uint32_t cmd; /* LC_ROUTINES */ 788 | uint32_t cmdsize; /* total size of this command */ 789 | uint32_t init_address; /* address of initialization routine */ 790 | uint32_t init_module; /* index into the module table that */ 791 | /* the init routine is defined in */ 792 | uint32_t reserved1; 793 | uint32_t reserved2; 794 | uint32_t reserved3; 795 | uint32_t reserved4; 796 | uint32_t reserved5; 797 | uint32_t reserved6; 798 | }; 799 | 800 | /* 801 | * The 64-bit routines command. Same use as above. 802 | */ 803 | struct routines_command_64 { /* for 64-bit architectures */ 804 | uint32_t cmd; /* LC_ROUTINES_64 */ 805 | uint32_t cmdsize; /* total size of this command */ 806 | uint64_t init_address; /* address of initialization routine */ 807 | uint64_t init_module; /* index into the module table that */ 808 | /* the init routine is defined in */ 809 | uint64_t reserved1; 810 | uint64_t reserved2; 811 | uint64_t reserved3; 812 | uint64_t reserved4; 813 | uint64_t reserved5; 814 | uint64_t reserved6; 815 | }; 816 | 817 | /* 818 | * The symtab_command contains the offsets and sizes of the link-edit 4.3BSD 819 | * "stab" style symbol table information as described in the header files 820 | * and . 821 | */ 822 | struct symtab_command { 823 | uint32_t cmd; /* LC_SYMTAB */ 824 | uint32_t cmdsize; /* sizeof(struct symtab_command) */ 825 | uint32_t symoff; /* symbol table offset */ 826 | uint32_t nsyms; /* number of symbol table entries */ 827 | uint32_t stroff; /* string table offset */ 828 | uint32_t strsize; /* string table size in bytes */ 829 | }; 830 | 831 | /* 832 | * This is the second set of the symbolic information which is used to support 833 | * the data structures for the dynamically link editor. 834 | * 835 | * The original set of symbolic information in the symtab_command which contains 836 | * the symbol and string tables must also be present when this load command is 837 | * present. When this load command is present the symbol table is organized 838 | * into three groups of symbols: 839 | * local symbols (static and debugging symbols) - grouped by module 840 | * defined external symbols - grouped by module (sorted by name if not lib) 841 | * undefined external symbols (sorted by name if MH_BINDATLOAD is not set, 842 | * and in order the were seen by the static 843 | * linker if MH_BINDATLOAD is set) 844 | * In this load command there are offsets and counts to each of the three groups 845 | * of symbols. 846 | * 847 | * This load command contains a the offsets and sizes of the following new 848 | * symbolic information tables: 849 | * table of contents 850 | * module table 851 | * reference symbol table 852 | * indirect symbol table 853 | * The first three tables above (the table of contents, module table and 854 | * reference symbol table) are only present if the file is a dynamically linked 855 | * shared library. For executable and object modules, which are files 856 | * containing only one module, the information that would be in these three 857 | * tables is determined as follows: 858 | * table of contents - the defined external symbols are sorted by name 859 | * module table - the file contains only one module so everything in the 860 | * file is part of the module. 861 | * reference symbol table - is the defined and undefined external symbols 862 | * 863 | * For dynamically linked shared library files this load command also contains 864 | * offsets and sizes to the pool of relocation entries for all sections 865 | * separated into two groups: 866 | * external relocation entries 867 | * local relocation entries 868 | * For executable and object modules the relocation entries continue to hang 869 | * off the section structures. 870 | */ 871 | struct dysymtab_command { 872 | uint32_t cmd; /* LC_DYSYMTAB */ 873 | uint32_t cmdsize; /* sizeof(struct dysymtab_command) */ 874 | 875 | /* 876 | * The symbols indicated by symoff and nsyms of the LC_SYMTAB load command 877 | * are grouped into the following three groups: 878 | * local symbols (further grouped by the module they are from) 879 | * defined external symbols (further grouped by the module they are from) 880 | * undefined symbols 881 | * 882 | * The local symbols are used only for debugging. The dynamic binding 883 | * process may have to use them to indicate to the debugger the local 884 | * symbols for a module that is being bound. 885 | * 886 | * The last two groups are used by the dynamic binding process to do the 887 | * binding (indirectly through the module table and the reference symbol 888 | * table when this is a dynamically linked shared library file). 889 | */ 890 | uint32_t ilocalsym; /* index to local symbols */ 891 | uint32_t nlocalsym; /* number of local symbols */ 892 | 893 | uint32_t iextdefsym;/* index to externally defined symbols */ 894 | uint32_t nextdefsym;/* number of externally defined symbols */ 895 | 896 | uint32_t iundefsym; /* index to undefined symbols */ 897 | uint32_t nundefsym; /* number of undefined symbols */ 898 | 899 | /* 900 | * For the for the dynamic binding process to find which module a symbol 901 | * is defined in the table of contents is used (analogous to the ranlib 902 | * structure in an archive) which maps defined external symbols to modules 903 | * they are defined in. This exists only in a dynamically linked shared 904 | * library file. For executable and object modules the defined external 905 | * symbols are sorted by name and is use as the table of contents. 906 | */ 907 | uint32_t tocoff; /* file offset to table of contents */ 908 | uint32_t ntoc; /* number of entries in table of contents */ 909 | 910 | /* 911 | * To support dynamic binding of "modules" (whole object files) the symbol 912 | * table must reflect the modules that the file was created from. This is 913 | * done by having a module table that has indexes and counts into the merged 914 | * tables for each module. The module structure that these two entries 915 | * refer to is described below. This exists only in a dynamically linked 916 | * shared library file. For executable and object modules the file only 917 | * contains one module so everything in the file belongs to the module. 918 | */ 919 | uint32_t modtaboff; /* file offset to module table */ 920 | uint32_t nmodtab; /* number of module table entries */ 921 | 922 | /* 923 | * To support dynamic module binding the module structure for each module 924 | * indicates the external references (defined and undefined) each module 925 | * makes. For each module there is an offset and a count into the 926 | * reference symbol table for the symbols that the module references. 927 | * This exists only in a dynamically linked shared library file. For 928 | * executable and object modules the defined external symbols and the 929 | * undefined external symbols indicates the external references. 930 | */ 931 | uint32_t extrefsymoff; /* offset to referenced symbol table */ 932 | uint32_t nextrefsyms; /* number of referenced symbol table entries */ 933 | 934 | /* 935 | * The sections that contain "symbol pointers" and "routine stubs" have 936 | * indexes and (implied counts based on the size of the section and fixed 937 | * size of the entry) into the "indirect symbol" table for each pointer 938 | * and stub. For every section of these two types the index into the 939 | * indirect symbol table is stored in the section header in the field 940 | * reserved1. An indirect symbol table entry is simply a 32bit index into 941 | * the symbol table to the symbol that the pointer or stub is referring to. 942 | * The indirect symbol table is ordered to match the entries in the section. 943 | */ 944 | uint32_t indirectsymoff; /* file offset to the indirect symbol table */ 945 | uint32_t nindirectsyms; /* number of indirect symbol table entries */ 946 | 947 | /* 948 | * To support relocating an individual module in a library file quickly the 949 | * external relocation entries for each module in the library need to be 950 | * accessed efficiently. Since the relocation entries can't be accessed 951 | * through the section headers for a library file they are separated into 952 | * groups of local and external entries further grouped by module. In this 953 | * case the presents of this load command who's extreloff, nextrel, 954 | * locreloff and nlocrel fields are non-zero indicates that the relocation 955 | * entries of non-merged sections are not referenced through the section 956 | * structures (and the reloff and nreloc fields in the section headers are 957 | * set to zero). 958 | * 959 | * Since the relocation entries are not accessed through the section headers 960 | * this requires the r_address field to be something other than a section 961 | * offset to identify the item to be relocated. In this case r_address is 962 | * set to the offset from the vmaddr of the first LC_SEGMENT command. 963 | * For MH_SPLIT_SEGS images r_address is set to the the offset from the 964 | * vmaddr of the first read-write LC_SEGMENT command. 965 | * 966 | * The relocation entries are grouped by module and the module table 967 | * entries have indexes and counts into them for the group of external 968 | * relocation entries for that the module. 969 | * 970 | * For sections that are merged across modules there must not be any 971 | * remaining external relocation entries for them (for merged sections 972 | * remaining relocation entries must be local). 973 | */ 974 | uint32_t extreloff; /* offset to external relocation entries */ 975 | uint32_t nextrel; /* number of external relocation entries */ 976 | 977 | /* 978 | * All the local relocation entries are grouped together (they are not 979 | * grouped by their module since they are only used if the object is moved 980 | * from it staticly link edited address). 981 | */ 982 | uint32_t locreloff; /* offset to local relocation entries */ 983 | uint32_t nlocrel; /* number of local relocation entries */ 984 | 985 | }; 986 | 987 | /* 988 | * An indirect symbol table entry is simply a 32bit index into the symbol table 989 | * to the symbol that the pointer or stub is refering to. Unless it is for a 990 | * non-lazy symbol pointer section for a defined symbol which strip(1) as 991 | * removed. In which case it has the value INDIRECT_SYMBOL_LOCAL. If the 992 | * symbol was also absolute INDIRECT_SYMBOL_ABS is or'ed with that. 993 | */ 994 | #define INDIRECT_SYMBOL_LOCAL 0x80000000 995 | #define INDIRECT_SYMBOL_ABS 0x40000000 996 | 997 | 998 | /* a table of contents entry */ 999 | struct dylib_table_of_contents { 1000 | uint32_t symbol_index; /* the defined external symbol 1001 | (index into the symbol table) */ 1002 | uint32_t module_index; /* index into the module table this symbol 1003 | is defined in */ 1004 | }; 1005 | 1006 | /* a module table entry */ 1007 | struct dylib_module { 1008 | uint32_t module_name; /* the module name (index into string table) */ 1009 | 1010 | uint32_t iextdefsym; /* index into externally defined symbols */ 1011 | uint32_t nextdefsym; /* number of externally defined symbols */ 1012 | uint32_t irefsym; /* index into reference symbol table */ 1013 | uint32_t nrefsym; /* number of reference symbol table entries */ 1014 | uint32_t ilocalsym; /* index into symbols for local symbols */ 1015 | uint32_t nlocalsym; /* number of local symbols */ 1016 | 1017 | uint32_t iextrel; /* index into external relocation entries */ 1018 | uint32_t nextrel; /* number of external relocation entries */ 1019 | 1020 | uint32_t iinit_iterm; /* low 16 bits are the index into the init 1021 | section, high 16 bits are the index into 1022 | the term section */ 1023 | uint32_t ninit_nterm; /* low 16 bits are the number of init section 1024 | entries, high 16 bits are the number of 1025 | term section entries */ 1026 | 1027 | uint32_t /* for this module address of the start of */ 1028 | objc_module_info_addr; /* the (__OBJC,__module_info) section */ 1029 | uint32_t /* for this module size of */ 1030 | objc_module_info_size; /* the (__OBJC,__module_info) section */ 1031 | }; 1032 | 1033 | /* a 64-bit module table entry */ 1034 | struct dylib_module_64 { 1035 | uint32_t module_name; /* the module name (index into string table) */ 1036 | 1037 | uint32_t iextdefsym; /* index into externally defined symbols */ 1038 | uint32_t nextdefsym; /* number of externally defined symbols */ 1039 | uint32_t irefsym; /* index into reference symbol table */ 1040 | uint32_t nrefsym; /* number of reference symbol table entries */ 1041 | uint32_t ilocalsym; /* index into symbols for local symbols */ 1042 | uint32_t nlocalsym; /* number of local symbols */ 1043 | 1044 | uint32_t iextrel; /* index into external relocation entries */ 1045 | uint32_t nextrel; /* number of external relocation entries */ 1046 | 1047 | uint32_t iinit_iterm; /* low 16 bits are the index into the init 1048 | section, high 16 bits are the index into 1049 | the term section */ 1050 | uint32_t ninit_nterm; /* low 16 bits are the number of init section 1051 | entries, high 16 bits are the number of 1052 | term section entries */ 1053 | 1054 | uint32_t /* for this module size of */ 1055 | objc_module_info_size; /* the (__OBJC,__module_info) section */ 1056 | uint64_t /* for this module address of the start of */ 1057 | objc_module_info_addr; /* the (__OBJC,__module_info) section */ 1058 | }; 1059 | 1060 | /* 1061 | * The entries in the reference symbol table are used when loading the module 1062 | * (both by the static and dynamic link editors) and if the module is unloaded 1063 | * or replaced. Therefore all external symbols (defined and undefined) are 1064 | * listed in the module's reference table. The flags describe the type of 1065 | * reference that is being made. The constants for the flags are defined in 1066 | * as they are also used for symbol table entries. 1067 | */ 1068 | struct dylib_reference { 1069 | uint32_t isym:24, /* index into the symbol table */ 1070 | flags:8; /* flags to indicate the type of reference */ 1071 | }; 1072 | 1073 | /* 1074 | * The twolevel_hints_command contains the offset and number of hints in the 1075 | * two-level namespace lookup hints table. 1076 | */ 1077 | struct twolevel_hints_command { 1078 | uint32_t cmd; /* LC_TWOLEVEL_HINTS */ 1079 | uint32_t cmdsize; /* sizeof(struct twolevel_hints_command) */ 1080 | uint32_t offset; /* offset to the hint table */ 1081 | uint32_t nhints; /* number of hints in the hint table */ 1082 | }; 1083 | 1084 | /* 1085 | * The entries in the two-level namespace lookup hints table are twolevel_hint 1086 | * structs. These provide hints to the dynamic link editor where to start 1087 | * looking for an undefined symbol in a two-level namespace image. The 1088 | * isub_image field is an index into the sub-images (sub-frameworks and 1089 | * sub-umbrellas list) that made up the two-level image that the undefined 1090 | * symbol was found in when it was built by the static link editor. If 1091 | * isub-image is 0 the the symbol is expected to be defined in library and not 1092 | * in the sub-images. If isub-image is non-zero it is an index into the array 1093 | * of sub-images for the umbrella with the first index in the sub-images being 1094 | * 1. The array of sub-images is the ordered list of sub-images of the umbrella 1095 | * that would be searched for a symbol that has the umbrella recorded as its 1096 | * primary library. The table of contents index is an index into the 1097 | * library's table of contents. This is used as the starting point of the 1098 | * binary search or a directed linear search. 1099 | */ 1100 | struct twolevel_hint { 1101 | uint32_t 1102 | isub_image:8, /* index into the sub images */ 1103 | itoc:24; /* index into the table of contents */ 1104 | }; 1105 | 1106 | /* 1107 | * The prebind_cksum_command contains the value of the original check sum for 1108 | * prebound files or zero. When a prebound file is first created or modified 1109 | * for other than updating its prebinding information the value of the check sum 1110 | * is set to zero. When the file has it prebinding re-done and if the value of 1111 | * the check sum is zero the original check sum is calculated and stored in 1112 | * cksum field of this load command in the output file. If when the prebinding 1113 | * is re-done and the cksum field is non-zero it is left unchanged from the 1114 | * input file. 1115 | */ 1116 | struct prebind_cksum_command { 1117 | uint32_t cmd; /* LC_PREBIND_CKSUM */ 1118 | uint32_t cmdsize; /* sizeof(struct prebind_cksum_command) */ 1119 | uint32_t cksum; /* the check sum or zero */ 1120 | }; 1121 | 1122 | /* 1123 | * The uuid load command contains a single 128-bit unique random number that 1124 | * identifies an object produced by the static link editor. 1125 | */ 1126 | struct uuid_command { 1127 | uint32_t cmd; /* LC_UUID */ 1128 | uint32_t cmdsize; /* sizeof(struct uuid_command) */ 1129 | uint8_t uuid[16]; /* the 128-bit uuid */ 1130 | }; 1131 | 1132 | /* 1133 | * The rpath_command contains a path which at runtime should be added to 1134 | * the current run path used to find @rpath prefixed dylibs. 1135 | */ 1136 | struct rpath_command { 1137 | uint32_t cmd; /* LC_RPATH */ 1138 | uint32_t cmdsize; /* includes string */ 1139 | union lc_str path; /* path to add to run path */ 1140 | }; 1141 | 1142 | /* 1143 | * The linkedit_data_command contains the offsets and sizes of a blob 1144 | * of data in the __LINKEDIT segment. 1145 | */ 1146 | struct linkedit_data_command { 1147 | uint32_t cmd; /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, 1148 | LC_FUNCTION_STARTS, LC_DATA_IN_CODE, 1149 | or LC_DYLIB_CODE_SIGN_DRS */ 1150 | uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */ 1151 | uint32_t dataoff; /* file offset of data in __LINKEDIT segment */ 1152 | uint32_t datasize; /* file size of data in __LINKEDIT segment */ 1153 | }; 1154 | 1155 | /* 1156 | * The encryption_info_command contains the file offset and size of an 1157 | * of an encrypted segment. 1158 | */ 1159 | struct encryption_info_command { 1160 | uint32_t cmd; /* LC_ENCRYPTION_INFO */ 1161 | uint32_t cmdsize; /* sizeof(struct encryption_info_command) */ 1162 | uint32_t cryptoff; /* file offset of encrypted range */ 1163 | uint32_t cryptsize; /* file size of encrypted range */ 1164 | uint32_t cryptid; /* which enryption system, 1165 | 0 means not-encrypted yet */ 1166 | }; 1167 | 1168 | /* 1169 | * The encryption_info_command_64 contains the file offset and size of an 1170 | * of an encrypted segment (for use in 64-bit targets). 1171 | */ 1172 | struct encryption_info_command_64 { 1173 | uint32_t cmd; /* LC_ENCRYPTION_INFO_64 */ 1174 | uint32_t cmdsize; /* sizeof(struct encryption_info_command_64) */ 1175 | uint32_t cryptoff; /* file offset of encrypted range */ 1176 | uint32_t cryptsize; /* file size of encrypted range */ 1177 | uint32_t cryptid; /* which enryption system, 1178 | 0 means not-encrypted yet */ 1179 | uint32_t pad; /* padding to make this struct's size a multiple 1180 | of 8 bytes */ 1181 | }; 1182 | 1183 | /* 1184 | * The version_min_command contains the min OS version on which this 1185 | * binary was built to run. 1186 | */ 1187 | struct version_min_command { 1188 | uint32_t cmd; /* LC_VERSION_MIN_MACOSX or 1189 | LC_VERSION_MIN_IPHONEOS */ 1190 | uint32_t cmdsize; /* sizeof(struct min_version_command) */ 1191 | uint32_t version; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ 1192 | uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ 1193 | }; 1194 | 1195 | /* 1196 | * The dyld_info_command contains the file offsets and sizes of 1197 | * the new compressed form of the information dyld needs to 1198 | * load the image. This information is used by dyld on Mac OS X 1199 | * 10.6 and later. All information pointed to by this command 1200 | * is encoded using byte streams, so no endian swapping is needed 1201 | * to interpret it. 1202 | */ 1203 | struct dyld_info_command { 1204 | uint32_t cmd; /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */ 1205 | uint32_t cmdsize; /* sizeof(struct dyld_info_command) */ 1206 | 1207 | /* 1208 | * Dyld rebases an image whenever dyld loads it at an address different 1209 | * from its preferred address. The rebase information is a stream 1210 | * of byte sized opcodes whose symbolic names start with REBASE_OPCODE_. 1211 | * Conceptually the rebase information is a table of tuples: 1212 | * 1213 | * The opcodes are a compressed way to encode the table by only 1214 | * encoding when a column changes. In addition simple patterns 1215 | * like "every n'th offset for m times" can be encoded in a few 1216 | * bytes. 1217 | */ 1218 | uint32_t rebase_off; /* file offset to rebase info */ 1219 | uint32_t rebase_size; /* size of rebase info */ 1220 | 1221 | /* 1222 | * Dyld binds an image during the loading process, if the image 1223 | * requires any pointers to be initialized to symbols in other images. 1224 | * The bind information is a stream of byte sized 1225 | * opcodes whose symbolic names start with BIND_OPCODE_. 1226 | * Conceptually the bind information is a table of tuples: 1227 | * 1228 | * The opcodes are a compressed way to encode the table by only 1229 | * encoding when a column changes. In addition simple patterns 1230 | * like for runs of pointers initialzed to the same value can be 1231 | * encoded in a few bytes. 1232 | */ 1233 | uint32_t bind_off; /* file offset to binding info */ 1234 | uint32_t bind_size; /* size of binding info */ 1235 | 1236 | /* 1237 | * Some C++ programs require dyld to unique symbols so that all 1238 | * images in the process use the same copy of some code/data. 1239 | * This step is done after binding. The content of the weak_bind 1240 | * info is an opcode stream like the bind_info. But it is sorted 1241 | * alphabetically by symbol name. This enable dyld to walk 1242 | * all images with weak binding information in order and look 1243 | * for collisions. If there are no collisions, dyld does 1244 | * no updating. That means that some fixups are also encoded 1245 | * in the bind_info. For instance, all calls to "operator new" 1246 | * are first bound to libstdc++.dylib using the information 1247 | * in bind_info. Then if some image overrides operator new 1248 | * that is detected when the weak_bind information is processed 1249 | * and the call to operator new is then rebound. 1250 | */ 1251 | uint32_t weak_bind_off; /* file offset to weak binding info */ 1252 | uint32_t weak_bind_size; /* size of weak binding info */ 1253 | 1254 | /* 1255 | * Some uses of external symbols do not need to be bound immediately. 1256 | * Instead they can be lazily bound on first use. The lazy_bind 1257 | * are contains a stream of BIND opcodes to bind all lazy symbols. 1258 | * Normal use is that dyld ignores the lazy_bind section when 1259 | * loading an image. Instead the static linker arranged for the 1260 | * lazy pointer to initially point to a helper function which 1261 | * pushes the offset into the lazy_bind area for the symbol 1262 | * needing to be bound, then jumps to dyld which simply adds 1263 | * the offset to lazy_bind_off to get the information on what 1264 | * to bind. 1265 | */ 1266 | uint32_t lazy_bind_off; /* file offset to lazy binding info */ 1267 | uint32_t lazy_bind_size; /* size of lazy binding infs */ 1268 | 1269 | /* 1270 | * The symbols exported by a dylib are encoded in a trie. This 1271 | * is a compact representation that factors out common prefixes. 1272 | * It also reduces LINKEDIT pages in RAM because it encodes all 1273 | * information (name, address, flags) in one small, contiguous range. 1274 | * The export area is a stream of nodes. The first node sequentially 1275 | * is the start node for the trie. 1276 | * 1277 | * Nodes for a symbol start with a uleb128 that is the length of 1278 | * the exported symbol information for the string so far. 1279 | * If there is no exported symbol, the node starts with a zero byte. 1280 | * If there is exported info, it follows the length. 1281 | * 1282 | * First is a uleb128 containing flags. Normally, it is followed by 1283 | * a uleb128 encoded offset which is location of the content named 1284 | * by the symbol from the mach_header for the image. If the flags 1285 | * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is 1286 | * a uleb128 encoded library ordinal, then a zero terminated 1287 | * UTF8 string. If the string is zero length, then the symbol 1288 | * is re-export from the specified dylib with the same name. 1289 | * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following 1290 | * the flags is two uleb128s: the stub offset and the resolver offset. 1291 | * The stub is used by non-lazy pointers. The resolver is used 1292 | * by lazy pointers and must be called to get the actual address to use. 1293 | * 1294 | * After the optional exported symbol information is a byte of 1295 | * how many edges (0-255) that this node has leaving it, 1296 | * followed by each edge. 1297 | * Each edge is a zero terminated UTF8 of the addition chars 1298 | * in the symbol, followed by a uleb128 offset for the node that 1299 | * edge points to. 1300 | * 1301 | */ 1302 | uint32_t export_off; /* file offset to lazy binding info */ 1303 | uint32_t export_size; /* size of lazy binding infs */ 1304 | }; 1305 | 1306 | /* 1307 | * The following are used to encode rebasing information 1308 | */ 1309 | #define REBASE_TYPE_POINTER 1 1310 | #define REBASE_TYPE_TEXT_ABSOLUTE32 2 1311 | #define REBASE_TYPE_TEXT_PCREL32 3 1312 | 1313 | #define REBASE_OPCODE_MASK 0xF0 1314 | #define REBASE_IMMEDIATE_MASK 0x0F 1315 | #define REBASE_OPCODE_DONE 0x00 1316 | #define REBASE_OPCODE_SET_TYPE_IMM 0x10 1317 | #define REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x20 1318 | #define REBASE_OPCODE_ADD_ADDR_ULEB 0x30 1319 | #define REBASE_OPCODE_ADD_ADDR_IMM_SCALED 0x40 1320 | #define REBASE_OPCODE_DO_REBASE_IMM_TIMES 0x50 1321 | #define REBASE_OPCODE_DO_REBASE_ULEB_TIMES 0x60 1322 | #define REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB 0x70 1323 | #define REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB 0x80 1324 | 1325 | 1326 | /* 1327 | * The following are used to encode binding information 1328 | */ 1329 | #define BIND_TYPE_POINTER 1 1330 | #define BIND_TYPE_TEXT_ABSOLUTE32 2 1331 | #define BIND_TYPE_TEXT_PCREL32 3 1332 | 1333 | #define BIND_SPECIAL_DYLIB_SELF 0 1334 | #define BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE -1 1335 | #define BIND_SPECIAL_DYLIB_FLAT_LOOKUP -2 1336 | 1337 | #define BIND_SYMBOL_FLAGS_WEAK_IMPORT 0x1 1338 | #define BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION 0x8 1339 | 1340 | #define BIND_OPCODE_MASK 0xF0 1341 | #define BIND_IMMEDIATE_MASK 0x0F 1342 | #define BIND_OPCODE_DONE 0x00 1343 | #define BIND_OPCODE_SET_DYLIB_ORDINAL_IMM 0x10 1344 | #define BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB 0x20 1345 | #define BIND_OPCODE_SET_DYLIB_SPECIAL_IMM 0x30 1346 | #define BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM 0x40 1347 | #define BIND_OPCODE_SET_TYPE_IMM 0x50 1348 | #define BIND_OPCODE_SET_ADDEND_SLEB 0x60 1349 | #define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB 0x70 1350 | #define BIND_OPCODE_ADD_ADDR_ULEB 0x80 1351 | #define BIND_OPCODE_DO_BIND 0x90 1352 | #define BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB 0xA0 1353 | #define BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED 0xB0 1354 | #define BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB 0xC0 1355 | 1356 | 1357 | /* 1358 | * The following are used on the flags byte of a terminal node 1359 | * in the export information. 1360 | */ 1361 | #define EXPORT_SYMBOL_FLAGS_KIND_MASK 0x03 1362 | #define EXPORT_SYMBOL_FLAGS_KIND_REGULAR 0x00 1363 | #define EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL 0x01 1364 | #define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION 0x04 1365 | #define EXPORT_SYMBOL_FLAGS_REEXPORT 0x08 1366 | #define EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER 0x10 1367 | 1368 | /* 1369 | * The symseg_command contains the offset and size of the GNU style 1370 | * symbol table information as described in the header file . 1371 | * The symbol roots of the symbol segments must also be aligned properly 1372 | * in the file. So the requirement of keeping the offsets aligned to a 1373 | * multiple of a 4 bytes translates to the length field of the symbol 1374 | * roots also being a multiple of a long. Also the padding must again be 1375 | * zeroed. (THIS IS OBSOLETE and no longer supported). 1376 | */ 1377 | struct symseg_command { 1378 | uint32_t cmd; /* LC_SYMSEG */ 1379 | uint32_t cmdsize; /* sizeof(struct symseg_command) */ 1380 | uint32_t offset; /* symbol segment offset */ 1381 | uint32_t size; /* symbol segment size in bytes */ 1382 | }; 1383 | 1384 | /* 1385 | * The ident_command contains a free format string table following the 1386 | * ident_command structure. The strings are null terminated and the size of 1387 | * the command is padded out with zero bytes to a multiple of 4 bytes/ 1388 | * (THIS IS OBSOLETE and no longer supported). 1389 | */ 1390 | struct ident_command { 1391 | uint32_t cmd; /* LC_IDENT */ 1392 | uint32_t cmdsize; /* strings that follow this command */ 1393 | }; 1394 | 1395 | /* 1396 | * The fvmfile_command contains a reference to a file to be loaded at the 1397 | * specified virtual address. (Presently, this command is reserved for 1398 | * internal use. The kernel ignores this command when loading a program into 1399 | * memory). 1400 | */ 1401 | struct fvmfile_command { 1402 | uint32_t cmd; /* LC_FVMFILE */ 1403 | uint32_t cmdsize; /* includes pathname string */ 1404 | union lc_str name; /* files pathname */ 1405 | uint32_t header_addr; /* files virtual address */ 1406 | }; 1407 | 1408 | 1409 | /* 1410 | * The entry_point_command is a replacement for thread_command. 1411 | * It is used for main executables to specify the location (file offset) 1412 | * of main(). If -stack_size was used at link time, the stacksize 1413 | * field will contain the stack size need for the main thread. 1414 | */ 1415 | struct entry_point_command { 1416 | uint32_t cmd; /* LC_MAIN only used in MH_EXECUTE filetypes */ 1417 | uint32_t cmdsize; /* 24 */ 1418 | uint64_t entryoff; /* file (__TEXT) offset of main() */ 1419 | uint64_t stacksize;/* if not zero, initial stack size */ 1420 | }; 1421 | 1422 | 1423 | /* 1424 | * The source_version_command is an optional load command containing 1425 | * the version of the sources used to build the binary. 1426 | */ 1427 | struct source_version_command { 1428 | uint32_t cmd; /* LC_SOURCE_VERSION */ 1429 | uint32_t cmdsize; /* 16 */ 1430 | uint64_t version; /* A.B.C.D.E packed as a24.b10.c10.d10.e10 */ 1431 | }; 1432 | 1433 | 1434 | /* 1435 | * The LC_DATA_IN_CODE load commands uses a linkedit_data_command 1436 | * to point to an array of data_in_code_entry entries. Each entry 1437 | * describes a range of data in a code section. 1438 | */ 1439 | struct data_in_code_entry { 1440 | uint32_t offset; /* from mach_header to start of data range*/ 1441 | uint16_t length; /* number of bytes in data range */ 1442 | uint16_t kind; /* a DICE_KIND_* value */ 1443 | }; 1444 | #define DICE_KIND_DATA 0x0001 1445 | #define DICE_KIND_JUMP_TABLE8 0x0002 1446 | #define DICE_KIND_JUMP_TABLE16 0x0003 1447 | #define DICE_KIND_JUMP_TABLE32 0x0004 1448 | #define DICE_KIND_ABS_JUMP_TABLE32 0x0005 1449 | 1450 | 1451 | 1452 | /* 1453 | * Sections of type S_THREAD_LOCAL_VARIABLES contain an array 1454 | * of tlv_descriptor structures. 1455 | */ 1456 | struct tlv_descriptor 1457 | { 1458 | void* (*thunk)(struct tlv_descriptor*); 1459 | unsigned long key; 1460 | unsigned long offset; 1461 | }; 1462 | 1463 | #endif /* _MACHO_LOADER_H_ */ 1464 | -------------------------------------------------------------------------------- /src/syscalltbl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Private Syscall 3 | */ 4 | const char * mach_syscall_name_table[128] = { 5 | /* 0 */ "kern_invalid", 6 | /* 1 */ "kern_invalid", 7 | /* 2 */ "kern_invalid", 8 | /* 3 */ "kern_invalid", 9 | /* 4 */ "kern_invalid", 10 | /* 5 */ "kern_invalid", 11 | /* 6 */ "kern_invalid", 12 | /* 7 */ "kern_invalid", 13 | /* 8 */ "kern_invalid", 14 | /* 9 */ "kern_invalid", 15 | /* 10 */ "_kernelrpc_mach_vm_allocate_trap", // OS X : "kern_invalid", 16 | /* 11 */ "_kernelrpc_vm_allocate_trap", // OS X : "kern_invalid", 17 | /* 12 */ "_kernelrpc_mach_vm_deallocate_trap", // OS X: "kern_invalid", 18 | /* 13 */ "_kernelrpc_vm_deallocate_trap" , // "kern_invalid", 19 | /* 14 */ "_kernelrpc_mach_vm_protect_trap", //"kern_invalid", 20 | /* 15 */ "_kernelrpc_vm_protect_trap", // kern_invalid", 21 | /* 16 */ "_kernelrpc_mach_port_allocate_trap", //"kern_invalid", 22 | /* 17 */ "_kernelrpc_mach_port_destroy_trap" ,//"kern_invalid", 23 | /* 18 */ "_kernelrpc_mach_port_deallocate_trap", // "kern_invalid", 24 | /* 19 */ "_kernelrpc_mach_port_mod_refs_trap", //"kern_invalid", 25 | /* 20 */ "_kernelrpc_mach_port_move_member_trap", //"kern_invalid", 26 | /* 21 */ "_kernelrpc_mach_port_insert_right_trap", //"kern_invalid", 27 | /* 22 */ "_kernelrpc_mach_port_insert_member_trap", // "kern_invalid", 28 | /* 23 */ "_kernelrpc_mach_port_extract_member_trap", // "kern_invalid", 29 | /* 24 */ "kern_invalid", 30 | /* 25 */ "kern_invalid", 31 | /* 26 */ "mach_reply_port", 32 | /* 27 */ "thread_self_trap", 33 | /* 28 */ "task_self_trap", 34 | /* 29 */ "host_self_trap", 35 | /* 30 */ "kern_invalid", 36 | /* 31 */ "mach_msg_trap", 37 | /* 32 */ "mach_msg_overwrite_trap", 38 | /* 33 */ "semaphore_signal_trap", 39 | /* 34 */ "semaphore_signal_all_trap", 40 | /* 35 */ "semaphore_signal_thread_trap", 41 | /* 36 */ "semaphore_wait_trap", 42 | /* 37 */ "semaphore_wait_signal_trap", 43 | /* 38 */ "semaphore_timedwait_trap", 44 | /* 39 */ "semaphore_timedwait_signal_trap", 45 | /* 40 */ "kern_invalid", 46 | /* 41 */ "kern_invalid", 47 | /* 42 */ "kern_invalid", 48 | /* 43 */ "map_fd", 49 | /* 44 */ "task_name_for_pid", 50 | /* 45 */ "task_for_pid", 51 | /* 46 */ "pid_for_task", 52 | /* 47 */ "kern_invalid", 53 | /* 48 */ "macx_swapon", 54 | /* 49 */ "macx_swapoff", 55 | /* 50 */ "kern_invalid", 56 | /* 51 */ "macx_triggers", 57 | /* 52 */ "macx_backing_store_suspend", 58 | /* 53 */ "macx_backing_store_recovery", 59 | /* 54 */ "kern_invalid", 60 | /* 55 */ "kern_invalid", 61 | /* 56 */ "kern_invalid", 62 | /* 57 */ "kern_invalid", 63 | /* 58 */ "pfz_exit", 64 | /* 59 */ "swtch_pri", 65 | /* 60 */ "swtch", 66 | /* 61 */ "thread_switch", 67 | /* 62 */ "clock_sleep_trap", 68 | /* 63 */ "kern_invalid", 69 | /* traps 64 - 95 reserved (debo) */ 70 | /* 64 */ "kern_invalid", 71 | /* 65 */ "kern_invalid", 72 | /* 66 */ "kern_invalid", 73 | /* 67 */ "kern_invalid", 74 | /* 68 */ "kern_invalid", 75 | /* 69 */ "kern_invalid", 76 | /* 70 */ "kern_invalid", 77 | /* 71 */ "kern_invalid", 78 | /* 72 */ "kern_invalid", 79 | /* 73 */ "kern_invalid", 80 | /* 74 */ "kern_invalid", 81 | /* 75 */ "kern_invalid", 82 | /* 76 */ "kern_invalid", 83 | /* 77 */ "kern_invalid", 84 | /* 78 */ "kern_invalid", 85 | /* 79 */ "kern_invalid", 86 | /* 80 */ "kern_invalid", 87 | /* 81 */ "kern_invalid", 88 | /* 82 */ "kern_invalid", 89 | /* 83 */ "kern_invalid", 90 | /* 84 */ "kern_invalid", 91 | /* 85 */ "kern_invalid", 92 | /* 86 */ "kern_invalid", 93 | /* 87 */ "kern_invalid", 94 | /* 88 */ "kern_invalid", 95 | /* 89 */ "mach_timebase_info_trap", 96 | /* 90 */ "mach_wait_until_trap", 97 | /* 91 */ "mk_timer_create_trap", 98 | /* 92 */ "mk_timer_destroy_trap", 99 | /* 93 */ "mk_timer_arm_trap", 100 | /* 94 */ "mk_timer_cancel_trap", 101 | /* 95 */ "kern_invalid", 102 | /* traps 64 - 95 reserved (debo) */ 103 | /* 96 */ "kern_invalid", 104 | /* 97 */ "kern_invalid", 105 | /* 98 */ "kern_invalid", 106 | /* 99 */ "kern_invalid", 107 | /* traps 100-107 reserved for iokit (esb) */ 108 | /* 100 */ "kern_invalid", 109 | /* 100 */ //"iokit_user_client_trap", 110 | /* 101 */ "kern_invalid", 111 | /* 102 */ "kern_invalid", 112 | /* 103 */ "kern_invalid", 113 | /* 104 */ "kern_invalid", 114 | /* 105 */ "kern_invalid", 115 | /* 106 */ "kern_invalid", 116 | /* 107 */ "kern_invalid", 117 | /* traps 108-127 unused */ 118 | /* 108 */ "kern_invalid", 119 | /* 109 */ "kern_invalid", 120 | /* 110 */ "kern_invalid", 121 | /* 111 */ "kern_invalid", 122 | /* 112 */ "kern_invalid", 123 | /* 113 */ "kern_invalid", 124 | /* 114 */ "kern_invalid", 125 | /* 115 */ "kern_invalid", 126 | /* 116 */ "kern_invalid", 127 | /* 117 */ "kern_invalid", 128 | /* 118 */ "kern_invalid", 129 | /* 119 */ "kern_invalid", 130 | /* 120 */ "kern_invalid", 131 | /* 121 */ "kern_invalid", 132 | /* 122 */ "kern_invalid", 133 | /* 123 */ "kern_invalid", 134 | /* 124 */ "kern_invalid", 135 | /* 125 */ "kern_invalid", 136 | /* 126 */ "kern_invalid", 137 | /* 127 */ "kern_invalid", 138 | }; 139 | 140 | 141 | /* 142 | * Posix syscall 143 | */ 144 | #define SYS_MAXSYSCALL 443 145 | #define SYS_MAXSYSCALL_7 454 146 | 147 | char *syscall_names[] = { 148 | "syscall", /* 0 */ 149 | "exit", 150 | "fork", 151 | "read", 152 | "write", 153 | "open", 154 | "close", 155 | "wait4", 156 | "8 old creat", 157 | "link", 158 | "unlink", /* 10 */ 159 | "11 old execv", 160 | "chdir", 161 | "fchdir", 162 | "mknod", 163 | "chmod", 164 | "chown", 165 | "17 old break", 166 | "getfsstat", 167 | "19 old lseek", 168 | "getpid", /* 20 */ 169 | "21 old mount", 170 | "22 old umount", 171 | "setuid", 172 | "getuid", 173 | "geteuid", 174 | "ptrace", 175 | "recvmsg", 176 | "sendmsg", 177 | "recvfrom", 178 | "accept", /* 30 */ 179 | "getpeername", 180 | "getsockname", 181 | "access", 182 | "chflags", 183 | "fchflags", 184 | "sync", 185 | "kill", 186 | "38 old stat", 187 | "getppid", 188 | "40 old lstat", /* 40 */ 189 | "dup", 190 | "pipe", 191 | "getegid", 192 | "profil", 193 | "45 old ktrace", 194 | "sigaction", 195 | "getgid", 196 | "sigprocmask", 197 | "getlogin", 198 | "setlogin", /* 50 */ 199 | "acct", 200 | "sigpending", 201 | "sigaltstack", 202 | "ioctl", 203 | "reboot", 204 | "revoke", 205 | "symlink", 206 | "readlink", 207 | "execve", 208 | "umask", /* 60 */ 209 | "chroot", 210 | "62 old fstat", 211 | "63 used internally , reserved", 212 | "64 old getpagesize", 213 | "msync", 214 | "vfork", 215 | "67 old vread", 216 | "68 old vwrite", 217 | "69 old sbrk", 218 | "70 old sstk", /* 70 */ 219 | "71 old mmap", 220 | "72 old vadvise", 221 | "munmap", 222 | "mprotect", 223 | "madvise", 224 | "76 old vhangup", 225 | "77 old vlimit", 226 | "mincore", 227 | "getgroups", 228 | "setgroups", /* 80 */ 229 | "getpgrp", 230 | "setpgid", 231 | "setitimer", 232 | "84 old wait", 233 | "swapon", 234 | "getitimer", 235 | "87 old gethostname", 236 | "88 old sethostname", 237 | "getdtablesize", 238 | "dup2", /* 90 */ 239 | "91 old getdopt", 240 | "fcntl", 241 | "select", 242 | "94 old setdopt", 243 | "fsync", 244 | "setpriority", 245 | "socket", 246 | "connect", 247 | "99 old accept", 248 | "getpriority", /* 100 */ 249 | "101 old send", 250 | "102 old recv", 251 | "103 old sigreturn", 252 | "bind", 253 | "setsockopt", 254 | "listen", 255 | "107 old vtimes", 256 | "108 old sigvec", 257 | "109 old sigblock", 258 | "110 old sigsetmask", /* 110 */ 259 | "sigsuspend", 260 | "112 old sigstack", 261 | "113 old recvmsg", 262 | "114 old sendmsg", 263 | "115 old vtrace", 264 | "gettimeofday", 265 | "getrusage", 266 | "getsockopt", 267 | "119 old resuba", 268 | "readv", /* 120 */ 269 | "writev", 270 | "settimeofday", 271 | "fchown", 272 | "fchmod", 273 | "125 old recvfrom", 274 | "setreuid", 275 | "setregid", 276 | "rename", 277 | "129 old truncate", 278 | "130 old ftruncate", /* 130 */ 279 | "flock", 280 | "mkfifo", 281 | "sendto", 282 | "shutdown", 283 | "socketpair", 284 | "mkdir", 285 | "rmdir", 286 | "utimes", 287 | "futimes", 288 | "adjtime", /* 140 */ 289 | "141 old getpeername", 290 | "gethostuuid", 291 | "143 old sethostid", 292 | "144 old getrlimit", 293 | "145 old setrlimit", 294 | "146 old killpg", 295 | "setsid", 296 | "148 old setquota", 297 | "149 old qquota", 298 | "150 old getsockname", /* 150 */ 299 | "getpgid", 300 | "setprivexec", 301 | "pread", 302 | "pwrite", 303 | "nfssvc", 304 | "156 old getdirentries", 305 | "statfs", 306 | "fstatfs", 307 | "unmount", 308 | "160 old async_daemon", /* 160 */ 309 | "getfh", 310 | "162 old getdomainname", 311 | "163 old setdomainname", 312 | "164", 313 | "quotactl", 314 | "166 old exportfs", 315 | "mount", 316 | "168 old ustat", 317 | "csops", 318 | "csops_audittoken", /* 170 */ 319 | "171 old wait3", 320 | "172 old rpause", 321 | "waitid", 322 | "174 old getdents", 323 | "175 old gc_control", 324 | "add_profil", 325 | "177", 326 | "178", 327 | "179", 328 | "kdebug_trace", /* 180 */ 329 | "setgid", 330 | "setegid", 331 | "seteuid", 332 | "sigreturn", 333 | "chud", 334 | "186", 335 | "fdatasync", 336 | "stat", 337 | "fstat", 338 | "lstat", /* 190 */ 339 | "pathconf", 340 | "fpathconf", 341 | "193", 342 | "getrlimit", 343 | "setrlimit", 344 | "getdirentries", 345 | "mmap", 346 | "198 __syscall", 347 | "lseek", 348 | "truncate", /* 200 */ 349 | "ftruncate", 350 | "__sysctl", 351 | "mlock", 352 | "munlock", 353 | "undelete", 354 | "ATsocket", 355 | "ATgetmsg", 356 | "ATputmsg", 357 | "ATPsndreq", 358 | "ATPsndrsp", /* 210 */ 359 | "ATPgetreq", 360 | "ATPgetrsp", 361 | "213 Reserved for AppleTalk", 362 | "214", 363 | "215", 364 | "mkcomplex", 365 | "statv", 366 | "lstatv", 367 | "fstatv", 368 | "getattrlist", /* 220 */ 369 | "setattrlist", 370 | "getdirentriesattr", 371 | "exchangedata", 372 | "224 old checkuseraccess / fsgetpath ( which moved to 427 )", 373 | "searchfs", 374 | "delete", 375 | "copyfile", 376 | "fgetattrlist", 377 | "fsetattrlist", 378 | "poll", /* 230 */ 379 | "watchevent", 380 | "waitevent", 381 | "modwatch", 382 | "getxattr", 383 | "fgetxattr", 384 | "setxattr", 385 | "fsetxattr", 386 | "removexattr", 387 | "fremovexattr", 388 | "listxattr", /* 240 */ 389 | "flistxattr", 390 | "fsctl", 391 | "initgroups", 392 | "posix_spawn", 393 | "ffsctl", 394 | "246", 395 | "nfsclnt", 396 | "fhopen", 397 | "249", 398 | "minherit", /* 250 */ 399 | "semsys", 400 | "msgsys", 401 | "shmsys", 402 | "semctl", 403 | "semget", 404 | "semop", 405 | "257", 406 | "msgctl", 407 | "msgget", 408 | "msgsnd", /* 260 */ 409 | "msgrcv", 410 | "shmat", 411 | "shmctl", 412 | "shmdt", 413 | "shmget", 414 | "shm_open", 415 | "shm_unlink", 416 | "sem_open", 417 | "sem_close", 418 | "sem_unlink", /* 270 */ 419 | "sem_wait", 420 | "sem_trywait", 421 | "sem_post", 422 | "sem_getvalue", 423 | "sem_init", 424 | "sem_destroy", 425 | "open_extended", 426 | "umask_extended", 427 | "stat_extended", 428 | "lstat_extended", /* 280 */ 429 | "fstat_extended", 430 | "chmod_extended", 431 | "fchmod_extended", 432 | "access_extended", 433 | "settid", 434 | "gettid", 435 | "setsgroups", 436 | "getsgroups", 437 | "setwgroups", 438 | "getwgroups", /* 290 */ 439 | "mkfifo_extended", 440 | "mkdir_extended", 441 | "identitysvc", 442 | "shared_region_check_np", 443 | "shared_region_map_np", 444 | "vm_pressure_monitor", 445 | "psynch_rw_longrdlock", 446 | "psynch_rw_yieldwrlock", 447 | "psynch_rw_downgrade", 448 | "psynch_rw_upgrade", /* 300 */ 449 | "psynch_mutexwait", 450 | "psynch_mutexdrop", 451 | "psynch_cvbroad", 452 | "psynch_cvsignal", 453 | "psynch_cvwait", 454 | "psynch_rw_rdlock", 455 | "psynch_rw_wrlock", 456 | "psynch_rw_unlock", 457 | "psynch_rw_unlock2", 458 | "getsid", /* 310 */ 459 | "settid_with_pid", 460 | "psynch_cvclrprepost", 461 | "aio_fsync", 462 | "aio_return", 463 | "aio_suspend", 464 | "aio_cancel", 465 | "aio_error", 466 | "aio_read", 467 | "aio_write", 468 | "lio_listio", /* 320 */ 469 | "321 old __pthread_cond_wait", 470 | "iopolicysys", 471 | "process_policy", 472 | "mlockall", 473 | "munlockall", 474 | "326", 475 | "issetugid", 476 | "__pthread_kill", 477 | "__pthread_sigmask", 478 | "__sigwait", /* 330 */ 479 | "__disable_threadsignal", 480 | "__pthread_markcancel", 481 | "__pthread_canceled", 482 | "__semwait_signal", 483 | "335 old utrace", 484 | "proc_info", 485 | "sendfile", 486 | "stat64", 487 | "fstat64", 488 | "lstat64", /* 340 */ 489 | "stat64_extended", 490 | "lstat64_extended", 491 | "fstat64_extended", 492 | "getdirentries64", 493 | "statfs64", 494 | "fstatfs64", 495 | "getfsstat64", 496 | "__pthread_chdir", 497 | "__pthread_fchdir", 498 | "audit", /* 350 */ 499 | "auditon", 500 | "352", 501 | "getauid", 502 | "setauid", 503 | "getaudit", 504 | "setaudit", 505 | "getaudit_addr", 506 | "setaudit_addr", 507 | "auditctl", 508 | "bsdthread_create", /* 360 */ 509 | "bsdthread_terminate", 510 | "kqueue", 511 | "kevent", 512 | "lchown", 513 | "stack_snapshot", 514 | "bsdthread_register", 515 | "workq_open", 516 | "workq_kernreturn", 517 | "kevent64", 518 | "__old_semwait_signal", /* 370 */ 519 | "__old_semwait_signal_nocancel", 520 | "thread_selfid", 521 | "ledger", 522 | "374", 523 | "375", 524 | "376", 525 | "377", 526 | "378", 527 | "379", 528 | "__mac_execve", /* 380 */ 529 | "__mac_syscall", 530 | "__mac_get_file", 531 | "__mac_set_file", 532 | "__mac_get_link", 533 | "__mac_set_link", 534 | "__mac_get_proc", 535 | "__mac_set_proc", 536 | "__mac_get_fd", 537 | "__mac_set_fd", 538 | "__mac_get_pid", /* 390 */ 539 | "__mac_get_lcid", 540 | "__mac_get_lctx", 541 | "__mac_set_lctx", 542 | "setlcid", 543 | "getlcid", 544 | "read_nocancel", 545 | "write_nocancel", 546 | "open_nocancel", 547 | "close_nocancel", 548 | "wait4_nocancel", /* 400 */ 549 | "recvmsg_nocancel", 550 | "sendmsg_nocancel", 551 | "recvfrom_nocancel", 552 | "accept_nocancel", 553 | "msync_nocancel", 554 | "fcntl_nocancel", 555 | "select_nocancel", 556 | "fsync_nocancel", 557 | "connect_nocancel", 558 | "sigsuspend_nocancel", /* 410 */ 559 | "readv_nocancel", 560 | "writev_nocancel", 561 | "sendto_nocancel", 562 | "pread_nocancel", 563 | "pwrite_nocancel", 564 | "waitid_nocancel", 565 | "poll_nocancel", 566 | "msgsnd_nocancel", 567 | "msgrcv_nocancel", 568 | "sem_wait_nocancel", /* 420 */ 569 | "aio_suspend_nocancel", 570 | "__sigwait_nocancel", 571 | "__semwait_signal_nocancel", 572 | "__mac_mount", 573 | "__mac_get_mount", 574 | "__mac_getfsstat", 575 | "fsgetpath", 576 | "audit_session_self", 577 | "audit_session_join", 578 | "fileport_makeport", /* 430 */ 579 | "fileport_makefd", 580 | "audit_session_port", 581 | "pid_suspend", 582 | "pid_resume", 583 | "pid_hibernate", 584 | "pid_shutdown_sockets", 585 | "437 old shared_region_slide_np", 586 | "shared_region_map_and_slide_np" , 587 | "kas_info", 588 | "memorystatus_control", /*440 */ 589 | "guarded_open_np", 590 | "guarded_close_np", 591 | "guarded_kqueue_np", /* 443 */ 592 | "change_fdguard_np", 593 | "old __proc_suppress", 594 | "proc_rlimit_control", 595 | "proc_connectx", 596 | "proc_disconnectx", 597 | "proc_peeloff", 598 | "proc_socket_delegate", /* 450 */ 599 | "proc_telemetry", 600 | "proc_uuid_policy", 601 | "memorystatus_get_level", /* 453 */ 602 | NULL 603 | }; 604 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "utils.h" 4 | 5 | FILE *open_file(char *name, int *size) 6 | { 7 | FILE *fp; 8 | fp = fopen(name, "rb"); 9 | if(fp==NULL){ 10 | perror("open_file"); 11 | return NULL; 12 | } 13 | fseek(fp, 0, SEEK_END); 14 | *size = ftell(fp); 15 | fseek(fp, 0, SEEK_SET); 16 | return fp; 17 | } 18 | 19 | u8 *load_file(char *name, int *size) 20 | { 21 | FILE *fp; 22 | u8 *buf; 23 | fp = open_file(name, size); 24 | if(fp==NULL) 25 | return NULL; 26 | buf = malloc(*size); 27 | fread(buf, *size, 1, fp); 28 | fclose(fp); 29 | return buf; 30 | } 31 | 32 | int save_file(char *name, void *buf, int size) 33 | { 34 | FILE *fp; 35 | fp = fopen(name, "wb"); 36 | if(fp==NULL){ 37 | printf("Open file %s failed!\n", name); 38 | return -1; 39 | } 40 | fwrite(buf, size, 1, fp); 41 | fclose(fp); 42 | return 0; 43 | } 44 | 45 | void hex_dump(char *str, void *buf, int size) 46 | { 47 | int i; 48 | u8 *ubuf = buf; 49 | 50 | if(str) 51 | printf("%s:", str); 52 | 53 | for(i=0; i