Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- |
michael@0 | 2 | * vim: set ts=8 sts=4 et sw=4 tw=99: |
michael@0 | 3 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | #ifdef __APPLE__ |
michael@0 | 8 | |
michael@0 | 9 | #include "sharkctl.h" |
michael@0 | 10 | #include <stddef.h> |
michael@0 | 11 | #include <stdio.h> |
michael@0 | 12 | #include <stdlib.h> |
michael@0 | 13 | #include <unistd.h> |
michael@0 | 14 | |
michael@0 | 15 | #include "jsutil.h" |
michael@0 | 16 | |
michael@0 | 17 | #define SHARK_MSG_ACQUIRE 0x29a |
michael@0 | 18 | #define SHARK_MSG_RELEASE 0x29b |
michael@0 | 19 | #define SHARK_MSG_STOP 0x29c |
michael@0 | 20 | #define SHARK_MSG_START 0x29d |
michael@0 | 21 | |
michael@0 | 22 | #define RECV_SIZEOF(ty) offsetof(ty, out) |
michael@0 | 23 | |
michael@0 | 24 | // Private API in libSystem.dylib |
michael@0 | 25 | extern "C" void bootstrap_look_up(mach_port_t special_port, const char *name, |
michael@0 | 26 | mach_port_t *dest_port); |
michael@0 | 27 | |
michael@0 | 28 | struct chud_client_acquire_msg { |
michael@0 | 29 | mach_msg_header_t hdr; |
michael@0 | 30 | uint32_t unk0; // always 0 |
michael@0 | 31 | uint32_t unk1; // always 1 |
michael@0 | 32 | uint32_t pid; |
michael@0 | 33 | uint32_t out[2]; |
michael@0 | 34 | }; |
michael@0 | 35 | |
michael@0 | 36 | struct chud_client_start_msg { |
michael@0 | 37 | mach_msg_header_t hdr; |
michael@0 | 38 | uint32_t unk0; // always 1 |
michael@0 | 39 | uint32_t name0; |
michael@0 | 40 | uint32_t arg2; // always 6 |
michael@0 | 41 | uint8_t unk1; // always 0 |
michael@0 | 42 | uint8_t unk2; // always 1 |
michael@0 | 43 | uint8_t unk3; // uninitialized |
michael@0 | 44 | uint8_t unk4; // always 1 |
michael@0 | 45 | uint32_t unk5; // always 0 |
michael@0 | 46 | uint32_t unk6; // always 1 |
michael@0 | 47 | uint32_t name1; // same as name0 |
michael@0 | 48 | }; |
michael@0 | 49 | |
michael@0 | 50 | struct chud_client_stop_msg { |
michael@0 | 51 | mach_msg_header_t hdr; |
michael@0 | 52 | uint32_t out[5]; |
michael@0 | 53 | }; |
michael@0 | 54 | |
michael@0 | 55 | struct chud_client_release_msg { |
michael@0 | 56 | mach_msg_header_t hdr; |
michael@0 | 57 | uint32_t unk0; // always 0 |
michael@0 | 58 | uint32_t unk1; // always 1 |
michael@0 | 59 | uint32_t pid; |
michael@0 | 60 | uint32_t out[2]; |
michael@0 | 61 | }; |
michael@0 | 62 | |
michael@0 | 63 | static mach_port_t |
michael@0 | 64 | CreatePort(void) |
michael@0 | 65 | { |
michael@0 | 66 | mach_port_t bootstrap_port, shark_port = 0; |
michael@0 | 67 | task_get_special_port(mach_task_self(), TASK_BOOTSTRAP_PORT, |
michael@0 | 68 | &bootstrap_port); |
michael@0 | 69 | bootstrap_look_up(bootstrap_port, "CHUD_IPC", &shark_port); |
michael@0 | 70 | return shark_port; |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | static mach_msg_return_t |
michael@0 | 74 | Connect(mach_port_t shark_port) |
michael@0 | 75 | { |
michael@0 | 76 | mach_port_t reply_port = mig_get_reply_port(); |
michael@0 | 77 | |
michael@0 | 78 | struct chud_client_acquire_msg msg; |
michael@0 | 79 | msg.hdr.msgh_bits = 0x1513; |
michael@0 | 80 | msg.hdr.msgh_size = sizeof(mach_msg_header_t); |
michael@0 | 81 | msg.hdr.msgh_remote_port = shark_port; |
michael@0 | 82 | msg.hdr.msgh_local_port = reply_port; |
michael@0 | 83 | msg.hdr.msgh_reserved = 0; |
michael@0 | 84 | msg.hdr.msgh_id = SHARK_MSG_ACQUIRE; |
michael@0 | 85 | msg.unk0 = 0; |
michael@0 | 86 | msg.unk1 = 1; |
michael@0 | 87 | msg.pid = getpid(); |
michael@0 | 88 | |
michael@0 | 89 | JS_ASSERT(RECV_SIZEOF(struct chud_client_acquire_msg) == 0x24); |
michael@0 | 90 | JS_ASSERT(sizeof(msg) == 0x2c); |
michael@0 | 91 | mach_msg_return_t result = mach_msg(&msg.hdr, MACH_SEND_MSG | MACH_RCV_MSG, |
michael@0 | 92 | RECV_SIZEOF(struct chud_client_acquire_msg), |
michael@0 | 93 | sizeof(msg), reply_port, 0, 0); |
michael@0 | 94 | mig_dealloc_reply_port(reply_port); |
michael@0 | 95 | return result; |
michael@0 | 96 | } |
michael@0 | 97 | |
michael@0 | 98 | static mach_msg_return_t |
michael@0 | 99 | Start(mach_port_t shark_port, uint32_t name) |
michael@0 | 100 | { |
michael@0 | 101 | mach_port_t reply_port = mig_get_reply_port(); |
michael@0 | 102 | |
michael@0 | 103 | struct chud_client_start_msg msg; |
michael@0 | 104 | msg.hdr.msgh_bits = 0x80001513; |
michael@0 | 105 | msg.hdr.msgh_size = sizeof(mach_msg_header_t); |
michael@0 | 106 | msg.hdr.msgh_remote_port = shark_port; |
michael@0 | 107 | msg.hdr.msgh_local_port = reply_port; |
michael@0 | 108 | msg.hdr.msgh_reserved = 0; |
michael@0 | 109 | msg.hdr.msgh_id = SHARK_MSG_START; |
michael@0 | 110 | msg.unk0 = 1; |
michael@0 | 111 | msg.name0 = name; |
michael@0 | 112 | msg.arg2 = 6; |
michael@0 | 113 | msg.unk1 = 0; |
michael@0 | 114 | msg.unk2 = 1; |
michael@0 | 115 | msg.unk3 = 0; |
michael@0 | 116 | msg.unk4 = 1; |
michael@0 | 117 | msg.unk5 = 0; |
michael@0 | 118 | msg.unk6 = 1; |
michael@0 | 119 | msg.name1 = name; |
michael@0 | 120 | |
michael@0 | 121 | JS_ASSERT(sizeof(msg) == 0x34); |
michael@0 | 122 | mach_msg_return_t result = mach_msg(&msg.hdr, MACH_SEND_MSG | MACH_RCV_MSG, |
michael@0 | 123 | sizeof(msg), 0x30, reply_port, 0, 0); |
michael@0 | 124 | mig_dealloc_reply_port(reply_port); |
michael@0 | 125 | return result; |
michael@0 | 126 | } |
michael@0 | 127 | |
michael@0 | 128 | mach_msg_return_t |
michael@0 | 129 | Stop(mach_port_t shark_port) |
michael@0 | 130 | { |
michael@0 | 131 | mach_port_t reply_port = mig_get_reply_port(); |
michael@0 | 132 | |
michael@0 | 133 | struct chud_client_stop_msg msg; |
michael@0 | 134 | msg.hdr.msgh_bits = 0x1513; |
michael@0 | 135 | msg.hdr.msgh_size = sizeof(mach_msg_header_t); |
michael@0 | 136 | msg.hdr.msgh_remote_port = shark_port; |
michael@0 | 137 | msg.hdr.msgh_local_port = reply_port; |
michael@0 | 138 | msg.hdr.msgh_reserved = 0; |
michael@0 | 139 | msg.hdr.msgh_id = SHARK_MSG_STOP; |
michael@0 | 140 | |
michael@0 | 141 | JS_ASSERT(RECV_SIZEOF(struct chud_client_stop_msg) == 0x18); |
michael@0 | 142 | JS_ASSERT(sizeof(msg) == 0x2c); |
michael@0 | 143 | mach_msg_return_t result = mach_msg(&msg.hdr, MACH_SEND_MSG | MACH_RCV_MSG, |
michael@0 | 144 | RECV_SIZEOF(struct chud_client_stop_msg), |
michael@0 | 145 | sizeof(msg), reply_port, 0, 0); |
michael@0 | 146 | mig_dealloc_reply_port(reply_port); |
michael@0 | 147 | return result; |
michael@0 | 148 | } |
michael@0 | 149 | |
michael@0 | 150 | static mach_msg_return_t |
michael@0 | 151 | Disconnect(mach_port_t shark_port) |
michael@0 | 152 | { |
michael@0 | 153 | mach_port_t reply_port = mig_get_reply_port(); |
michael@0 | 154 | |
michael@0 | 155 | struct chud_client_release_msg msg; |
michael@0 | 156 | msg.hdr.msgh_bits = 0x1513; |
michael@0 | 157 | msg.hdr.msgh_size = sizeof(mach_msg_header_t); |
michael@0 | 158 | msg.hdr.msgh_remote_port = shark_port; |
michael@0 | 159 | msg.hdr.msgh_local_port = reply_port; |
michael@0 | 160 | msg.hdr.msgh_reserved = 0; |
michael@0 | 161 | msg.hdr.msgh_id = SHARK_MSG_RELEASE; |
michael@0 | 162 | msg.unk0 = 0; |
michael@0 | 163 | msg.unk1 = 1; |
michael@0 | 164 | msg.pid = getpid(); |
michael@0 | 165 | |
michael@0 | 166 | JS_ASSERT(RECV_SIZEOF(struct chud_client_release_msg) == 0x24); |
michael@0 | 167 | JS_ASSERT(sizeof(msg) == 0x2c); |
michael@0 | 168 | mach_msg_return_t result = mach_msg(&msg.hdr, MACH_SEND_MSG | MACH_RCV_MSG, |
michael@0 | 169 | RECV_SIZEOF(struct chud_client_release_msg), |
michael@0 | 170 | sizeof(msg), reply_port, 0, 0); |
michael@0 | 171 | mig_dealloc_reply_port(reply_port); |
michael@0 | 172 | return result; |
michael@0 | 173 | } |
michael@0 | 174 | |
michael@0 | 175 | static mach_port_t shark_port = 0; |
michael@0 | 176 | static bool connected = false; |
michael@0 | 177 | static bool running = false; |
michael@0 | 178 | |
michael@0 | 179 | namespace Shark { |
michael@0 | 180 | |
michael@0 | 181 | bool |
michael@0 | 182 | Start() |
michael@0 | 183 | { |
michael@0 | 184 | if (!shark_port && !(shark_port = CreatePort())) |
michael@0 | 185 | return false; |
michael@0 | 186 | if (!connected && Connect(shark_port)) |
michael@0 | 187 | return false; |
michael@0 | 188 | connected = true; |
michael@0 | 189 | if (!running && ::Start(shark_port, 0xdeadbeef)) |
michael@0 | 190 | return false; |
michael@0 | 191 | return running = true; |
michael@0 | 192 | } |
michael@0 | 193 | |
michael@0 | 194 | void |
michael@0 | 195 | Stop() |
michael@0 | 196 | { |
michael@0 | 197 | if (!shark_port || !connected) |
michael@0 | 198 | return; |
michael@0 | 199 | ::Stop(shark_port); |
michael@0 | 200 | running = false; |
michael@0 | 201 | Disconnect(shark_port); |
michael@0 | 202 | connected = false; |
michael@0 | 203 | } |
michael@0 | 204 | |
michael@0 | 205 | } |
michael@0 | 206 | |
michael@0 | 207 | #endif |