├── .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 | [](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 |
--------------------------------------------------------------------------------