def device_information(lockdown, nocolor): """ Print system information. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: device_info = DeviceInfo(dvt) print_object({ 'system': device_info.system_information(), 'hardware': device_info.hardware_information(), 'network': device_info.network_information(), }, colored=not nocolor)
def parse_live_profile_session(lockdown, count, class_filter, subclass_filter, pid, tid, show_tid): """ Parse core profiling information. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: trace_codes_map = DeviceInfo(dvt).trace_codes() with CoreProfileSessionTap(dvt, class_filter, subclass_filter) as tap: events_parser = KdebugEventsParser(trace_codes_map) for event in tap.watch_events(count): if tid is not None and event.tid != tid: continue try: process = tap.thread_map[event.tid] except KeyError: process = ProcessData(pid=-1, name='') if pid is not None and process.pid != pid: continue events_parser.feed(event) parsed = events_parser.fetch() if parsed is None: continue formatted_data = f'{str(tap.parse_event_time(parsed.ktraces[0].timestamp)):<27}' formatted_data += f'{hex(event.tid):<12}' if show_tid else '' process_rep = (f'{process.name}({process.pid})' if process.pid != -1 else f'Error: tid {event.tid}') formatted_data += f'{process_rep:<27}' print(formatted_data + str(parsed))
def test_hardware_information(lockdown): """ Test getting hardware information. :param pymobiledevice3.lockdown.LockdownClient lockdown: Lockdown client. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: hardware_info = DeviceInfo(dvt).hardware_information() assert hardware_info['numberOfCpus'] > 0
def test_network_information(lockdown): """ Test getting network information. :param pymobiledevice3.lockdown.LockdownClient lockdown: Lockdown client. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: network_info = DeviceInfo(dvt).network_information() assert network_info['lo0'] == 'Loopback'
def test_ls_failure(lockdown): """ Test listing a directory. :param pymobiledevice3.lockdown.LockdownClient lockdown: Lockdown client. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: with pytest.raises(DvtDirListError): DeviceInfo(dvt).ls('Directory that does not exist')
def proclist(lockdown, nocolor): """ show process list """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: processes = DeviceInfo(dvt).proclist() for process in processes: if 'startDate' in process: process['startDate'] = str(process['startDate']) print_object(processes, colored=not nocolor)
def test_system_information(lockdown): """ Test getting system information. :param pymobiledevice3.lockdown.LockdownClient lockdown: Lockdown client. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: system_info = DeviceInfo(dvt).system_information() assert '_deviceDescription' in system_info and system_info[ '_deviceDescription'].startswith('Build Version')
def sysmon_processes(lockdown, fields, attributes): """ show currently running processes information. """ if fields is not None: fields = fields.split(',') count = 0 with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: sysmontap = Sysmontap(dvt) with sysmontap as sysmon: for row in sysmon: if 'Processes' in row: processes = row['Processes'].items() count += 1 if count > 1: # give some time for cpuUsage field to populate break device_info = DeviceInfo(dvt) for pid, process in processes: attrs = sysmontap.process_attributes_cls(*process) skip = False if attributes is not None: for filter_attr in attributes: filter_attr, filter_value = filter_attr.split('=') if str(getattr(attrs, filter_attr)) != filter_value: skip = True break if skip: continue print(f'{attrs.name} ({attrs.pid})') attrs_dict = asdict(attrs) attrs_dict['execname'] = device_info.execname_for_pid(pid) for name, value in attrs_dict.items(): if (fields is None) or (name in fields): print(f'\t{name}: {value}')
def __init__(self, dvt): self._device_info = DeviceInfo(dvt) process_attributes = list(self._device_info.request_information('sysmonProcessAttributes')) system_attributes = list(self._device_info.request_information('sysmonSystemAttributes')) self.process_attributes_cls = dataclasses.make_dataclass('SysmonProcessAttributes', process_attributes) self.system_attributes_cls = dataclasses.make_dataclass('SysmonSystemAttributes', system_attributes) config = { 'ur': 500, # Output frequency ms 'bm': 0, 'procAttrs': process_attributes, 'sysAttrs': system_attributes, 'cpuUsage': True, 'sampleInterval': 500000000 } super().__init__(dvt, self.IDENTIFIER, config)
def show_dirlist(device_info: DeviceInfo, dirname, recursive=False): try: filenames = device_info.ls(dirname) except DvtDirListError: return for filename in filenames: filename = posixpath.join(dirname, filename) print(filename) if recursive: show_dirlist(device_info, filename, recursive=recursive)
def test_ls(lockdown): """ Test listing a directory. :param pymobiledevice3.lockdown.LockdownClient lockdown: Lockdown client. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: ls = set(DeviceInfo(dvt).ls('/')) assert { 'usr', 'bin', 'etc', 'var', 'private', 'lib', 'Applications', 'Developer' } <= ls
def test_launch(lockdown): """ Test launching a process. :param pymobiledevice3.lockdown.LockdownClient lockdown: Lockdown client. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: pid = ProcessControl(dvt).launch('com.apple.mobilesafari') assert pid with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: for process in DeviceInfo(dvt).proclist(): if pid == process['pid']: assert process['name'] == 'MobileSafari'
def live_profile_session(lockdown, count, class_filter, subclass_filter, pid, tid, timestamp, event_name, func_qual, show_tid, process_name, args): """ Print core profiling information. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: trace_codes_map = DeviceInfo(dvt).trace_codes() with CoreProfileSessionTap(dvt, class_filter, subclass_filter) as tap: for event in tap.watch_events(count): if event.eventid in trace_codes_map: name = trace_codes_map[event.eventid] + f' ({hex(event.eventid)})' else: # Some event IDs are not public. name = hex(event.eventid) try: if tid is not None and event.tid != tid: continue try: process = tap.thread_map[event.tid] except KeyError: process = ProcessData(pid=-1, name='') if pid is not None and process.pid != pid: continue formatted_data = '' if timestamp: formatted_data += f'{str(tap.parse_event_time(event.timestamp)):<27}' formatted_data += f'{name:<58}' if event_name else '' if func_qual: try: formatted_data += f'{DgbFuncQual(event.func_qualifier).name:<15}' except ValueError: formatted_data += f'''{'Error':<16}''' formatted_data += f'{hex(event.tid):<12}' if show_tid else '' if process_name: process_rep = (f'{process.name}({process.pid})' if process.pid != -1 else f'Error: tid {event.tid}') formatted_data += f'{process_rep:<27}' if process_name else '' formatted_data += f'{str(event.args.data):<34}' if args else '' print(formatted_data) except (ValueError, KeyError): pass
def trace_codes(lockdown, nocolor): """ Print system information. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: device_info = DeviceInfo(dvt) print_object({hex(k): v for k, v in device_info.trace_codes().items()}, colored=not nocolor)
def get_process_data(lockdown, name): with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: processes = DeviceInfo(dvt).proclist() return [process for process in processes if process['name'] == name][0]
def ls(lockdown, path, recursive): """ List directory. """ with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: show_dirlist(DeviceInfo(dvt), path, recursive=recursive)
def test_parsing_bsc_open(lockdown): """ Test parsing BSC_open. :param pymobiledevice3.lockdown.LockdownClient lockdown: Lockdown client. """ events = [ Container({ 'timestamp': 458577723780, 'args': Container(data=( b'\x88\x95\xd7m\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00\x00\x00P\x88\xd7m\x01\x00\x00\x00'), value=ListContainer([6137812360, 0, 0, 6137808976]), offset1=245320, offset2=245352, length=32), 'tid': 53906, 'debugid': 67895317, 'eventid': 0x40c0014, 'class': 4, 'subclass': 12, 'code': 5, 'func_qualifier': 1, 'cpuid': 1, 'unused': 0 }), Container({ 'timestamp': 458577724301, 'args': Container(data=b'\xd5\xcbv\x1d7\xeb\xebL/System/Library/CoreServ', value=ListContainer([ 5542782388359580629, 3417499243072017199, 3420891154821048652, 8534995652679200579 ]), offset1=245384, offset2=245416, length=32), 'tid': 53906, 'debugid': 50397329, 'eventid': 0x3010090, 'class': 3, 'subclass': 1, 'code': 36, 'func_qualifier': 1, 'cpuid': 1, 'unused': 0 }), Container({ 'timestamp': 458577724316, 'args': Container(data=b'ices/SpringBoard.app/SpringBoard', value=ListContainer([ 8246182380979970921, 7237954681621147241, 8246182380930359598, 7237954681621147241 ]), offset1=245448, offset2=245480, length=32), 'tid': 53906, 'debugid': 50397330, 'eventid': 0x3010090, 'class': 3, 'subclass': 1, 'code': 36, 'func_qualifier': 2, 'cpuid': 1, 'unused': 0 }), Container({ 'timestamp': 458577726009, 'args': Container(data=( b'\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' b'\x00\x00+\x00\x00\x00\x00\x00\x00\x00'), value=ListContainer([0, 8, 0, 43]), offset1=245512, offset2=245544, length=32), 'tid': 53906, 'debugid': 67895318, 'eventid': 0x40c0014, 'class': 4, 'subclass': 12, 'code': 5, 'func_qualifier': 2, 'cpuid': 1, 'unused': 0 }) ] with DvtSecureSocketProxyService(lockdown=lockdown) as dvt: trace_codes_map = DeviceInfo(dvt).trace_codes() parser = KdebugEventsParser(trace_codes_map) for event in events: parser.feed(event) bsc_open = parser.fetch() assert bsc_open.path == '/System/Library/CoreServices/SpringBoard.app/SpringBoard' assert bsc_open.ktraces == events assert bsc_open.flags == [BscOpenFlags.O_RDONLY] assert bsc_open.result == 'fd: 8'