├── .gitignore ├── Info.plist ├── Makefile ├── README.md ├── asm_repl.c ├── assemble.c ├── assemble.h ├── colors.h ├── float_registers.h ├── mach_exc ├── mach_exc.h ├── mach_excServer.c └── mach_excUser.c ├── registers.h ├── status_flags.h ├── taskport_auth.c ├── taskport_auth.h ├── utils.c └── utils.h /.gitignore: -------------------------------------------------------------------------------- 1 | asm_repl 2 | -------------------------------------------------------------------------------- /Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.tyilo.asm_repl 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | asm_repl 13 | CFBundleVersion 14 | 1.0 15 | SecTaskAccess 16 | 17 | allowed 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | sdk = $(shell xcodebuild -sdk -version | grep '^Path: .*MacOSX10.10' | awk '{print $$2}') 2 | CERTNAME=task_for_pid 3 | 4 | all: 5 | @$(CC) -arch i386 -arch x86_64 $(wildcard *.c mach_exc/*.c) -ledit -framework Security -o asm_repl -sectcreate __TEXT __info_plist Info.plist 6 | @if ! codesign -s $(CERTNAME) asm_repl; then \ 7 | echo "WARNING:"; \ 8 | echo "You don't have a certificate named $(CERTNAME)."; \ 9 | echo "If you want to run asm_repl without root,"; \ 10 | echo "create a certificate named $(CERTNAME) using the guide here: "; \ 11 | echo "https://gcc.gnu.org/onlinedocs/gnat_ugn/Codesigning-the-Debugger.html"; \ 12 | fi 13 | @rm -rf _CodeSignature 14 | 15 | 16 | clean: 17 | rm -f asm_repl 18 | 19 | run64: all 20 | @arch -64 ./asm_repl 21 | 22 | run32: all 23 | @arch -32 ./asm_repl 24 | 25 | mach_exc: 26 | mkdir -p mach_exc; \ 27 | cd mach_exc; \ 28 | mig "$(sdk)/usr/include/mach/mach_exc.defs" 29 | 30 | scan: 31 | scan-build make CFLAGS='-isysroot $(sdk)' 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # asm_repl 2 | A [REPL](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) for assembly. 3 | 4 | Type some assembly instructions and immediatly see which registers were changed. 5 | 6 | Currently only supports i386 and x86_64 on OS X. 7 | 8 | Screenshot 9 | == 10 | [![Screenshot x86_64](http://i.imgur.com/Eb8Bz15.png)](http://i.imgur.com/Eb8Bz15.png) 11 | 12 | Also see [https://asciinema.org/a/19605](https://asciinema.org/a/19605). 13 | 14 | Running 15 | == 16 | 17 | * Install [radare2](https://github.com/radare/radare2). 18 | * `make` 19 | * `./asm_repl` (`make run32` or `make run64` to choose a specific architecture) 20 | 21 | You need to codesign `asm_repl` binary or run it as root as we have to access the process we're running the assembly code in. You can codesign the binary so it can use `task_for_pid` without root by creating a certificate named `task_for_pid` using the guide [here](https://gcc.gnu.org/onlinedocs/gnat_ugn/Codesigning-the-Debugger.html) and then running `make`. 22 | 23 | Commands 24 | == 25 | 26 | ``` 27 | Valid input: 28 | Help: 29 | ? - show this help 30 | ?[cmd] - show help for a command 31 | 32 | Commands: 33 | .set - change value of register 34 | .read - read from memory 35 | .write - write hex to memory 36 | .writestr - write string to memory 37 | .alloc - allocate memory 38 | .regs - show the contents of the registers 39 | .show - toggle shown register types 40 | 41 | Any other input will be interpreted as x86_64 assembly 42 | ``` 43 | 44 | `.set` 45 | -- 46 | 47 | ``` 48 | Usage: .set register value 49 | Changes the value of a register 50 | 51 | register - register name (GPR, FPR or status) 52 | value - hex if GPR or FPR, 0 or 1 if status 53 | ``` 54 | 55 | `.read` 56 | -- 57 | 58 | ``` 59 | Usage: .read address [len] 60 | Displays a hexdump of memory starting at address 61 | 62 | address - an integer or a register name 63 | len - the amount of bytes to read 64 | ``` 65 | 66 | `.write` 67 | -- 68 | 69 | ``` 70 | Usage: .write address hexpairs 71 | Writes hexpairs to a destination address 72 | 73 | address - an integer or a register name 74 | hexpairs - pairs of hexadecimal numbers 75 | ``` 76 | 77 | `.writestr` 78 | -- 79 | 80 | ``` 81 | Usage: .writestr address string 82 | Writes an ascii string to a destination address 83 | 84 | address - an integer or a register name 85 | string - an ascii string 86 | ``` 87 | 88 | `.alloc` 89 | -- 90 | 91 | ``` 92 | Usage: .alloc len 93 | Allocates some memory and returns the address 94 | 95 | len - the amount of bytes to allocate 96 | ``` 97 | 98 | `.regs` 99 | -- 100 | 101 | ``` 102 | Usage: .regs 103 | Displays the values of the registers currently toggled on 104 | ``` 105 | 106 | `.show` 107 | -- 108 | 109 | ``` 110 | Usage: .show [gpr|status|fpr_hex|fpr_double] 111 | Toggles which types of registers are shown 112 | 113 | gpr - General purpose registers (rax, rsp, rip, ...) 114 | status - Status registers (CF, ZF, ...) 115 | fpr_hex - Floating point registers shown in hex (xmm0, xmm1, ...) 116 | fpr_double - Floating point registers shown as doubles 117 | ``` 118 | 119 | Todo 120 | == 121 | 122 | * Use a library (libr?) for assembling instead of reading the output of running `rasm2`. 123 | * Support more architectures (arm). 124 | * Support more platforms (linux). 125 | * Arithmetic for commands (`.read rip-0x10`). 126 | * Variables to specific memory addresses (`.alloc 4` => `.write $alloc 12345678`). 127 | -------------------------------------------------------------------------------- /asm_repl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "taskport_auth.h" 15 | 16 | #include "assemble.h" 17 | #include "colors.h" 18 | #include "utils.h" 19 | 20 | #include "registers.h" 21 | #include "float_registers.h" 22 | #include "status_flags.h" 23 | 24 | extern boolean_t mach_exc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); 25 | 26 | typedef union { 27 | uint32_t eflags; 28 | uint64_t rflags; 29 | struct __attribute__((packed)) { 30 | uint8_t CF :1; 31 | uint8_t _res1 :1; 32 | uint8_t PF :1; 33 | uint8_t _res2 :1; 34 | uint8_t AF :1; 35 | uint8_t _res3 :1; 36 | uint8_t ZF :1; 37 | uint8_t SF :1; 38 | uint8_t TF :1; 39 | uint8_t IF :1; 40 | uint8_t DF :1; 41 | uint8_t OF :1; 42 | uint8_t IOPL :2; 43 | uint8_t NT :1; 44 | uint8_t _res4 :1; 45 | 46 | uint8_t RF :1; 47 | uint8_t VM :1; 48 | uint8_t AC :1; 49 | uint8_t VIF :1; 50 | uint8_t VIP :1; 51 | uint8_t ID :1; 52 | 53 | uint16_t _res5 :10; 54 | 55 | uint32_t _res6 :32; 56 | }; 57 | } x86_flags_t; 58 | 59 | #if defined(__i386__) 60 | 61 | #define BITS 32 62 | #define ARCH_NAME "i386" 63 | 64 | #define ts ts32 65 | #define fs fs32 66 | 67 | typedef uint32_t gpr_register_t; 68 | #define REGISTER_FORMAT_DEC "%" PRIu32 69 | #define REGISTER_FORMAT_HEX "%" PRIX32 70 | #define REGISTER_FORMAT_HEX_PADDED "%08" PRIX32 71 | 72 | #define pc_register __eip 73 | #define flags_register __eflags 74 | 75 | #define IF32(X, Y) X 76 | 77 | #elif defined(__x86_64__) 78 | 79 | #define BITS 64 80 | #define ARCH_NAME "x86_64" 81 | 82 | #define ts ts64 83 | #define fs fs64 84 | 85 | typedef uint64_t gpr_register_t; 86 | #define REGISTER_FORMAT_DEC "%" PRIu64 87 | #define REGISTER_FORMAT_HEX "%" PRIX64 88 | #define REGISTER_FORMAT_HEX_PADDED "%016" PRIX64 89 | 90 | #define pc_register __rip 91 | #define flags_register __rflags 92 | 93 | #define IF32(X, Y) Y 94 | 95 | #else 96 | #error Unsupported architecture 97 | #endif 98 | 99 | #define ISGRAPH(c) (((unsigned char)c) <= 127 && isgraph(c)) 100 | 101 | typedef union { 102 | _STRUCT_XMM_REG bytes; 103 | double doubles[2]; 104 | float floats[4]; 105 | uint64_t ints[2]; 106 | } xmm_value_t; 107 | 108 | pthread_mutex_t mutex; 109 | 110 | #define MEMORY_SIZE 0x10000 111 | #define INT3 0xCC 112 | 113 | #define ELEMENTS(x) (sizeof(x) / sizeof(*x)) 114 | 115 | #define LIST(x, ...) x, 116 | #define STR_LIST(x, ...) #x, 117 | #define LIST2(x, y, ...) y, 118 | 119 | #define STD_FAIL(s, x) do { \ 120 | int ret = (x); \ 121 | if(ret != 0) { \ 122 | perror(s "()"); \ 123 | exit(ret); \ 124 | } \ 125 | } while(false) 126 | 127 | #define KERN_FAIL(s, x) do { \ 128 | kern_return_t ret = (x); \ 129 | if(ret != KERN_SUCCESS) { \ 130 | printf(s "() failed: %s\n", mach_error_string(ret)); \ 131 | exit(ret); \ 132 | } \ 133 | } while(false) 134 | 135 | #define KERN_TRY(s, x, f) if(true) { \ 136 | kern_return_t ret = (x); \ 137 | if(ret != KERN_SUCCESS) { \ 138 | printf(s "() failed: %s\n", mach_error_string(ret)); \ 139 | f \ 140 | } \ 141 | } else do {} while(0) 142 | 143 | void get_thread_state(thread_act_t thread, x86_thread_state_t *state) { 144 | mach_msg_type_number_t stateCount = x86_THREAD_STATE_COUNT; 145 | KERN_FAIL("thread_get_state", thread_get_state(thread, x86_THREAD_STATE, (thread_state_t)state, &stateCount)); 146 | } 147 | 148 | void set_thread_state(thread_act_t thread, x86_thread_state_t *state) { 149 | KERN_FAIL("thread_set_state", thread_set_state(thread, x86_THREAD_STATE, (thread_state_t)state, x86_THREAD_STATE_COUNT)); 150 | } 151 | 152 | void get_float_state(thread_act_t thread, x86_float_state_t *state) { 153 | mach_msg_type_number_t stateCount = x86_FLOAT_STATE_COUNT; 154 | KERN_FAIL("thread_get_state", thread_get_state(thread, x86_FLOAT_STATE, (thread_state_t)state, &stateCount)); 155 | } 156 | 157 | void set_float_state(thread_act_t thread, x86_float_state_t *state) { 158 | KERN_FAIL("thread_set_state", thread_set_state(thread, x86_FLOAT_STATE, (thread_state_t)state, x86_FLOAT_STATE_COUNT)); 159 | } 160 | 161 | gpr_register_t get_pc(thread_act_t thread) { 162 | x86_thread_state_t state; 163 | get_thread_state(thread, &state); 164 | return state.uts.ts.pc_register; 165 | } 166 | 167 | void set_pc(thread_act_t thread, gpr_register_t pc_value) { 168 | x86_thread_state_t state; 169 | get_thread_state(thread, &state); 170 | state.uts.ts.pc_register = pc_value; 171 | set_thread_state(thread, &state); 172 | } 173 | 174 | void write_int3(task_t task, mach_vm_address_t address) { 175 | unsigned char int3 = INT3; 176 | KERN_FAIL("mach_vm_write", mach_vm_write(task, address, (vm_offset_t)&int3, sizeof(int3))); 177 | } 178 | 179 | void setup_child(task_t task, thread_act_t *_thread, mach_vm_address_t *_memory) { 180 | thread_act_array_t thread_list; 181 | mach_msg_type_number_t thread_count; 182 | KERN_FAIL("task_threads", task_threads(task, &thread_list, &thread_count)); 183 | 184 | if(thread_count != 1) { 185 | printf("1 thread expected, got %d.\n", thread_count); 186 | exit(KERN_FAILURE); 187 | } 188 | 189 | thread_act_t thread = thread_list[0]; 190 | *_thread = thread; 191 | 192 | mach_vm_address_t memory; 193 | KERN_FAIL("mach_vm_allocate", mach_vm_allocate(task, &memory, MEMORY_SIZE, VM_FLAGS_ANYWHERE)); 194 | *_memory = memory; 195 | 196 | KERN_FAIL("mach_vm_protect", mach_vm_protect(task, memory, MEMORY_SIZE, 0, VM_PROT_ALL)); 197 | 198 | write_int3(task, memory); 199 | 200 | set_pc(thread, memory); 201 | } 202 | 203 | // Start of the exception handler thread 204 | void *exception_handler_main(void *arg) { 205 | mach_port_t exception_port = (mach_port_t)arg; 206 | if(mach_msg_server(mach_exc_server, 2048, exception_port, MACH_MSG_TIMEOUT_NONE) != MACH_MSG_SUCCESS) { 207 | puts("error: mach_msg_server()"); 208 | exit(1); 209 | } 210 | 211 | return NULL; 212 | } 213 | 214 | kern_return_t catch_mach_exception_raise_state(mach_port_t __unused exception_port, exception_type_t __unused exception, exception_data_t __unused code, mach_msg_type_number_t __unused code_count, int * __unused flavor, thread_state_t __unused in_state, mach_msg_type_number_t __unused in_state_count, thread_state_t __unused out_state, mach_msg_type_number_t * __unused out_state_count) { 215 | return KERN_FAILURE; 216 | } 217 | 218 | kern_return_t catch_mach_exception_raise_state_identity(mach_port_t __unused exception_port, mach_port_t __unused thread, mach_port_t __unused task, exception_type_t __unused exception, exception_data_t __unused code, mach_msg_type_number_t __unused code_count, int * __unused flavor, thread_state_t __unused in_state, mach_msg_type_number_t __unused in_state_count, thread_state_t __unused out_state, mach_msg_type_number_t * __unused out_state_count) { 219 | return KERN_FAILURE; 220 | } 221 | 222 | // Called when an exception is caught from the child, e.g. SIGTRAP 223 | kern_return_t catch_mach_exception_raise(mach_port_t __unused exception_port, mach_port_t thread, mach_port_t __unused task, exception_type_t exception, exception_data_t __unused code, mach_msg_type_number_t __unused code_count) { 224 | if(exception == EXC_BREAKPOINT) { 225 | KERN_FAIL("task_suspend", task_suspend(task)); 226 | set_pc(thread, get_pc(thread) - 1); 227 | pthread_mutex_unlock(&mutex); 228 | return KERN_SUCCESS; 229 | } else { 230 | return KERN_FAILURE; 231 | } 232 | } 233 | 234 | void setup_exception_handler(task_t task) { 235 | mach_port_t exception_port; 236 | KERN_FAIL("mach_port_allocate", mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &exception_port)); 237 | KERN_FAIL("mach_port_insert_right", mach_port_insert_right(mach_task_self(), exception_port, exception_port, MACH_MSG_TYPE_MAKE_SEND)); 238 | KERN_FAIL("task_set_exception_port", task_set_exception_ports(task, EXC_MASK_BREAKPOINT, exception_port, (exception_behavior_t)(EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES), MACHINE_THREAD_STATE)); 239 | 240 | pthread_t exception_handler_thread; 241 | STD_FAIL("pthread_create", pthread_create(&exception_handler_thread, NULL, exception_handler_main, (void *)(uintptr_t)exception_port)); 242 | } 243 | 244 | #define FOREACH_TYPE(X) \ 245 | X(gpr, true) \ 246 | X(status, true) \ 247 | X(fpr_hex, false) \ 248 | X(fpr_double, false) 249 | 250 | typedef enum { 251 | FOREACH_TYPE(LIST) 252 | } register_type; 253 | 254 | char *register_type_names[] = { 255 | FOREACH_TYPE(STR_LIST) 256 | }; 257 | 258 | bool show_register_types[] = { 259 | FOREACH_TYPE(LIST2) 260 | }; 261 | 262 | void print_registers(x86_thread_state_t *state, x86_float_state_t *float_state) { 263 | puts(""); 264 | 265 | static x86_thread_state_t last_state; 266 | static x86_float_state_t last_float_state; 267 | static x86_flags_t last_flags; 268 | static bool first = true; 269 | 270 | if(show_register_types[fpr_double]) { 271 | #define X(r) do { \ 272 | xmm_value_t v = (xmm_value_t)float_state->ufs.fs.__fpu_ ## r; \ 273 | xmm_value_t l = (xmm_value_t)last_float_state.ufs.fs.__fpu_ ## r; \ 274 | bool c1 = !first && v.ints[0] != l.ints[0]; \ 275 | bool c2 = !first && v.ints[1] != l.ints[1]; \ 276 | printf(KGRN "%" IF32("4", "5") "s:" RESET " { %s%e" RESET ", %s%e" RESET " }\n", #r, c1? KRED: RESET, v.doubles[0], c2? KRED: RESET, v.doubles[1]); \ 277 | } while(false) 278 | FOREACH_FLOAT_REGISTER(X) 279 | #undef X 280 | } 281 | 282 | if(show_register_types[fpr_hex]) { 283 | #define X(r) do { \ 284 | xmm_value_t v = (xmm_value_t)float_state->ufs.fs.__fpu_ ## r; \ 285 | xmm_value_t l = (xmm_value_t)last_float_state.ufs.fs.__fpu_ ## r; \ 286 | bool c = !first && (v.ints[0] != l.ints[0] || v.ints[1] != l.ints[1]); \ 287 | printf(KGRN "%" IF32("4", "5") "s: %s%016" PRIX64 "%016" PRIX64 RESET "\n", #r, c? KRED: RESET, v.ints[0], v.ints[1]); \ 288 | } while(false) 289 | FOREACH_FLOAT_REGISTER(X) 290 | #undef X 291 | } 292 | 293 | if(show_register_types[gpr]) { 294 | int i = 0; 295 | int columns = IF32(4, 3); 296 | #define X(r) do { \ 297 | gpr_register_t v = state->uts.ts.__ ## r; \ 298 | bool c = !first && v != last_state.uts.ts.__ ## r; \ 299 | printf(KGRN "%3s: %s" REGISTER_FORMAT_HEX_PADDED RESET "%s", #r, c? KRED: RESET, v, (i % columns == columns - 1 || i == REGISTERS - 1)? "\n": " "); \ 300 | i++; \ 301 | } while(false) 302 | FOREACH_REGISTER(X) 303 | #undef X 304 | } 305 | 306 | x86_flags_t flags = (x86_flags_t)state->uts.ts.flags_register; 307 | 308 | if(show_register_types[status]) { 309 | printf(KBLU "Status:" KNRM); 310 | 311 | #define X(f) do { \ 312 | uint8_t v = flags.f; \ 313 | bool c = !first && v != last_flags.f; \ 314 | printf(" " KGRN "%s: %s%d" RESET, #f, c? KRED: RESET, v); \ 315 | } while(false) 316 | FOREACH_STATUS_FLAG(X) 317 | #undef X 318 | } 319 | 320 | puts(""); 321 | 322 | first = false; 323 | last_state = *state; 324 | last_float_state = *float_state; 325 | last_flags = flags; 326 | } 327 | 328 | gpr_register_t *get_gpr_pointer(char *name, x86_thread_state_t *state) { 329 | #define X(r) do { \ 330 | if(strcmp(name, #r) == 0) { \ 331 | return &(state->uts.ts.__ ## r); \ 332 | } \ 333 | } while(false) 334 | FOREACH_REGISTER(X) 335 | #undef X 336 | 337 | return NULL; 338 | } 339 | 340 | xmm_value_t *get_fpr_pointer(char *name, x86_float_state_t *float_state) { 341 | #define X(r) do { \ 342 | if(strcmp(name, #r) == 0) { \ 343 | return (xmm_value_t *)&(float_state->ufs.fs.__fpu_ ## r); \ 344 | } \ 345 | } while(false) 346 | FOREACH_FLOAT_REGISTER(X) 347 | #undef X 348 | 349 | return NULL; 350 | } 351 | 352 | bool get_number(char *str, gpr_register_t *val) { 353 | char *endptr; 354 | *val = strtoll(str, &endptr, 0); 355 | return *endptr == '\0'; 356 | } 357 | 358 | bool get_value(char *str, x86_thread_state_t *state, gpr_register_t *val) { 359 | if(get_number(str, val)) { 360 | return true; 361 | } 362 | 363 | gpr_register_t *gpr = get_gpr_pointer(str, state); 364 | if(gpr) { 365 | *val = *gpr; 366 | return true; 367 | } 368 | 369 | return false; 370 | } 371 | 372 | size_t count_tokens(char *str, char *seperators) { 373 | size_t i = 0; 374 | char *p = strdup(str); 375 | while(strsep(&p, seperators)) { 376 | i++; 377 | } 378 | free(p); 379 | return i; 380 | } 381 | 382 | char *histfile; 383 | bool waiting_for_input = false; 384 | jmp_buf prompt_jmp_buf; 385 | 386 | int syntax_type = 0; // 0 = intel, 1 = at&t 387 | 388 | void read_input(task_t task, thread_act_t thread, x86_thread_state_t *state, x86_float_state_t *float_state) { 389 | static char *line = NULL; 390 | while(true) { 391 | if(line) { 392 | free(line); 393 | } 394 | 395 | waiting_for_input = true; 396 | setjmp(prompt_jmp_buf); 397 | 398 | line = readline("> "); 399 | 400 | waiting_for_input = false; 401 | 402 | if(!line) { 403 | exit(0); 404 | } 405 | 406 | if(line[0] == '\0') { 407 | continue; 408 | } 409 | 410 | add_history(line); 411 | write_history(histfile); 412 | 413 | #define FOREACH_CMD(X) \ 414 | X(set) \ 415 | X(read) \ 416 | X(write) \ 417 | X(writestr) \ 418 | X(alloc) \ 419 | X(regs) \ 420 | X(show) \ 421 | X(syntax) 422 | typedef enum { 423 | FOREACH_CMD(LIST) 424 | } cmds; 425 | static char *cmd_names[] = { 426 | FOREACH_CMD(STR_LIST) 427 | }; 428 | 429 | static char *help[] = { 430 | "Usage: .set register value\n" 431 | "Changes the value of a register\n" 432 | "\n" 433 | " register - register name (GPR, FPR or status)\n" 434 | " value - hex if GPR or FPR, 0 or 1 if status", 435 | 436 | "Usage: .read address [len]\n" 437 | "Displays a hexdump of memory starting at address\n" 438 | "\n" 439 | " address - an integer or a register name\n" 440 | " len - the amount of bytes to read", 441 | 442 | "Usage: .write address hexpairs\n" 443 | "Writes hexpairs to a destination address\n" 444 | "\n" 445 | " address - an integer or a register name\n" 446 | " hexpairs - pairs of hexadecimal numbers", 447 | 448 | "Usage: .writestr address string\n" 449 | "Writes an ascii string to a destination address\n" 450 | "\n" 451 | " address - an integer or a register name\n" 452 | " string - an ascii string", 453 | 454 | "Usage: .alloc len\n" 455 | "Allocates some memory and returns the address\n" 456 | "\n" 457 | " len - the amount of bytes to allocate", 458 | 459 | "Usage: .regs\n" 460 | "Displays the values of the registers currently toggled on", 461 | 462 | "Usage: .show [gpr|status|fpr_hex|fpr_double]\n" 463 | "Toggles which types of registers are shown\n" 464 | "\n" 465 | " gpr - General purpose registers (rax, rsp, rip, ...)\n" 466 | " status - Status registers (CF, ZF, ...)\n" 467 | " fpr_hex - Floating point registers shown in hex (xmm0, xmm1, ...)\n" 468 | " fpr_double - Floating point registers shown as doubles", 469 | 470 | "Usage: .syntax [att|intel]\n" 471 | "Changes the assembly syntax to intel or at&t\n" 472 | }; 473 | 474 | ssize_t cmd = -1; 475 | if(line[0] == '?' || line[0] == '.') { 476 | for(size_t i = 0; i != ELEMENTS(cmd_names); i++) { 477 | size_t len = strlen(cmd_names[i]); 478 | if(strncmp(cmd_names[i], line + 1, len) == 0 && (line[len + 1] == '\0' || line[len + 1] == ' ')) { 479 | cmd = i; 480 | break; 481 | } 482 | } 483 | } 484 | 485 | if(line[0] == '?') { 486 | if(cmd != -1) { 487 | puts(help[cmd]); 488 | continue; 489 | } 490 | 491 | puts("Valid input:\n" 492 | " Help:\n" 493 | " ? - show this help\n" 494 | " ?[cmd] - show help for a command\n" 495 | "\n" 496 | " Commands:\n" 497 | " .set - change value of register\n" 498 | " .read - read from memory\n" 499 | " .write - write hex to memory\n" 500 | " .writestr - write string to memory\n" 501 | " .alloc - allocate memory\n" 502 | " .regs - show the contents of the registers\n" 503 | " .show - toggle shown register types\n" 504 | " .syntax - change the assembly syntax to intel or at&t\n" 505 | "\n" 506 | "Any other input will be interpreted as " ARCH_NAME " assembly" 507 | ); 508 | } else if(line[0] == '.') { 509 | size_t args = count_tokens(line, " ") - 1; 510 | 511 | char *p = line + 1; 512 | char *cmd_name = strsep(&p, " "); 513 | char *arg1 = strsep(&p, " "); 514 | char *arg2 = strsep(&p, " "); 515 | 516 | switch(cmd) { 517 | case set: { 518 | if(args != 2) { 519 | puts(help[cmd]); 520 | continue; 521 | } 522 | 523 | size_t len = strlen(arg2); 524 | if(len == 1) { 525 | char c = arg2[0]; 526 | if(c == '0' || c == '1') { 527 | x86_flags_t *flags = (x86_flags_t *)&state->uts.ts.flags_register; 528 | bool matched = false; 529 | #define X(f) do { \ 530 | if(strcmp(arg1, #f) == 0) { \ 531 | flags->f = c - '0'; \ 532 | matched = true; \ 533 | } \ 534 | } while(false) 535 | FOREACH_STATUS_FLAG(X) 536 | #undef X 537 | 538 | if(matched) { 539 | continue; 540 | } 541 | } 542 | } 543 | 544 | size_t size; 545 | unsigned char *data = hex2bytes(arg2, &size, true); 546 | if(!data) { 547 | puts(help[cmd]); 548 | continue; 549 | } 550 | 551 | size_t expected_size; 552 | gpr_register_t *gpr = get_gpr_pointer(arg1, state); 553 | xmm_value_t *xmm; 554 | if(gpr) { 555 | expected_size = sizeof(*gpr); 556 | } else { 557 | xmm = get_fpr_pointer(arg1, float_state); 558 | if(xmm) { 559 | expected_size = sizeof(*xmm); 560 | } 561 | } 562 | 563 | if((!gpr && !xmm) || expected_size < size) { 564 | puts(help[cmd]); 565 | free(data); 566 | continue; 567 | } 568 | 569 | if(gpr) { 570 | *gpr = 0; 571 | unsigned char *ptr = (void *)gpr; 572 | for(size_t i = 0; i != size; i++) { 573 | ptr[i] = data[size - i - 1]; 574 | } 575 | set_thread_state(thread, state); 576 | } else { 577 | xmm->ints[0] = 0; 578 | xmm->ints[1] = 0; 579 | unsigned char *p1 = (void *)&(xmm->ints[1]); 580 | unsigned char *p2 = (void *)&(xmm->ints[0]); 581 | for(size_t i = 0; i != size; i++) { 582 | if(i < sizeof(*xmm->ints)) { 583 | p1[i] = data[size - i - 1]; 584 | } else { 585 | p2[i % sizeof(*xmm->ints)] = data[size - i - 1]; 586 | } 587 | } 588 | set_float_state(thread, float_state); 589 | } 590 | 591 | free(data); 592 | 593 | break; 594 | } 595 | case read: { 596 | gpr_register_t address; 597 | if(args < 1 || args > 2 || !get_value(arg1, state, &address)) { 598 | puts(help[cmd]); 599 | continue; 600 | } 601 | 602 | gpr_register_t len = 0x20; 603 | if(args == 2) { 604 | if(!get_number(arg2, &len)) { 605 | puts(help[cmd]); 606 | continue; 607 | } 608 | } 609 | 610 | unsigned char *data = malloc(len); 611 | mach_vm_size_t count; 612 | KERN_TRY("mach_vm_read_overwrite", mach_vm_read_overwrite(task, address, len, (mach_vm_address_t)data, &count), { 613 | free(data); 614 | continue; 615 | }); 616 | 617 | const size_t row_bytes = 8; 618 | for(int i = 0; i < count; i += row_bytes) { 619 | char str[3 * row_bytes + 2 + row_bytes]; 620 | for(int j = 0; j < row_bytes && i + j < count; j++) { 621 | unsigned char c = data[i + j]; 622 | str[3 * j] = int2hex(c >> 4); 623 | str[3 * j + 1] = int2hex(c & 0x0f); 624 | str[3 * j + 2] = ' '; 625 | str[3 * row_bytes + 1 + j] = ISGRAPH(c)? c: '.'; 626 | } 627 | str[3 * row_bytes] = ' '; 628 | str[sizeof(str) - 1] = '\0'; 629 | printf(REGISTER_FORMAT_HEX ": %s\n", address + i, str); 630 | } 631 | 632 | free(data); 633 | break; 634 | } 635 | case write: { 636 | gpr_register_t address; 637 | if(args != 2 || !get_value(arg1, state, &address)) { 638 | puts(help[cmd]); 639 | continue; 640 | } 641 | 642 | size_t size; 643 | unsigned char *data = hex2bytes(arg2, &size, false); 644 | if(!data) { 645 | printf("Invalid hexpairs!\n"); 646 | continue; 647 | } 648 | 649 | KERN_TRY("mach_vm_write", mach_vm_write(task, address, (vm_offset_t)data, size), { 650 | free(data); 651 | continue; 652 | }); 653 | 654 | printf("Wrote %zu bytes.\n", size); 655 | 656 | free(data); 657 | break; 658 | } 659 | case writestr: { 660 | gpr_register_t address; 661 | if(args != 2 || !get_value(arg1, state, &address)) { 662 | puts(help[cmd]); 663 | continue; 664 | } 665 | 666 | size_t size = strlen(arg2) + 1; 667 | 668 | KERN_TRY("mach_vm_write", mach_vm_write(task, address, (vm_offset_t)arg2, size), { 669 | continue; 670 | }); 671 | 672 | printf("Wrote %zu bytes.\n", size); 673 | 674 | break; 675 | } 676 | case alloc: { 677 | gpr_register_t size; 678 | if(args != 1 || !get_number(arg1, &size)) { 679 | puts(help[cmd]); 680 | continue; 681 | } 682 | 683 | mach_vm_address_t address; 684 | KERN_TRY("mach_vm_allocate", mach_vm_allocate(task, &address, size, VM_FLAGS_ANYWHERE), { 685 | continue; 686 | }); 687 | 688 | printf("Allocated " REGISTER_FORMAT_DEC " bytes at 0x%llx\n", size, address); 689 | break; 690 | } 691 | case regs: { 692 | print_registers(state, float_state); 693 | break; 694 | } 695 | case show: { 696 | if(args == 1) { 697 | bool toggled = false; 698 | for(size_t i = 0; i < ELEMENTS(register_type_names); i++) { 699 | if(strcmp(arg1, register_type_names[i]) == 0) { 700 | bool val = !show_register_types[i]; 701 | show_register_types[i] = val; 702 | printf("%s toggled %s\n", arg1, val? "on": "off"); 703 | toggled = true; 704 | break; 705 | } 706 | } 707 | if(toggled) { 708 | continue; 709 | } 710 | } 711 | 712 | puts(help[cmd]); 713 | break; 714 | } 715 | case syntax: { 716 | if(args == 1) { 717 | int type = -1; 718 | if(strcmp(arg1, "intel") == 0) { 719 | type = 0; 720 | } 721 | if(strcmp(arg1, "att") == 0) { 722 | type = 1; 723 | } 724 | 725 | if(type != -1) { 726 | syntax_type = type; 727 | continue; 728 | } 729 | } 730 | 731 | if(args == 0) { 732 | printf("Current syntax: %s\n", syntax_type? "att": "intel"); 733 | } 734 | 735 | puts(help[cmd]); 736 | break; 737 | } 738 | default: { 739 | printf("Invalid command: .%s\n", cmd_name); 740 | break; 741 | } 742 | } 743 | } else { 744 | unsigned char *assembly; 745 | size_t asm_len; 746 | mach_vm_address_t pc = state->uts.ts.pc_register; 747 | if(assemble_string(line, BITS, pc, &assembly, &asm_len, syntax_type)) { 748 | KERN_FAIL("mach_vm_write", mach_vm_write(task, pc, (vm_offset_t)assembly, asm_len)); 749 | free(assembly); 750 | write_int3(task, pc + asm_len); 751 | break; 752 | } else { 753 | puts("Failed to assemble instruction."); 754 | } 755 | } 756 | } 757 | } 758 | 759 | void setup_readline() { 760 | // Disable file auto-complete 761 | rl_bind_key('\t', rl_insert); 762 | 763 | asprintf(&histfile, "%s/%s", getenv("HOME"), ".asm_repl_history"); 764 | read_history(histfile); 765 | } 766 | 767 | #define READY 'R' 768 | 769 | void write_ready(int fd) { 770 | static char ready = READY; 771 | write(fd, &ready, sizeof(ready)); 772 | } 773 | 774 | void read_ready(int fd) { 775 | char buf; 776 | if(read(fd, &buf, sizeof(buf)) <= 0 || buf != READY) { 777 | puts("Failed to read"); 778 | exit(1); 779 | } 780 | } 781 | 782 | task_t child_task; 783 | 784 | void sigint_handler(int sig) { 785 | if(waiting_for_input) { 786 | // Clear line 787 | printf("\33[2K\r"); 788 | // Print prompt again 789 | longjmp(prompt_jmp_buf, 0); 790 | } else { 791 | // Suspend child and prompt for input 792 | puts(""); 793 | task_suspend(child_task); 794 | pthread_mutex_unlock(&mutex); 795 | } 796 | } 797 | 798 | void sigchld_handler(int sig) { 799 | int status; 800 | waitpid(-1, &status, WNOHANG); 801 | if(WIFSIGNALED(status)) { 802 | puts("Process died!"); 803 | exit(1); 804 | } 805 | } 806 | 807 | int main(int argc, const char *argv[]) { 808 | if(!taskport_auth()) { 809 | puts("Failed to get taskport auth!"); 810 | exit(1); 811 | } 812 | 813 | int p1[2]; 814 | int p2[2]; 815 | pipe(p1); 816 | pipe(p2); 817 | 818 | int parent_read = p1[0]; 819 | int child_write = p1[1]; 820 | int child_read = p2[0]; 821 | int parent_write = p2[1]; 822 | 823 | pid_t pid = fork(); 824 | if(pid == -1) { 825 | perror("fork"); 826 | return 1; 827 | } 828 | 829 | if(pid == 0) { 830 | close(parent_read); 831 | close(parent_write); 832 | 833 | signal(SIGINT, SIG_IGN); 834 | 835 | // Try to drop privileges 836 | setgid(-2); 837 | setuid(-2); 838 | 839 | // We are ready for the parent to register the exception handlers 840 | write_ready(child_write); 841 | 842 | // Wait for the parents exception handler 843 | read_ready(child_read); 844 | 845 | // This will be caught by the parents exception handler 846 | __asm__("int3"); 847 | } else { 848 | close(child_read); 849 | close(child_write); 850 | 851 | signal(SIGINT, sigint_handler); 852 | signal(SIGCHLD, sigchld_handler); 853 | 854 | setup_readline(); 855 | 856 | // Wait for the child to be ready 857 | read_ready(parent_read); 858 | 859 | task_t task; 860 | if(task_for_pid(mach_task_self(), pid, &task) != KERN_SUCCESS) { 861 | puts("task_for_pid() failed!"); 862 | puts("Either codesign asm_repl or run as root."); 863 | exit(1); 864 | } 865 | child_task = task; 866 | 867 | pthread_mutex_init(&mutex, NULL); 868 | pthread_mutex_lock(&mutex); 869 | 870 | setup_exception_handler(task); 871 | 872 | // We have set up the exception handler so we make the child raise SIGTRAP 873 | write_ready(parent_write); 874 | 875 | // Wait for exception handler to be called 876 | pthread_mutex_lock(&mutex); 877 | 878 | thread_act_t thread; 879 | mach_vm_address_t memory; 880 | setup_child(task, &thread, &memory); 881 | 882 | task_resume(task); 883 | 884 | while(true) { 885 | // Wait for exception handler 886 | pthread_mutex_lock(&mutex); 887 | 888 | x86_thread_state_t state; 889 | get_thread_state(thread, &state); 890 | 891 | x86_float_state_t float_state; 892 | get_float_state(thread, &float_state); 893 | 894 | print_registers(&state, &float_state); 895 | 896 | read_input(task, thread, &state, &float_state); 897 | 898 | task_resume(task); 899 | } 900 | } 901 | 902 | return 0; 903 | } 904 | -------------------------------------------------------------------------------- /assemble.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "utils.h" 8 | 9 | char *shell_escape(const char *str) { 10 | size_t len = strlen(str); 11 | char *escaped = malloc(4 * len + 1); 12 | 13 | size_t j = 0; 14 | for(size_t i = 0; i <= len; i++) { 15 | if(str[i] == '\'') { 16 | strcpy(escaped + j, "'\\''"); 17 | j += 4; 18 | } else { 19 | escaped[j] = str[i]; 20 | j++; 21 | } 22 | } 23 | 24 | escaped[j] = '\0'; 25 | 26 | return escaped; 27 | } 28 | 29 | // TODO: Actually use a library to assemble instead of calling out to rasm2 30 | bool assemble_string(char *str, uint8_t bits, uint64_t address, unsigned char **output, size_t *output_size, bool att_syntax) { 31 | *output_size = 0; 32 | *output = malloc(16); 33 | 34 | char *escaped = shell_escape(str); 35 | 36 | char *cmd; 37 | if(att_syntax) { 38 | asprintf(&cmd, "rasm2 -s att -a x86.as -b %u '%s'", 39 | bits, escaped); 40 | } else { 41 | asprintf(&cmd, "rasm2 -a x86.nasm -b %u -o 0x%llx '%s'", 42 | bits, address, escaped); 43 | } 44 | 45 | free(escaped); 46 | 47 | FILE *f = popen(cmd, "r"); 48 | free(cmd); 49 | 50 | if(!f) { 51 | return false; 52 | } 53 | 54 | size_t bytes_read = 0; 55 | 56 | char buf[256]; 57 | while(fgets(buf, sizeof(buf), f)) { 58 | size_t len = strlen(buf); 59 | *output_size += (len - 1) / 2; 60 | *output = realloc(*output, *output_size); 61 | for(int i = 0; i < len; i += 2) { 62 | (*output)[bytes_read++] = hex2int(buf[i]) * 0x10 + hex2int(buf[i + 1]); 63 | } 64 | } 65 | 66 | pclose(f); 67 | 68 | if(bytes_read == 0) { 69 | return false; 70 | } 71 | 72 | return true; 73 | } 74 | -------------------------------------------------------------------------------- /assemble.h: -------------------------------------------------------------------------------- 1 | int assemble_string(char *str, uint8_t bits, uint64_t address, unsigned char **output, size_t *output_size, bool att_syntax); 2 | -------------------------------------------------------------------------------- /colors.h: -------------------------------------------------------------------------------- 1 | #define KNRM "\x1B[0m" 2 | #define KRED "\x1B[31m" 3 | #define KGRN "\x1B[32m" 4 | #define KYEL "\x1B[33m" 5 | #define KBLU "\x1B[34m" 6 | #define KMAG "\x1B[35m" 7 | #define KCYN "\x1B[36m" 8 | #define KWHT "\x1B[37m" 9 | #define RESET "\033[0m" 10 | -------------------------------------------------------------------------------- /float_registers.h: -------------------------------------------------------------------------------- 1 | #if defined(__i386__) 2 | 3 | #define FLOAT_REGISTERS 8 4 | 5 | #define FOREACH_FLOAT_REGISTER(X) \ 6 | X(xmm0); \ 7 | X(xmm1); \ 8 | X(xmm2); \ 9 | X(xmm3); \ 10 | X(xmm4); \ 11 | X(xmm5); \ 12 | X(xmm6); \ 13 | X(xmm7); 14 | 15 | #elif defined(__x86_64__) 16 | 17 | #define FLOAT_REGISTERS 16 18 | 19 | #define FOREACH_FLOAT_REGISTER(X) \ 20 | X(xmm0); \ 21 | X(xmm1); \ 22 | X(xmm2); \ 23 | X(xmm3); \ 24 | X(xmm4); \ 25 | X(xmm5); \ 26 | X(xmm6); \ 27 | X(xmm7); \ 28 | X(xmm8); \ 29 | X(xmm9); \ 30 | X(xmm10); \ 31 | X(xmm11); \ 32 | X(xmm12); \ 33 | X(xmm13); \ 34 | X(xmm14); \ 35 | X(xmm15); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /mach_exc/mach_exc.h: -------------------------------------------------------------------------------- 1 | #ifndef _mach_exc_user_ 2 | #define _mach_exc_user_ 3 | 4 | /* Module mach_exc */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | /* BEGIN VOUCHER CODE */ 17 | 18 | #ifndef KERNEL 19 | #if defined(__has_include) 20 | #if __has_include() 21 | #ifndef USING_VOUCHERS 22 | #define USING_VOUCHERS 23 | #endif 24 | #ifndef __VOUCHER_FORWARD_TYPE_DECLS__ 25 | #define __VOUCHER_FORWARD_TYPE_DECLS__ 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); 30 | #ifdef __cplusplus 31 | } 32 | #endif 33 | #endif // __VOUCHER_FORWARD_TYPE_DECLS__ 34 | #endif // __has_include() 35 | #endif // __has_include 36 | #endif // !KERNEL 37 | 38 | /* END VOUCHER CODE */ 39 | 40 | 41 | #ifdef AUTOTEST 42 | #ifndef FUNCTION_PTR_T 43 | #define FUNCTION_PTR_T 44 | typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); 45 | typedef struct { 46 | char *name; 47 | function_ptr_t function; 48 | } function_table_entry; 49 | typedef function_table_entry *function_table_t; 50 | #endif /* FUNCTION_PTR_T */ 51 | #endif /* AUTOTEST */ 52 | 53 | #ifndef mach_exc_MSG_COUNT 54 | #define mach_exc_MSG_COUNT 3 55 | #endif /* mach_exc_MSG_COUNT */ 56 | 57 | #include 58 | #include 59 | #include 60 | #include 61 | 62 | #ifdef __BeforeMigUserHeader 63 | __BeforeMigUserHeader 64 | #endif /* __BeforeMigUserHeader */ 65 | 66 | #include 67 | __BEGIN_DECLS 68 | 69 | 70 | /* Routine mach_exception_raise */ 71 | #ifdef mig_external 72 | mig_external 73 | #else 74 | extern 75 | #endif /* mig_external */ 76 | kern_return_t mach_exception_raise 77 | ( 78 | mach_port_t exception_port, 79 | mach_port_t thread, 80 | mach_port_t task, 81 | exception_type_t exception, 82 | mach_exception_data_t code, 83 | mach_msg_type_number_t codeCnt 84 | ); 85 | 86 | /* Routine mach_exception_raise_state */ 87 | #ifdef mig_external 88 | mig_external 89 | #else 90 | extern 91 | #endif /* mig_external */ 92 | kern_return_t mach_exception_raise_state 93 | ( 94 | mach_port_t exception_port, 95 | exception_type_t exception, 96 | const mach_exception_data_t code, 97 | mach_msg_type_number_t codeCnt, 98 | int *flavor, 99 | const thread_state_t old_state, 100 | mach_msg_type_number_t old_stateCnt, 101 | thread_state_t new_state, 102 | mach_msg_type_number_t *new_stateCnt 103 | ); 104 | 105 | /* Routine mach_exception_raise_state_identity */ 106 | #ifdef mig_external 107 | mig_external 108 | #else 109 | extern 110 | #endif /* mig_external */ 111 | kern_return_t mach_exception_raise_state_identity 112 | ( 113 | mach_port_t exception_port, 114 | mach_port_t thread, 115 | mach_port_t task, 116 | exception_type_t exception, 117 | mach_exception_data_t code, 118 | mach_msg_type_number_t codeCnt, 119 | int *flavor, 120 | thread_state_t old_state, 121 | mach_msg_type_number_t old_stateCnt, 122 | thread_state_t new_state, 123 | mach_msg_type_number_t *new_stateCnt 124 | ); 125 | 126 | __END_DECLS 127 | 128 | /********************** Caution **************************/ 129 | /* The following data types should be used to calculate */ 130 | /* maximum message sizes only. The actual message may be */ 131 | /* smaller, and the position of the arguments within the */ 132 | /* message layout may vary from what is presented here. */ 133 | /* For example, if any of the arguments are variable- */ 134 | /* sized, and less than the maximum is sent, the data */ 135 | /* will be packed tight in the actual message to reduce */ 136 | /* the presence of holes. */ 137 | /********************** Caution **************************/ 138 | 139 | /* typedefs for all requests */ 140 | 141 | #ifndef __Request__mach_exc_subsystem__defined 142 | #define __Request__mach_exc_subsystem__defined 143 | 144 | #ifdef __MigPackStructs 145 | #pragma pack(4) 146 | #endif 147 | typedef struct { 148 | mach_msg_header_t Head; 149 | /* start of the kernel processed data */ 150 | mach_msg_body_t msgh_body; 151 | mach_msg_port_descriptor_t thread; 152 | mach_msg_port_descriptor_t task; 153 | /* end of the kernel processed data */ 154 | NDR_record_t NDR; 155 | exception_type_t exception; 156 | mach_msg_type_number_t codeCnt; 157 | int64_t code[2]; 158 | } __Request__mach_exception_raise_t __attribute__((unused)); 159 | #ifdef __MigPackStructs 160 | #pragma pack() 161 | #endif 162 | 163 | #ifdef __MigPackStructs 164 | #pragma pack(4) 165 | #endif 166 | typedef struct { 167 | mach_msg_header_t Head; 168 | NDR_record_t NDR; 169 | exception_type_t exception; 170 | mach_msg_type_number_t codeCnt; 171 | int64_t code[2]; 172 | int flavor; 173 | mach_msg_type_number_t old_stateCnt; 174 | natural_t old_state[224]; 175 | } __Request__mach_exception_raise_state_t __attribute__((unused)); 176 | #ifdef __MigPackStructs 177 | #pragma pack() 178 | #endif 179 | 180 | #ifdef __MigPackStructs 181 | #pragma pack(4) 182 | #endif 183 | typedef struct { 184 | mach_msg_header_t Head; 185 | /* start of the kernel processed data */ 186 | mach_msg_body_t msgh_body; 187 | mach_msg_port_descriptor_t thread; 188 | mach_msg_port_descriptor_t task; 189 | /* end of the kernel processed data */ 190 | NDR_record_t NDR; 191 | exception_type_t exception; 192 | mach_msg_type_number_t codeCnt; 193 | int64_t code[2]; 194 | int flavor; 195 | mach_msg_type_number_t old_stateCnt; 196 | natural_t old_state[224]; 197 | } __Request__mach_exception_raise_state_identity_t __attribute__((unused)); 198 | #ifdef __MigPackStructs 199 | #pragma pack() 200 | #endif 201 | #endif /* !__Request__mach_exc_subsystem__defined */ 202 | 203 | /* union of all requests */ 204 | 205 | #ifndef __RequestUnion__mach_exc_subsystem__defined 206 | #define __RequestUnion__mach_exc_subsystem__defined 207 | union __RequestUnion__mach_exc_subsystem { 208 | __Request__mach_exception_raise_t Request_mach_exception_raise; 209 | __Request__mach_exception_raise_state_t Request_mach_exception_raise_state; 210 | __Request__mach_exception_raise_state_identity_t Request_mach_exception_raise_state_identity; 211 | }; 212 | #endif /* !__RequestUnion__mach_exc_subsystem__defined */ 213 | /* typedefs for all replies */ 214 | 215 | #ifndef __Reply__mach_exc_subsystem__defined 216 | #define __Reply__mach_exc_subsystem__defined 217 | 218 | #ifdef __MigPackStructs 219 | #pragma pack(4) 220 | #endif 221 | typedef struct { 222 | mach_msg_header_t Head; 223 | NDR_record_t NDR; 224 | kern_return_t RetCode; 225 | } __Reply__mach_exception_raise_t __attribute__((unused)); 226 | #ifdef __MigPackStructs 227 | #pragma pack() 228 | #endif 229 | 230 | #ifdef __MigPackStructs 231 | #pragma pack(4) 232 | #endif 233 | typedef struct { 234 | mach_msg_header_t Head; 235 | NDR_record_t NDR; 236 | kern_return_t RetCode; 237 | int flavor; 238 | mach_msg_type_number_t new_stateCnt; 239 | natural_t new_state[224]; 240 | } __Reply__mach_exception_raise_state_t __attribute__((unused)); 241 | #ifdef __MigPackStructs 242 | #pragma pack() 243 | #endif 244 | 245 | #ifdef __MigPackStructs 246 | #pragma pack(4) 247 | #endif 248 | typedef struct { 249 | mach_msg_header_t Head; 250 | NDR_record_t NDR; 251 | kern_return_t RetCode; 252 | int flavor; 253 | mach_msg_type_number_t new_stateCnt; 254 | natural_t new_state[224]; 255 | } __Reply__mach_exception_raise_state_identity_t __attribute__((unused)); 256 | #ifdef __MigPackStructs 257 | #pragma pack() 258 | #endif 259 | #endif /* !__Reply__mach_exc_subsystem__defined */ 260 | 261 | /* union of all replies */ 262 | 263 | #ifndef __ReplyUnion__mach_exc_subsystem__defined 264 | #define __ReplyUnion__mach_exc_subsystem__defined 265 | union __ReplyUnion__mach_exc_subsystem { 266 | __Reply__mach_exception_raise_t Reply_mach_exception_raise; 267 | __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; 268 | __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; 269 | }; 270 | #endif /* !__RequestUnion__mach_exc_subsystem__defined */ 271 | 272 | #ifndef subsystem_to_name_map_mach_exc 273 | #define subsystem_to_name_map_mach_exc \ 274 | { "mach_exception_raise", 2405 },\ 275 | { "mach_exception_raise_state", 2406 },\ 276 | { "mach_exception_raise_state_identity", 2407 } 277 | #endif 278 | 279 | #ifdef __AfterMigUserHeader 280 | __AfterMigUserHeader 281 | #endif /* __AfterMigUserHeader */ 282 | 283 | #endif /* _mach_exc_user_ */ 284 | -------------------------------------------------------------------------------- /mach_exc/mach_excServer.c: -------------------------------------------------------------------------------- 1 | /* 2 | * IDENTIFICATION: 3 | * stub generated Wed May 6 20:32:21 2015 4 | * with a MiG generated by bootstrap_cmds-93 5 | * OPTIONS: 6 | */ 7 | 8 | /* Module mach_exc */ 9 | 10 | #define __MIG_check__Request__mach_exc_subsystem__ 1 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | /* BEGIN VOUCHER CODE */ 23 | 24 | #ifndef KERNEL 25 | #if defined(__has_include) 26 | #if __has_include() 27 | #ifndef USING_VOUCHERS 28 | #define USING_VOUCHERS 29 | #endif 30 | #ifndef __VOUCHER_FORWARD_TYPE_DECLS__ 31 | #define __VOUCHER_FORWARD_TYPE_DECLS__ 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | #endif // __VOUCHER_FORWARD_TYPE_DECLS__ 40 | #endif // __has_include() 41 | #endif // __has_include 42 | #endif // !KERNEL 43 | 44 | /* END VOUCHER CODE */ 45 | 46 | 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #ifndef mig_internal 53 | #define mig_internal static __inline__ 54 | #endif /* mig_internal */ 55 | 56 | #ifndef mig_external 57 | #define mig_external 58 | #endif /* mig_external */ 59 | 60 | #if !defined(__MigTypeCheck) && defined(TypeCheck) 61 | #define __MigTypeCheck TypeCheck /* Legacy setting */ 62 | #endif /* !defined(__MigTypeCheck) */ 63 | 64 | #if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) 65 | #define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ 66 | #endif /* !defined(__MigKernelSpecificCode) */ 67 | 68 | #ifndef LimitCheck 69 | #define LimitCheck 0 70 | #endif /* LimitCheck */ 71 | 72 | #ifndef min 73 | #define min(a,b) ( ((a) < (b))? (a): (b) ) 74 | #endif /* min */ 75 | 76 | #if !defined(_WALIGN_) 77 | #define _WALIGN_(x) (((x) + 3) & ~3) 78 | #endif /* !defined(_WALIGN_) */ 79 | 80 | #if !defined(_WALIGNSZ_) 81 | #define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) 82 | #endif /* !defined(_WALIGNSZ_) */ 83 | 84 | #ifndef UseStaticTemplates 85 | #define UseStaticTemplates 0 86 | #endif /* UseStaticTemplates */ 87 | 88 | #ifndef __DeclareRcvRpc 89 | #define __DeclareRcvRpc(_NUM_, _NAME_) 90 | #endif /* __DeclareRcvRpc */ 91 | 92 | #ifndef __BeforeRcvRpc 93 | #define __BeforeRcvRpc(_NUM_, _NAME_) 94 | #endif /* __BeforeRcvRpc */ 95 | 96 | #ifndef __AfterRcvRpc 97 | #define __AfterRcvRpc(_NUM_, _NAME_) 98 | #endif /* __AfterRcvRpc */ 99 | 100 | #ifndef __DeclareRcvSimple 101 | #define __DeclareRcvSimple(_NUM_, _NAME_) 102 | #endif /* __DeclareRcvSimple */ 103 | 104 | #ifndef __BeforeRcvSimple 105 | #define __BeforeRcvSimple(_NUM_, _NAME_) 106 | #endif /* __BeforeRcvSimple */ 107 | 108 | #ifndef __AfterRcvSimple 109 | #define __AfterRcvSimple(_NUM_, _NAME_) 110 | #endif /* __AfterRcvSimple */ 111 | 112 | #define novalue void 113 | 114 | #define msgh_request_port msgh_local_port 115 | #define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) 116 | #define msgh_reply_port msgh_remote_port 117 | #define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) 118 | 119 | #define MIG_RETURN_ERROR(X, code) {\ 120 | ((mig_reply_error_t *)X)->RetCode = code;\ 121 | ((mig_reply_error_t *)X)->NDR = NDR_record;\ 122 | return;\ 123 | } 124 | 125 | /* typedefs for all requests */ 126 | 127 | #ifndef __Request__mach_exc_subsystem__defined 128 | #define __Request__mach_exc_subsystem__defined 129 | 130 | #ifdef __MigPackStructs 131 | #pragma pack(4) 132 | #endif 133 | typedef struct { 134 | mach_msg_header_t Head; 135 | /* start of the kernel processed data */ 136 | mach_msg_body_t msgh_body; 137 | mach_msg_port_descriptor_t thread; 138 | mach_msg_port_descriptor_t task; 139 | /* end of the kernel processed data */ 140 | NDR_record_t NDR; 141 | exception_type_t exception; 142 | mach_msg_type_number_t codeCnt; 143 | int64_t code[2]; 144 | } __Request__mach_exception_raise_t __attribute__((unused)); 145 | #ifdef __MigPackStructs 146 | #pragma pack() 147 | #endif 148 | 149 | #ifdef __MigPackStructs 150 | #pragma pack(4) 151 | #endif 152 | typedef struct { 153 | mach_msg_header_t Head; 154 | NDR_record_t NDR; 155 | exception_type_t exception; 156 | mach_msg_type_number_t codeCnt; 157 | int64_t code[2]; 158 | int flavor; 159 | mach_msg_type_number_t old_stateCnt; 160 | natural_t old_state[224]; 161 | } __Request__mach_exception_raise_state_t __attribute__((unused)); 162 | #ifdef __MigPackStructs 163 | #pragma pack() 164 | #endif 165 | 166 | #ifdef __MigPackStructs 167 | #pragma pack(4) 168 | #endif 169 | typedef struct { 170 | mach_msg_header_t Head; 171 | /* start of the kernel processed data */ 172 | mach_msg_body_t msgh_body; 173 | mach_msg_port_descriptor_t thread; 174 | mach_msg_port_descriptor_t task; 175 | /* end of the kernel processed data */ 176 | NDR_record_t NDR; 177 | exception_type_t exception; 178 | mach_msg_type_number_t codeCnt; 179 | int64_t code[2]; 180 | int flavor; 181 | mach_msg_type_number_t old_stateCnt; 182 | natural_t old_state[224]; 183 | } __Request__mach_exception_raise_state_identity_t __attribute__((unused)); 184 | #ifdef __MigPackStructs 185 | #pragma pack() 186 | #endif 187 | #endif /* !__Request__mach_exc_subsystem__defined */ 188 | 189 | /* typedefs for all replies */ 190 | 191 | #ifndef __Reply__mach_exc_subsystem__defined 192 | #define __Reply__mach_exc_subsystem__defined 193 | 194 | #ifdef __MigPackStructs 195 | #pragma pack(4) 196 | #endif 197 | typedef struct { 198 | mach_msg_header_t Head; 199 | NDR_record_t NDR; 200 | kern_return_t RetCode; 201 | } __Reply__mach_exception_raise_t __attribute__((unused)); 202 | #ifdef __MigPackStructs 203 | #pragma pack() 204 | #endif 205 | 206 | #ifdef __MigPackStructs 207 | #pragma pack(4) 208 | #endif 209 | typedef struct { 210 | mach_msg_header_t Head; 211 | NDR_record_t NDR; 212 | kern_return_t RetCode; 213 | int flavor; 214 | mach_msg_type_number_t new_stateCnt; 215 | natural_t new_state[224]; 216 | } __Reply__mach_exception_raise_state_t __attribute__((unused)); 217 | #ifdef __MigPackStructs 218 | #pragma pack() 219 | #endif 220 | 221 | #ifdef __MigPackStructs 222 | #pragma pack(4) 223 | #endif 224 | typedef struct { 225 | mach_msg_header_t Head; 226 | NDR_record_t NDR; 227 | kern_return_t RetCode; 228 | int flavor; 229 | mach_msg_type_number_t new_stateCnt; 230 | natural_t new_state[224]; 231 | } __Reply__mach_exception_raise_state_identity_t __attribute__((unused)); 232 | #ifdef __MigPackStructs 233 | #pragma pack() 234 | #endif 235 | #endif /* !__Reply__mach_exc_subsystem__defined */ 236 | 237 | 238 | /* union of all replies */ 239 | 240 | #ifndef __ReplyUnion__catch_mach_exc_subsystem__defined 241 | #define __ReplyUnion__catch_mach_exc_subsystem__defined 242 | union __ReplyUnion__catch_mach_exc_subsystem { 243 | __Reply__mach_exception_raise_t Reply_mach_exception_raise; 244 | __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; 245 | __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; 246 | }; 247 | #endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ 248 | /* Forward Declarations */ 249 | 250 | 251 | mig_internal novalue _Xmach_exception_raise 252 | (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); 253 | 254 | mig_internal novalue _Xmach_exception_raise_state 255 | (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); 256 | 257 | mig_internal novalue _Xmach_exception_raise_state_identity 258 | (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); 259 | 260 | 261 | #if ( __MigTypeCheck ) 262 | #if __MIG_check__Request__mach_exc_subsystem__ 263 | #if !defined(__MIG_check__Request__mach_exception_raise_t__defined) 264 | #define __MIG_check__Request__mach_exception_raise_t__defined 265 | 266 | mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_t(__attribute__((__unused__)) __Request__mach_exception_raise_t *In0P) 267 | { 268 | 269 | typedef __Request__mach_exception_raise_t __Request; 270 | #if __MigTypeCheck 271 | unsigned int msgh_size; 272 | #endif /* __MigTypeCheck */ 273 | 274 | #if __MigTypeCheck 275 | msgh_size = In0P->Head.msgh_size; 276 | if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || 277 | (In0P->msgh_body.msgh_descriptor_count != 2) || 278 | (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 16)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) 279 | return MIG_BAD_ARGUMENTS; 280 | #endif /* __MigTypeCheck */ 281 | 282 | #if __MigTypeCheck 283 | if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || 284 | In0P->thread.disposition != 17) 285 | return MIG_TYPE_ERROR; 286 | #endif /* __MigTypeCheck */ 287 | 288 | #if __MigTypeCheck 289 | if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || 290 | In0P->task.disposition != 17) 291 | return MIG_TYPE_ERROR; 292 | #endif /* __MigTypeCheck */ 293 | 294 | #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) 295 | if (In0P->NDR.int_rep != NDR_record.int_rep) 296 | __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); 297 | #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ 298 | #if __MigTypeCheck 299 | if ( In0P->codeCnt > 2 ) 300 | return MIG_BAD_ARGUMENTS; 301 | if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 16)) / 8 < In0P->codeCnt) || 302 | (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 16) + (8 * In0P->codeCnt))) 303 | return MIG_BAD_ARGUMENTS; 304 | #endif /* __MigTypeCheck */ 305 | 306 | return MACH_MSG_SUCCESS; 307 | } 308 | #endif /* !defined(__MIG_check__Request__mach_exception_raise_t__defined) */ 309 | #endif /* __MIG_check__Request__mach_exc_subsystem__ */ 310 | #endif /* ( __MigTypeCheck ) */ 311 | 312 | 313 | /* Routine mach_exception_raise */ 314 | #ifdef mig_external 315 | mig_external 316 | #else 317 | extern 318 | #endif /* mig_external */ 319 | kern_return_t catch_mach_exception_raise 320 | ( 321 | mach_port_t exception_port, 322 | mach_port_t thread, 323 | mach_port_t task, 324 | exception_type_t exception, 325 | mach_exception_data_t code, 326 | mach_msg_type_number_t codeCnt 327 | ); 328 | 329 | /* Routine mach_exception_raise */ 330 | mig_internal novalue _Xmach_exception_raise 331 | (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) 332 | { 333 | 334 | #ifdef __MigPackStructs 335 | #pragma pack(4) 336 | #endif 337 | typedef struct { 338 | mach_msg_header_t Head; 339 | /* start of the kernel processed data */ 340 | mach_msg_body_t msgh_body; 341 | mach_msg_port_descriptor_t thread; 342 | mach_msg_port_descriptor_t task; 343 | /* end of the kernel processed data */ 344 | NDR_record_t NDR; 345 | exception_type_t exception; 346 | mach_msg_type_number_t codeCnt; 347 | int64_t code[2]; 348 | mach_msg_trailer_t trailer; 349 | } Request __attribute__((unused)); 350 | #ifdef __MigPackStructs 351 | #pragma pack() 352 | #endif 353 | typedef __Request__mach_exception_raise_t __Request; 354 | typedef __Reply__mach_exception_raise_t Reply __attribute__((unused)); 355 | 356 | /* 357 | * typedef struct { 358 | * mach_msg_header_t Head; 359 | * NDR_record_t NDR; 360 | * kern_return_t RetCode; 361 | * } mig_reply_error_t; 362 | */ 363 | 364 | Request *In0P = (Request *) InHeadP; 365 | Reply *OutP = (Reply *) OutHeadP; 366 | #ifdef __MIG_check__Request__mach_exception_raise_t__defined 367 | kern_return_t check_result; 368 | #endif /* __MIG_check__Request__mach_exception_raise_t__defined */ 369 | 370 | __DeclareRcvRpc(2405, "mach_exception_raise") 371 | __BeforeRcvRpc(2405, "mach_exception_raise") 372 | 373 | #if defined(__MIG_check__Request__mach_exception_raise_t__defined) 374 | check_result = __MIG_check__Request__mach_exception_raise_t((__Request *)In0P); 375 | if (check_result != MACH_MSG_SUCCESS) 376 | { MIG_RETURN_ERROR(OutP, check_result); } 377 | #endif /* defined(__MIG_check__Request__mach_exception_raise_t__defined) */ 378 | 379 | OutP->RetCode = catch_mach_exception_raise(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt); 380 | 381 | OutP->NDR = NDR_record; 382 | 383 | 384 | __AfterRcvRpc(2405, "mach_exception_raise") 385 | } 386 | 387 | #if ( __MigTypeCheck ) 388 | #if __MIG_check__Request__mach_exc_subsystem__ 389 | #if !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) 390 | #define __MIG_check__Request__mach_exception_raise_state_t__defined 391 | 392 | mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_t **In1PP) 393 | { 394 | 395 | typedef __Request__mach_exception_raise_state_t __Request; 396 | __Request *In1P; 397 | #if __MigTypeCheck 398 | unsigned int msgh_size; 399 | #endif /* __MigTypeCheck */ 400 | unsigned int msgh_size_delta; 401 | 402 | #if __MigTypeCheck 403 | msgh_size = In0P->Head.msgh_size; 404 | if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || 405 | (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) 406 | return MIG_BAD_ARGUMENTS; 407 | #endif /* __MigTypeCheck */ 408 | 409 | #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) 410 | if (In0P->NDR.int_rep != NDR_record.int_rep) 411 | __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); 412 | #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ 413 | msgh_size_delta = (8 * In0P->codeCnt); 414 | #if __MigTypeCheck 415 | if ( In0P->codeCnt > 2 ) 416 | return MIG_BAD_ARGUMENTS; 417 | if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || 418 | (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) 419 | return MIG_BAD_ARGUMENTS; 420 | msgh_size -= msgh_size_delta; 421 | #endif /* __MigTypeCheck */ 422 | 423 | *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); 424 | 425 | #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) 426 | if (In0P->NDR.int_rep != NDR_record.int_rep) 427 | __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); 428 | #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ 429 | #if __MigTypeCheck 430 | if ( In1P->old_stateCnt > 224 ) 431 | return MIG_BAD_ARGUMENTS; 432 | if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || 433 | (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) 434 | return MIG_BAD_ARGUMENTS; 435 | #endif /* __MigTypeCheck */ 436 | 437 | return MACH_MSG_SUCCESS; 438 | } 439 | #endif /* !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ 440 | #endif /* __MIG_check__Request__mach_exc_subsystem__ */ 441 | #endif /* ( __MigTypeCheck ) */ 442 | 443 | 444 | /* Routine mach_exception_raise_state */ 445 | #ifdef mig_external 446 | mig_external 447 | #else 448 | extern 449 | #endif /* mig_external */ 450 | kern_return_t catch_mach_exception_raise_state 451 | ( 452 | mach_port_t exception_port, 453 | exception_type_t exception, 454 | const mach_exception_data_t code, 455 | mach_msg_type_number_t codeCnt, 456 | int *flavor, 457 | const thread_state_t old_state, 458 | mach_msg_type_number_t old_stateCnt, 459 | thread_state_t new_state, 460 | mach_msg_type_number_t *new_stateCnt 461 | ); 462 | 463 | /* Routine mach_exception_raise_state */ 464 | mig_internal novalue _Xmach_exception_raise_state 465 | (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) 466 | { 467 | 468 | #ifdef __MigPackStructs 469 | #pragma pack(4) 470 | #endif 471 | typedef struct { 472 | mach_msg_header_t Head; 473 | NDR_record_t NDR; 474 | exception_type_t exception; 475 | mach_msg_type_number_t codeCnt; 476 | int64_t code[2]; 477 | int flavor; 478 | mach_msg_type_number_t old_stateCnt; 479 | natural_t old_state[224]; 480 | mach_msg_trailer_t trailer; 481 | } Request __attribute__((unused)); 482 | #ifdef __MigPackStructs 483 | #pragma pack() 484 | #endif 485 | typedef __Request__mach_exception_raise_state_t __Request; 486 | typedef __Reply__mach_exception_raise_state_t Reply __attribute__((unused)); 487 | 488 | /* 489 | * typedef struct { 490 | * mach_msg_header_t Head; 491 | * NDR_record_t NDR; 492 | * kern_return_t RetCode; 493 | * } mig_reply_error_t; 494 | */ 495 | 496 | Request *In0P = (Request *) InHeadP; 497 | Request *In1P; 498 | Reply *OutP = (Reply *) OutHeadP; 499 | #ifdef __MIG_check__Request__mach_exception_raise_state_t__defined 500 | kern_return_t check_result; 501 | #endif /* __MIG_check__Request__mach_exception_raise_state_t__defined */ 502 | 503 | __DeclareRcvRpc(2406, "mach_exception_raise_state") 504 | __BeforeRcvRpc(2406, "mach_exception_raise_state") 505 | 506 | #if defined(__MIG_check__Request__mach_exception_raise_state_t__defined) 507 | check_result = __MIG_check__Request__mach_exception_raise_state_t((__Request *)In0P, (__Request **)&In1P); 508 | if (check_result != MACH_MSG_SUCCESS) 509 | { MIG_RETURN_ERROR(OutP, check_result); } 510 | #endif /* defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ 511 | 512 | OutP->new_stateCnt = 224; 513 | 514 | OutP->RetCode = catch_mach_exception_raise_state(In0P->Head.msgh_request_port, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); 515 | if (OutP->RetCode != KERN_SUCCESS) { 516 | MIG_RETURN_ERROR(OutP, OutP->RetCode); 517 | } 518 | 519 | OutP->NDR = NDR_record; 520 | 521 | 522 | OutP->flavor = In1P->flavor; 523 | OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); 524 | 525 | __AfterRcvRpc(2406, "mach_exception_raise_state") 526 | } 527 | 528 | #if ( __MigTypeCheck ) 529 | #if __MIG_check__Request__mach_exc_subsystem__ 530 | #if !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) 531 | #define __MIG_check__Request__mach_exception_raise_state_identity_t__defined 532 | 533 | mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_identity_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t **In1PP) 534 | { 535 | 536 | typedef __Request__mach_exception_raise_state_identity_t __Request; 537 | __Request *In1P; 538 | #if __MigTypeCheck 539 | unsigned int msgh_size; 540 | #endif /* __MigTypeCheck */ 541 | unsigned int msgh_size_delta; 542 | 543 | #if __MigTypeCheck 544 | msgh_size = In0P->Head.msgh_size; 545 | if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || 546 | (In0P->msgh_body.msgh_descriptor_count != 2) || 547 | (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) 548 | return MIG_BAD_ARGUMENTS; 549 | #endif /* __MigTypeCheck */ 550 | 551 | #if __MigTypeCheck 552 | if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || 553 | In0P->thread.disposition != 17) 554 | return MIG_TYPE_ERROR; 555 | #endif /* __MigTypeCheck */ 556 | 557 | #if __MigTypeCheck 558 | if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || 559 | In0P->task.disposition != 17) 560 | return MIG_TYPE_ERROR; 561 | #endif /* __MigTypeCheck */ 562 | 563 | #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) 564 | if (In0P->NDR.int_rep != NDR_record.int_rep) 565 | __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); 566 | #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ 567 | msgh_size_delta = (8 * In0P->codeCnt); 568 | #if __MigTypeCheck 569 | if ( In0P->codeCnt > 2 ) 570 | return MIG_BAD_ARGUMENTS; 571 | if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || 572 | (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) 573 | return MIG_BAD_ARGUMENTS; 574 | msgh_size -= msgh_size_delta; 575 | #endif /* __MigTypeCheck */ 576 | 577 | *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); 578 | 579 | #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) 580 | if (In0P->NDR.int_rep != NDR_record.int_rep) 581 | __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); 582 | #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ 583 | #if __MigTypeCheck 584 | if ( In1P->old_stateCnt > 224 ) 585 | return MIG_BAD_ARGUMENTS; 586 | if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || 587 | (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) 588 | return MIG_BAD_ARGUMENTS; 589 | #endif /* __MigTypeCheck */ 590 | 591 | return MACH_MSG_SUCCESS; 592 | } 593 | #endif /* !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ 594 | #endif /* __MIG_check__Request__mach_exc_subsystem__ */ 595 | #endif /* ( __MigTypeCheck ) */ 596 | 597 | 598 | /* Routine mach_exception_raise_state_identity */ 599 | #ifdef mig_external 600 | mig_external 601 | #else 602 | extern 603 | #endif /* mig_external */ 604 | kern_return_t catch_mach_exception_raise_state_identity 605 | ( 606 | mach_port_t exception_port, 607 | mach_port_t thread, 608 | mach_port_t task, 609 | exception_type_t exception, 610 | mach_exception_data_t code, 611 | mach_msg_type_number_t codeCnt, 612 | int *flavor, 613 | thread_state_t old_state, 614 | mach_msg_type_number_t old_stateCnt, 615 | thread_state_t new_state, 616 | mach_msg_type_number_t *new_stateCnt 617 | ); 618 | 619 | /* Routine mach_exception_raise_state_identity */ 620 | mig_internal novalue _Xmach_exception_raise_state_identity 621 | (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) 622 | { 623 | 624 | #ifdef __MigPackStructs 625 | #pragma pack(4) 626 | #endif 627 | typedef struct { 628 | mach_msg_header_t Head; 629 | /* start of the kernel processed data */ 630 | mach_msg_body_t msgh_body; 631 | mach_msg_port_descriptor_t thread; 632 | mach_msg_port_descriptor_t task; 633 | /* end of the kernel processed data */ 634 | NDR_record_t NDR; 635 | exception_type_t exception; 636 | mach_msg_type_number_t codeCnt; 637 | int64_t code[2]; 638 | int flavor; 639 | mach_msg_type_number_t old_stateCnt; 640 | natural_t old_state[224]; 641 | mach_msg_trailer_t trailer; 642 | } Request __attribute__((unused)); 643 | #ifdef __MigPackStructs 644 | #pragma pack() 645 | #endif 646 | typedef __Request__mach_exception_raise_state_identity_t __Request; 647 | typedef __Reply__mach_exception_raise_state_identity_t Reply __attribute__((unused)); 648 | 649 | /* 650 | * typedef struct { 651 | * mach_msg_header_t Head; 652 | * NDR_record_t NDR; 653 | * kern_return_t RetCode; 654 | * } mig_reply_error_t; 655 | */ 656 | 657 | Request *In0P = (Request *) InHeadP; 658 | Request *In1P; 659 | Reply *OutP = (Reply *) OutHeadP; 660 | #ifdef __MIG_check__Request__mach_exception_raise_state_identity_t__defined 661 | kern_return_t check_result; 662 | #endif /* __MIG_check__Request__mach_exception_raise_state_identity_t__defined */ 663 | 664 | __DeclareRcvRpc(2407, "mach_exception_raise_state_identity") 665 | __BeforeRcvRpc(2407, "mach_exception_raise_state_identity") 666 | 667 | #if defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) 668 | check_result = __MIG_check__Request__mach_exception_raise_state_identity_t((__Request *)In0P, (__Request **)&In1P); 669 | if (check_result != MACH_MSG_SUCCESS) 670 | { MIG_RETURN_ERROR(OutP, check_result); } 671 | #endif /* defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ 672 | 673 | OutP->new_stateCnt = 224; 674 | 675 | OutP->RetCode = catch_mach_exception_raise_state_identity(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); 676 | if (OutP->RetCode != KERN_SUCCESS) { 677 | MIG_RETURN_ERROR(OutP, OutP->RetCode); 678 | } 679 | 680 | OutP->NDR = NDR_record; 681 | 682 | 683 | OutP->flavor = In1P->flavor; 684 | OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); 685 | 686 | __AfterRcvRpc(2407, "mach_exception_raise_state_identity") 687 | } 688 | 689 | 690 | #ifdef mig_external 691 | mig_external 692 | #else 693 | extern 694 | #endif /* mig_external */ 695 | boolean_t mach_exc_server( 696 | mach_msg_header_t *InHeadP, 697 | mach_msg_header_t *OutHeadP); 698 | 699 | #ifdef mig_external 700 | mig_external 701 | #else 702 | extern 703 | #endif /* mig_external */ 704 | mig_routine_t mach_exc_server_routine( 705 | mach_msg_header_t *InHeadP); 706 | 707 | 708 | /* Description of this subsystem, for use in direct RPC */ 709 | const struct catch_mach_exc_subsystem { 710 | mig_server_routine_t server; /* Server routine */ 711 | mach_msg_id_t start; /* Min routine number */ 712 | mach_msg_id_t end; /* Max routine number + 1 */ 713 | unsigned int maxsize; /* Max msg size */ 714 | vm_address_t reserved; /* Reserved */ 715 | struct routine_descriptor /*Array of routine descriptors */ 716 | routine[3]; 717 | } catch_mach_exc_subsystem = { 718 | mach_exc_server_routine, 719 | 2405, 720 | 2408, 721 | (mach_msg_size_t)sizeof(union __ReplyUnion__catch_mach_exc_subsystem), 722 | (vm_address_t)0, 723 | { 724 | { (mig_impl_routine_t) 0, 725 | (mig_stub_routine_t) _Xmach_exception_raise, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_t)}, 726 | { (mig_impl_routine_t) 0, 727 | (mig_stub_routine_t) _Xmach_exception_raise_state, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_t)}, 728 | { (mig_impl_routine_t) 0, 729 | (mig_stub_routine_t) _Xmach_exception_raise_state_identity, 11, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_identity_t)}, 730 | } 731 | }; 732 | 733 | mig_external boolean_t mach_exc_server 734 | (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) 735 | { 736 | /* 737 | * typedef struct { 738 | * mach_msg_header_t Head; 739 | * NDR_record_t NDR; 740 | * kern_return_t RetCode; 741 | * } mig_reply_error_t; 742 | */ 743 | 744 | register mig_routine_t routine; 745 | 746 | OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); 747 | OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; 748 | /* Minimal size: routine() will update it if different */ 749 | OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); 750 | OutHeadP->msgh_local_port = MACH_PORT_NULL; 751 | OutHeadP->msgh_id = InHeadP->msgh_id + 100; 752 | 753 | if ((InHeadP->msgh_id > 2407) || (InHeadP->msgh_id < 2405) || 754 | ((routine = catch_mach_exc_subsystem.routine[InHeadP->msgh_id - 2405].stub_routine) == 0)) { 755 | ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; 756 | ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; 757 | return FALSE; 758 | } 759 | (*routine) (InHeadP, OutHeadP); 760 | return TRUE; 761 | } 762 | 763 | mig_external mig_routine_t mach_exc_server_routine 764 | (mach_msg_header_t *InHeadP) 765 | { 766 | register int msgh_id; 767 | 768 | msgh_id = InHeadP->msgh_id - 2405; 769 | 770 | if ((msgh_id > 2) || (msgh_id < 0)) 771 | return 0; 772 | 773 | return catch_mach_exc_subsystem.routine[msgh_id].stub_routine; 774 | } 775 | -------------------------------------------------------------------------------- /mach_exc/mach_excUser.c: -------------------------------------------------------------------------------- 1 | /* 2 | * IDENTIFICATION: 3 | * stub generated Wed May 6 20:32:21 2015 4 | * with a MiG generated by bootstrap_cmds-93 5 | * OPTIONS: 6 | */ 7 | #define __MIG_check__Reply__mach_exc_subsystem__ 1 8 | 9 | #include "mach_exc.h" 10 | 11 | 12 | #ifndef mig_internal 13 | #define mig_internal static __inline__ 14 | #endif /* mig_internal */ 15 | 16 | #ifndef mig_external 17 | #define mig_external 18 | #endif /* mig_external */ 19 | 20 | #if !defined(__MigTypeCheck) && defined(TypeCheck) 21 | #define __MigTypeCheck TypeCheck /* Legacy setting */ 22 | #endif /* !defined(__MigTypeCheck) */ 23 | 24 | #if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) 25 | #define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ 26 | #endif /* !defined(__MigKernelSpecificCode) */ 27 | 28 | #ifndef LimitCheck 29 | #define LimitCheck 0 30 | #endif /* LimitCheck */ 31 | 32 | #ifndef min 33 | #define min(a,b) ( ((a) < (b))? (a): (b) ) 34 | #endif /* min */ 35 | 36 | #if !defined(_WALIGN_) 37 | #define _WALIGN_(x) (((x) + 3) & ~3) 38 | #endif /* !defined(_WALIGN_) */ 39 | 40 | #if !defined(_WALIGNSZ_) 41 | #define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) 42 | #endif /* !defined(_WALIGNSZ_) */ 43 | 44 | #ifndef UseStaticTemplates 45 | #define UseStaticTemplates 0 46 | #endif /* UseStaticTemplates */ 47 | 48 | #ifndef __MachMsgErrorWithTimeout 49 | #define __MachMsgErrorWithTimeout(_R_) { \ 50 | switch (_R_) { \ 51 | case MACH_SEND_INVALID_DATA: \ 52 | case MACH_SEND_INVALID_DEST: \ 53 | case MACH_SEND_INVALID_HEADER: \ 54 | mig_put_reply_port(InP->Head.msgh_reply_port); \ 55 | break; \ 56 | case MACH_SEND_TIMED_OUT: \ 57 | case MACH_RCV_TIMED_OUT: \ 58 | default: \ 59 | mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ 60 | } \ 61 | } 62 | #endif /* __MachMsgErrorWithTimeout */ 63 | 64 | #ifndef __MachMsgErrorWithoutTimeout 65 | #define __MachMsgErrorWithoutTimeout(_R_) { \ 66 | switch (_R_) { \ 67 | case MACH_SEND_INVALID_DATA: \ 68 | case MACH_SEND_INVALID_DEST: \ 69 | case MACH_SEND_INVALID_HEADER: \ 70 | mig_put_reply_port(InP->Head.msgh_reply_port); \ 71 | break; \ 72 | default: \ 73 | mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ 74 | } \ 75 | } 76 | #endif /* __MachMsgErrorWithoutTimeout */ 77 | 78 | #ifndef __DeclareSendRpc 79 | #define __DeclareSendRpc(_NUM_, _NAME_) 80 | #endif /* __DeclareSendRpc */ 81 | 82 | #ifndef __BeforeSendRpc 83 | #define __BeforeSendRpc(_NUM_, _NAME_) 84 | #endif /* __BeforeSendRpc */ 85 | 86 | #ifndef __AfterSendRpc 87 | #define __AfterSendRpc(_NUM_, _NAME_) 88 | #endif /* __AfterSendRpc */ 89 | 90 | #ifndef __DeclareSendSimple 91 | #define __DeclareSendSimple(_NUM_, _NAME_) 92 | #endif /* __DeclareSendSimple */ 93 | 94 | #ifndef __BeforeSendSimple 95 | #define __BeforeSendSimple(_NUM_, _NAME_) 96 | #endif /* __BeforeSendSimple */ 97 | 98 | #ifndef __AfterSendSimple 99 | #define __AfterSendSimple(_NUM_, _NAME_) 100 | #endif /* __AfterSendSimple */ 101 | 102 | #define msgh_request_port msgh_remote_port 103 | #define msgh_reply_port msgh_local_port 104 | 105 | 106 | 107 | #if ( __MigTypeCheck ) 108 | #if __MIG_check__Reply__mach_exc_subsystem__ 109 | #if !defined(__MIG_check__Reply__mach_exception_raise_t__defined) 110 | #define __MIG_check__Reply__mach_exception_raise_t__defined 111 | 112 | mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_t(__Reply__mach_exception_raise_t *Out0P) 113 | { 114 | 115 | typedef __Reply__mach_exception_raise_t __Reply __attribute__((unused)); 116 | if (Out0P->Head.msgh_id != 2505) { 117 | if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) 118 | { return MIG_SERVER_DIED; } 119 | else 120 | { return MIG_REPLY_MISMATCH; } 121 | } 122 | 123 | #if __MigTypeCheck 124 | if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || 125 | (Out0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Reply))) 126 | { return MIG_TYPE_ERROR ; } 127 | #endif /* __MigTypeCheck */ 128 | 129 | { 130 | return Out0P->RetCode; 131 | } 132 | } 133 | #endif /* !defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ 134 | #endif /* __MIG_check__Reply__mach_exc_subsystem__ */ 135 | #endif /* ( __MigTypeCheck ) */ 136 | 137 | 138 | /* Routine mach_exception_raise */ 139 | mig_external kern_return_t mach_exception_raise 140 | ( 141 | mach_port_t exception_port, 142 | mach_port_t thread, 143 | mach_port_t task, 144 | exception_type_t exception, 145 | mach_exception_data_t code, 146 | mach_msg_type_number_t codeCnt 147 | ) 148 | { 149 | 150 | #ifdef __MigPackStructs 151 | #pragma pack(4) 152 | #endif 153 | typedef struct { 154 | mach_msg_header_t Head; 155 | /* start of the kernel processed data */ 156 | mach_msg_body_t msgh_body; 157 | mach_msg_port_descriptor_t thread; 158 | mach_msg_port_descriptor_t task; 159 | /* end of the kernel processed data */ 160 | NDR_record_t NDR; 161 | exception_type_t exception; 162 | mach_msg_type_number_t codeCnt; 163 | int64_t code[2]; 164 | } Request __attribute__((unused)); 165 | #ifdef __MigPackStructs 166 | #pragma pack() 167 | #endif 168 | 169 | #ifdef __MigPackStructs 170 | #pragma pack(4) 171 | #endif 172 | typedef struct { 173 | mach_msg_header_t Head; 174 | NDR_record_t NDR; 175 | kern_return_t RetCode; 176 | mach_msg_trailer_t trailer; 177 | } Reply __attribute__((unused)); 178 | #ifdef __MigPackStructs 179 | #pragma pack() 180 | #endif 181 | 182 | #ifdef __MigPackStructs 183 | #pragma pack(4) 184 | #endif 185 | typedef struct { 186 | mach_msg_header_t Head; 187 | NDR_record_t NDR; 188 | kern_return_t RetCode; 189 | } __Reply __attribute__((unused)); 190 | #ifdef __MigPackStructs 191 | #pragma pack() 192 | #endif 193 | /* 194 | * typedef struct { 195 | * mach_msg_header_t Head; 196 | * NDR_record_t NDR; 197 | * kern_return_t RetCode; 198 | * } mig_reply_error_t; 199 | */ 200 | 201 | union { 202 | Request In; 203 | Reply Out; 204 | } Mess; 205 | 206 | Request *InP = &Mess.In; 207 | Reply *Out0P = &Mess.Out; 208 | 209 | mach_msg_return_t msg_result; 210 | unsigned int msgh_size; 211 | 212 | #ifdef __MIG_check__Reply__mach_exception_raise_t__defined 213 | kern_return_t check_result; 214 | #endif /* __MIG_check__Reply__mach_exception_raise_t__defined */ 215 | 216 | __DeclareSendRpc(2405, "mach_exception_raise") 217 | 218 | #if UseStaticTemplates 219 | const static mach_msg_port_descriptor_t threadTemplate = { 220 | /* name = */ MACH_PORT_NULL, 221 | /* pad1 = */ 0, 222 | /* pad2 = */ 0, 223 | /* disp = */ 19, 224 | /* type = */ MACH_MSG_PORT_DESCRIPTOR, 225 | }; 226 | #endif /* UseStaticTemplates */ 227 | 228 | #if UseStaticTemplates 229 | const static mach_msg_port_descriptor_t taskTemplate = { 230 | /* name = */ MACH_PORT_NULL, 231 | /* pad1 = */ 0, 232 | /* pad2 = */ 0, 233 | /* disp = */ 19, 234 | /* type = */ MACH_MSG_PORT_DESCRIPTOR, 235 | }; 236 | #endif /* UseStaticTemplates */ 237 | 238 | InP->msgh_body.msgh_descriptor_count = 2; 239 | #if UseStaticTemplates 240 | InP->thread = threadTemplate; 241 | InP->thread.name = thread; 242 | #else /* UseStaticTemplates */ 243 | InP->thread.name = thread; 244 | InP->thread.disposition = 19; 245 | InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; 246 | #endif /* UseStaticTemplates */ 247 | 248 | #if UseStaticTemplates 249 | InP->task = taskTemplate; 250 | InP->task.name = task; 251 | #else /* UseStaticTemplates */ 252 | InP->task.name = task; 253 | InP->task.disposition = 19; 254 | InP->task.type = MACH_MSG_PORT_DESCRIPTOR; 255 | #endif /* UseStaticTemplates */ 256 | 257 | InP->NDR = NDR_record; 258 | 259 | InP->exception = exception; 260 | 261 | if (codeCnt > 2) { 262 | { return MIG_ARRAY_TOO_LARGE; } 263 | } 264 | (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); 265 | 266 | InP->codeCnt = codeCnt; 267 | 268 | msgh_size = (mach_msg_size_t)(sizeof(Request) - 16) + ((8 * codeCnt)); 269 | InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| 270 | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); 271 | /* msgh_size passed as argument */ 272 | InP->Head.msgh_request_port = exception_port; 273 | InP->Head.msgh_reply_port = mig_get_reply_port(); 274 | InP->Head.msgh_id = 2405; 275 | 276 | /* BEGIN VOUCHER CODE */ 277 | 278 | #ifdef USING_VOUCHERS 279 | if (voucher_mach_msg_set != NULL) { 280 | voucher_mach_msg_set(&InP->Head); 281 | } 282 | #endif // USING_VOUCHERS 283 | 284 | /* END VOUCHER CODE */ 285 | 286 | __BeforeSendRpc(2405, "mach_exception_raise") 287 | msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); 288 | __AfterSendRpc(2405, "mach_exception_raise") 289 | if (msg_result != MACH_MSG_SUCCESS) { 290 | __MachMsgErrorWithoutTimeout(msg_result); 291 | { return msg_result; } 292 | } 293 | 294 | 295 | #if defined(__MIG_check__Reply__mach_exception_raise_t__defined) 296 | check_result = __MIG_check__Reply__mach_exception_raise_t((__Reply__mach_exception_raise_t *)Out0P); 297 | if (check_result != MACH_MSG_SUCCESS) 298 | { return check_result; } 299 | #endif /* defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ 300 | 301 | return KERN_SUCCESS; 302 | } 303 | 304 | #if ( __MigTypeCheck ) 305 | #if __MIG_check__Reply__mach_exc_subsystem__ 306 | #if !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) 307 | #define __MIG_check__Reply__mach_exception_raise_state_t__defined 308 | 309 | mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_t(__Reply__mach_exception_raise_state_t *Out0P) 310 | { 311 | 312 | typedef __Reply__mach_exception_raise_state_t __Reply __attribute__((unused)); 313 | #if __MigTypeCheck 314 | unsigned int msgh_size; 315 | #endif /* __MigTypeCheck */ 316 | 317 | if (Out0P->Head.msgh_id != 2506) { 318 | if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) 319 | { return MIG_SERVER_DIED; } 320 | else 321 | { return MIG_REPLY_MISMATCH; } 322 | } 323 | 324 | #if __MigTypeCheck 325 | msgh_size = Out0P->Head.msgh_size; 326 | 327 | if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || 328 | ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 896)) && 329 | (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || 330 | Out0P->RetCode == KERN_SUCCESS))) 331 | { return MIG_TYPE_ERROR ; } 332 | #endif /* __MigTypeCheck */ 333 | 334 | if (Out0P->RetCode != KERN_SUCCESS) { 335 | return ((mig_reply_error_t *)Out0P)->RetCode; 336 | } 337 | 338 | #if __MigTypeCheck 339 | if ( Out0P->new_stateCnt > 224 ) 340 | return MIG_TYPE_ERROR; 341 | if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 896)) / 4< Out0P->new_stateCnt) || 342 | (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 896) + Out0P->new_stateCnt * 4)) 343 | { return MIG_TYPE_ERROR ; } 344 | #endif /* __MigTypeCheck */ 345 | 346 | return MACH_MSG_SUCCESS; 347 | } 348 | #endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ 349 | #endif /* __MIG_check__Reply__mach_exc_subsystem__ */ 350 | #endif /* ( __MigTypeCheck ) */ 351 | 352 | 353 | /* Routine mach_exception_raise_state */ 354 | mig_external kern_return_t mach_exception_raise_state 355 | ( 356 | mach_port_t exception_port, 357 | exception_type_t exception, 358 | const mach_exception_data_t code, 359 | mach_msg_type_number_t codeCnt, 360 | int *flavor, 361 | const thread_state_t old_state, 362 | mach_msg_type_number_t old_stateCnt, 363 | thread_state_t new_state, 364 | mach_msg_type_number_t *new_stateCnt 365 | ) 366 | { 367 | 368 | #ifdef __MigPackStructs 369 | #pragma pack(4) 370 | #endif 371 | typedef struct { 372 | mach_msg_header_t Head; 373 | NDR_record_t NDR; 374 | exception_type_t exception; 375 | mach_msg_type_number_t codeCnt; 376 | int64_t code[2]; 377 | int flavor; 378 | mach_msg_type_number_t old_stateCnt; 379 | natural_t old_state[224]; 380 | } Request __attribute__((unused)); 381 | #ifdef __MigPackStructs 382 | #pragma pack() 383 | #endif 384 | 385 | #ifdef __MigPackStructs 386 | #pragma pack(4) 387 | #endif 388 | typedef struct { 389 | mach_msg_header_t Head; 390 | NDR_record_t NDR; 391 | kern_return_t RetCode; 392 | int flavor; 393 | mach_msg_type_number_t new_stateCnt; 394 | natural_t new_state[224]; 395 | mach_msg_trailer_t trailer; 396 | } Reply __attribute__((unused)); 397 | #ifdef __MigPackStructs 398 | #pragma pack() 399 | #endif 400 | 401 | #ifdef __MigPackStructs 402 | #pragma pack(4) 403 | #endif 404 | typedef struct { 405 | mach_msg_header_t Head; 406 | NDR_record_t NDR; 407 | kern_return_t RetCode; 408 | int flavor; 409 | mach_msg_type_number_t new_stateCnt; 410 | natural_t new_state[224]; 411 | } __Reply __attribute__((unused)); 412 | #ifdef __MigPackStructs 413 | #pragma pack() 414 | #endif 415 | /* 416 | * typedef struct { 417 | * mach_msg_header_t Head; 418 | * NDR_record_t NDR; 419 | * kern_return_t RetCode; 420 | * } mig_reply_error_t; 421 | */ 422 | 423 | union { 424 | Request In; 425 | Reply Out; 426 | } Mess; 427 | 428 | Request *InP = &Mess.In; 429 | Reply *Out0P = &Mess.Out; 430 | 431 | mach_msg_return_t msg_result; 432 | unsigned int msgh_size; 433 | unsigned int msgh_size_delta; 434 | 435 | 436 | #ifdef __MIG_check__Reply__mach_exception_raise_state_t__defined 437 | kern_return_t check_result; 438 | #endif /* __MIG_check__Reply__mach_exception_raise_state_t__defined */ 439 | 440 | __DeclareSendRpc(2406, "mach_exception_raise_state") 441 | 442 | InP->NDR = NDR_record; 443 | 444 | InP->exception = exception; 445 | 446 | if (codeCnt > 2) { 447 | { return MIG_ARRAY_TOO_LARGE; } 448 | } 449 | (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); 450 | 451 | InP->codeCnt = codeCnt; 452 | 453 | msgh_size_delta = (8 * codeCnt); 454 | msgh_size = (mach_msg_size_t)(sizeof(Request) - 912) + msgh_size_delta; 455 | InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); 456 | 457 | InP->flavor = *flavor; 458 | 459 | if (old_stateCnt > 224) { 460 | { return MIG_ARRAY_TOO_LARGE; } 461 | } 462 | (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); 463 | 464 | InP->old_stateCnt = old_stateCnt; 465 | 466 | msgh_size += (4 * old_stateCnt); 467 | InP = &Mess.In; 468 | InP->Head.msgh_bits = 469 | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); 470 | /* msgh_size passed as argument */ 471 | InP->Head.msgh_request_port = exception_port; 472 | InP->Head.msgh_reply_port = mig_get_reply_port(); 473 | InP->Head.msgh_id = 2406; 474 | 475 | /* BEGIN VOUCHER CODE */ 476 | 477 | #ifdef USING_VOUCHERS 478 | if (voucher_mach_msg_set != NULL) { 479 | voucher_mach_msg_set(&InP->Head); 480 | } 481 | #endif // USING_VOUCHERS 482 | 483 | /* END VOUCHER CODE */ 484 | 485 | __BeforeSendRpc(2406, "mach_exception_raise_state") 486 | msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); 487 | __AfterSendRpc(2406, "mach_exception_raise_state") 488 | if (msg_result != MACH_MSG_SUCCESS) { 489 | __MachMsgErrorWithoutTimeout(msg_result); 490 | { return msg_result; } 491 | } 492 | 493 | 494 | #if defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) 495 | check_result = __MIG_check__Reply__mach_exception_raise_state_t((__Reply__mach_exception_raise_state_t *)Out0P); 496 | if (check_result != MACH_MSG_SUCCESS) 497 | { return check_result; } 498 | #endif /* defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ 499 | 500 | *flavor = Out0P->flavor; 501 | 502 | if (Out0P->new_stateCnt > 224) { 503 | (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 224); 504 | *new_stateCnt = Out0P->new_stateCnt; 505 | { return MIG_ARRAY_TOO_LARGE; } 506 | } 507 | (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); 508 | 509 | *new_stateCnt = Out0P->new_stateCnt; 510 | 511 | return KERN_SUCCESS; 512 | } 513 | 514 | #if ( __MigTypeCheck ) 515 | #if __MIG_check__Reply__mach_exc_subsystem__ 516 | #if !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) 517 | #define __MIG_check__Reply__mach_exception_raise_state_identity_t__defined 518 | 519 | mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_identity_t(__Reply__mach_exception_raise_state_identity_t *Out0P) 520 | { 521 | 522 | typedef __Reply__mach_exception_raise_state_identity_t __Reply __attribute__((unused)); 523 | #if __MigTypeCheck 524 | unsigned int msgh_size; 525 | #endif /* __MigTypeCheck */ 526 | 527 | if (Out0P->Head.msgh_id != 2507) { 528 | if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) 529 | { return MIG_SERVER_DIED; } 530 | else 531 | { return MIG_REPLY_MISMATCH; } 532 | } 533 | 534 | #if __MigTypeCheck 535 | msgh_size = Out0P->Head.msgh_size; 536 | 537 | if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || 538 | ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 896)) && 539 | (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || 540 | Out0P->RetCode == KERN_SUCCESS))) 541 | { return MIG_TYPE_ERROR ; } 542 | #endif /* __MigTypeCheck */ 543 | 544 | if (Out0P->RetCode != KERN_SUCCESS) { 545 | return ((mig_reply_error_t *)Out0P)->RetCode; 546 | } 547 | 548 | #if __MigTypeCheck 549 | if ( Out0P->new_stateCnt > 224 ) 550 | return MIG_TYPE_ERROR; 551 | if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 896)) / 4< Out0P->new_stateCnt) || 552 | (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 896) + Out0P->new_stateCnt * 4)) 553 | { return MIG_TYPE_ERROR ; } 554 | #endif /* __MigTypeCheck */ 555 | 556 | return MACH_MSG_SUCCESS; 557 | } 558 | #endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ 559 | #endif /* __MIG_check__Reply__mach_exc_subsystem__ */ 560 | #endif /* ( __MigTypeCheck ) */ 561 | 562 | 563 | /* Routine mach_exception_raise_state_identity */ 564 | mig_external kern_return_t mach_exception_raise_state_identity 565 | ( 566 | mach_port_t exception_port, 567 | mach_port_t thread, 568 | mach_port_t task, 569 | exception_type_t exception, 570 | mach_exception_data_t code, 571 | mach_msg_type_number_t codeCnt, 572 | int *flavor, 573 | thread_state_t old_state, 574 | mach_msg_type_number_t old_stateCnt, 575 | thread_state_t new_state, 576 | mach_msg_type_number_t *new_stateCnt 577 | ) 578 | { 579 | 580 | #ifdef __MigPackStructs 581 | #pragma pack(4) 582 | #endif 583 | typedef struct { 584 | mach_msg_header_t Head; 585 | /* start of the kernel processed data */ 586 | mach_msg_body_t msgh_body; 587 | mach_msg_port_descriptor_t thread; 588 | mach_msg_port_descriptor_t task; 589 | /* end of the kernel processed data */ 590 | NDR_record_t NDR; 591 | exception_type_t exception; 592 | mach_msg_type_number_t codeCnt; 593 | int64_t code[2]; 594 | int flavor; 595 | mach_msg_type_number_t old_stateCnt; 596 | natural_t old_state[224]; 597 | } Request __attribute__((unused)); 598 | #ifdef __MigPackStructs 599 | #pragma pack() 600 | #endif 601 | 602 | #ifdef __MigPackStructs 603 | #pragma pack(4) 604 | #endif 605 | typedef struct { 606 | mach_msg_header_t Head; 607 | NDR_record_t NDR; 608 | kern_return_t RetCode; 609 | int flavor; 610 | mach_msg_type_number_t new_stateCnt; 611 | natural_t new_state[224]; 612 | mach_msg_trailer_t trailer; 613 | } Reply __attribute__((unused)); 614 | #ifdef __MigPackStructs 615 | #pragma pack() 616 | #endif 617 | 618 | #ifdef __MigPackStructs 619 | #pragma pack(4) 620 | #endif 621 | typedef struct { 622 | mach_msg_header_t Head; 623 | NDR_record_t NDR; 624 | kern_return_t RetCode; 625 | int flavor; 626 | mach_msg_type_number_t new_stateCnt; 627 | natural_t new_state[224]; 628 | } __Reply __attribute__((unused)); 629 | #ifdef __MigPackStructs 630 | #pragma pack() 631 | #endif 632 | /* 633 | * typedef struct { 634 | * mach_msg_header_t Head; 635 | * NDR_record_t NDR; 636 | * kern_return_t RetCode; 637 | * } mig_reply_error_t; 638 | */ 639 | 640 | union { 641 | Request In; 642 | Reply Out; 643 | } Mess; 644 | 645 | Request *InP = &Mess.In; 646 | Reply *Out0P = &Mess.Out; 647 | 648 | mach_msg_return_t msg_result; 649 | unsigned int msgh_size; 650 | unsigned int msgh_size_delta; 651 | 652 | 653 | #ifdef __MIG_check__Reply__mach_exception_raise_state_identity_t__defined 654 | kern_return_t check_result; 655 | #endif /* __MIG_check__Reply__mach_exception_raise_state_identity_t__defined */ 656 | 657 | __DeclareSendRpc(2407, "mach_exception_raise_state_identity") 658 | 659 | #if UseStaticTemplates 660 | const static mach_msg_port_descriptor_t threadTemplate = { 661 | /* name = */ MACH_PORT_NULL, 662 | /* pad1 = */ 0, 663 | /* pad2 = */ 0, 664 | /* disp = */ 19, 665 | /* type = */ MACH_MSG_PORT_DESCRIPTOR, 666 | }; 667 | #endif /* UseStaticTemplates */ 668 | 669 | #if UseStaticTemplates 670 | const static mach_msg_port_descriptor_t taskTemplate = { 671 | /* name = */ MACH_PORT_NULL, 672 | /* pad1 = */ 0, 673 | /* pad2 = */ 0, 674 | /* disp = */ 19, 675 | /* type = */ MACH_MSG_PORT_DESCRIPTOR, 676 | }; 677 | #endif /* UseStaticTemplates */ 678 | 679 | InP->msgh_body.msgh_descriptor_count = 2; 680 | #if UseStaticTemplates 681 | InP->thread = threadTemplate; 682 | InP->thread.name = thread; 683 | #else /* UseStaticTemplates */ 684 | InP->thread.name = thread; 685 | InP->thread.disposition = 19; 686 | InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; 687 | #endif /* UseStaticTemplates */ 688 | 689 | #if UseStaticTemplates 690 | InP->task = taskTemplate; 691 | InP->task.name = task; 692 | #else /* UseStaticTemplates */ 693 | InP->task.name = task; 694 | InP->task.disposition = 19; 695 | InP->task.type = MACH_MSG_PORT_DESCRIPTOR; 696 | #endif /* UseStaticTemplates */ 697 | 698 | InP->NDR = NDR_record; 699 | 700 | InP->exception = exception; 701 | 702 | if (codeCnt > 2) { 703 | { return MIG_ARRAY_TOO_LARGE; } 704 | } 705 | (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); 706 | 707 | InP->codeCnt = codeCnt; 708 | 709 | msgh_size_delta = (8 * codeCnt); 710 | msgh_size = (mach_msg_size_t)(sizeof(Request) - 912) + msgh_size_delta; 711 | InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); 712 | 713 | InP->flavor = *flavor; 714 | 715 | if (old_stateCnt > 224) { 716 | { return MIG_ARRAY_TOO_LARGE; } 717 | } 718 | (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); 719 | 720 | InP->old_stateCnt = old_stateCnt; 721 | 722 | msgh_size += (4 * old_stateCnt); 723 | InP = &Mess.In; 724 | InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| 725 | MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); 726 | /* msgh_size passed as argument */ 727 | InP->Head.msgh_request_port = exception_port; 728 | InP->Head.msgh_reply_port = mig_get_reply_port(); 729 | InP->Head.msgh_id = 2407; 730 | 731 | /* BEGIN VOUCHER CODE */ 732 | 733 | #ifdef USING_VOUCHERS 734 | if (voucher_mach_msg_set != NULL) { 735 | voucher_mach_msg_set(&InP->Head); 736 | } 737 | #endif // USING_VOUCHERS 738 | 739 | /* END VOUCHER CODE */ 740 | 741 | __BeforeSendRpc(2407, "mach_exception_raise_state_identity") 742 | msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); 743 | __AfterSendRpc(2407, "mach_exception_raise_state_identity") 744 | if (msg_result != MACH_MSG_SUCCESS) { 745 | __MachMsgErrorWithoutTimeout(msg_result); 746 | { return msg_result; } 747 | } 748 | 749 | 750 | #if defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) 751 | check_result = __MIG_check__Reply__mach_exception_raise_state_identity_t((__Reply__mach_exception_raise_state_identity_t *)Out0P); 752 | if (check_result != MACH_MSG_SUCCESS) 753 | { return check_result; } 754 | #endif /* defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ 755 | 756 | *flavor = Out0P->flavor; 757 | 758 | if (Out0P->new_stateCnt > 224) { 759 | (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 224); 760 | *new_stateCnt = Out0P->new_stateCnt; 761 | { return MIG_ARRAY_TOO_LARGE; } 762 | } 763 | (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); 764 | 765 | *new_stateCnt = Out0P->new_stateCnt; 766 | 767 | return KERN_SUCCESS; 768 | } 769 | -------------------------------------------------------------------------------- /registers.h: -------------------------------------------------------------------------------- 1 | #if defined(__i386__) 2 | 3 | #define REGISTERS 9 4 | 5 | #define FOREACH_REGISTER(X) \ 6 | X(eax); \ 7 | X(ebx); \ 8 | X(ecx); \ 9 | X(edx); \ 10 | X(edi); \ 11 | X(esi); \ 12 | X(ebp); \ 13 | X(esp); \ 14 | X(eip); 15 | 16 | #elif defined(__x86_64__) 17 | 18 | #define REGISTERS 17 19 | 20 | #define FOREACH_REGISTER(X) \ 21 | X(rax); \ 22 | X(rbx); \ 23 | X(rcx); \ 24 | X(rdx); \ 25 | X(rdi); \ 26 | X(rsi); \ 27 | X(rbp); \ 28 | X(rsp); \ 29 | X(r8); \ 30 | X(r9); \ 31 | X(r10); \ 32 | X(r11); \ 33 | X(r12); \ 34 | X(r13); \ 35 | X(r14); \ 36 | X(r15); \ 37 | X(rip); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /status_flags.h: -------------------------------------------------------------------------------- 1 | #define FOREACH_STATUS_FLAG(X) \ 2 | X(CF); \ 3 | X(PF); \ 4 | X(AF); \ 5 | X(ZF); \ 6 | X(SF); \ 7 | X(TF); \ 8 | X(IF); \ 9 | X(DF); \ 10 | X(OF); 11 | -------------------------------------------------------------------------------- /taskport_auth.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "taskport_auth.h" 4 | 5 | bool taskport_auth(void) { 6 | OSStatus stat; 7 | AuthorizationItem taskport_item[] = {{"system.privilege.taskport:"}}; 8 | AuthorizationRights rights = {1, taskport_item}, *out_rights = NULL; 9 | AuthorizationRef author; 10 | 11 | AuthorizationFlags auth_flags = kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize | kAuthorizationFlagInteractionAllowed | (1 << 5); 12 | 13 | stat = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, auth_flags, &author); 14 | if(stat != errAuthorizationSuccess) { 15 | return false; 16 | } 17 | 18 | stat = AuthorizationCopyRights(author, &rights, kAuthorizationEmptyEnvironment, auth_flags, &out_rights); 19 | if(stat != errAuthorizationSuccess) { 20 | return false; 21 | } 22 | return true; 23 | } 24 | -------------------------------------------------------------------------------- /taskport_auth.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | bool taskport_auth(void); 4 | -------------------------------------------------------------------------------- /utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int hex2int(char c) { 6 | if('0' <= c && c <= '9') { 7 | return c - '0'; 8 | } 9 | if('a' <= c && c <= 'f') { 10 | return c - 'a' + 10; 11 | } 12 | if('A' <= c && c <= 'F') { 13 | return c - 'A' + 10; 14 | } 15 | 16 | return -1; 17 | } 18 | 19 | char int2hex(int i) { 20 | if(0 <= i && i <= 9) { 21 | return '0' + i; 22 | } 23 | if(0xa <= i && i <= 0xf) { 24 | return 'a' - 0xa + i; 25 | } 26 | return -1; 27 | } 28 | 29 | unsigned char *hex2bytes(char *hex, size_t *size, bool allow_odd) { 30 | size_t len = strlen(hex); 31 | bool odd = false; 32 | if(len % 2 != 0) { 33 | if(allow_odd) { 34 | odd = true; 35 | } else { 36 | return NULL; 37 | } 38 | } 39 | 40 | *size = (len + 1) / 2; 41 | unsigned char *buf = malloc(*size); 42 | 43 | for(ssize_t i = odd? -1: 0; i != len; i += 2) { 44 | int i1 = i == -1? 0: hex2int(hex[i]); 45 | int i2 = hex2int(hex[i + 1]); 46 | if(i1 == -1 || i2 == -1) { 47 | free(buf); 48 | return NULL; 49 | } 50 | buf[(i + 1) / 2] = i1 * 0x10 + i2; 51 | } 52 | 53 | return buf; 54 | } 55 | -------------------------------------------------------------------------------- /utils.h: -------------------------------------------------------------------------------- 1 | int hex2int(char c); 2 | char int2hex(int i); 3 | unsigned char *hex2bytes(char *hex, size_t *size, bool allow_odd); 4 | --------------------------------------------------------------------------------