def test_get_crash_log(self):
        mux = USBMux()
        if not mux.devices:
            mux.process(0.1)
        if len(mux.devices) == 0:
            print("no real device found")
            self.no_device = True
            return
        udid = mux.devices[0].serial

        procname = "QQ"
        lockdown = LockdownClient(udid)
        self.service = lockdown.startService("com.apple.crashreportcopymobile")
        client = AFCClient(lockdown,service=self.service)
        afc_shell = AFCShell(client=client)
        remote_crash_path = '/'
        dest_path = '/tmp'
        local_crashes =[]
        print('udid:', udid)
        for _dirname, _dirs, files in afc_shell.afc.dir_walk(remote_crash_path):

            for filename in files:
                if procname in filename:
                    remote_crash_file = os.path.join(remote_crash_path, filename)
                    data = afc_shell.afc.get_file_contents(remote_crash_file)
                    local_crash_file = os.path.join(dest_path, filename)
                    local_crashes.append(local_crash_file)
                    with open(local_crash_file, 'wb') as fp:
                        fp.write(data)
        print(local_crashes)
示例#2
0
    def file_read(self, handle, sz):
        MAXIMUM_READ_SIZE = 1 << 16
        data = ""
        if PY3:
            data = b""
        while sz > 0:
            if sz > MAXIMUM_READ_SIZE:
                toRead = MAXIMUM_READ_SIZE
            else:
                toRead = sz
            try:
                self.dispatch_packet(AFC_OP_READ,
                                     struct.pack("<QQ", handle, toRead))
                s, d = self.receive_data()
            except:
                import traceback
                traceback.print_exc()
                self.lockdown = LockdownClient()
                self.service = self.lockdown.startService("com.apple.afc")
                return self.file_read(handle, sz)

            if s != AFC_E_SUCCESS:
                break
            sz -= toRead
            data += d
        return data
    def test_get_crash_log(self):
        mux = USBMux()
        if not mux.devices:
            mux.process(0.1)
        if len(mux.devices) == 0:
            print("no real device found")
            self.no_device = True
            return
        udid = mux.devices[0].serial

        procname = "QQ"
        lockdown = LockdownClient(udid)
        self.service = lockdown.startService("com.apple.crashreportcopymobile")
        client = AFCClient(lockdown, service=self.service)
        afc_shell = AFCShell(client=client)
        remote_crash_path = '/'
        dest_path = '/tmp'
        local_crashes = []
        print('udid:', udid)
        for _dirname, _dirs, files in afc_shell.afc.dir_walk(
                remote_crash_path):

            for filename in files:
                if procname in filename:
                    remote_crash_file = os.path.join(remote_crash_path,
                                                     filename)
                    data = afc_shell.afc.get_file_contents(remote_crash_file)
                    local_crash_file = os.path.join(dest_path, filename)
                    local_crashes.append(local_crash_file)
                    with open(local_crash_file, 'wb') as fp:
                        fp.write(data)
        print(local_crashes)
示例#4
0
 def install(self, ipa_path, options=None, handler=None, *args):
     '''安装应用程序
     
     :param ipa_path: 安装包的路径
     :type ipa_path: str
     :return: boolean - 安装是否成功
     '''
     print "上传安装包..."
     afc_client = AFCClient(self.lockdown)
     tmp_ipa = "t%d.ipa" % time.time()
     with open(ipa_path, "rb") as f:
         ipa_content = f.read()
         afc_client.set_file_contents("/" + tmp_ipa, ipa_content)
         print "上传完毕"
     print "开始安装"
     cmd = {"Command": "Install", "PackagePath": tmp_ipa}
     if options:
         cmd.update(options)
     self.lockdown = LockdownClient(self.udid)
     self.service = self.lockdown.startService(
         "com.apple.mobile.installation_proxy")
     self.service.sendPlist(cmd)
     ret = self.wait_completion(handler, args)
     if ret[0]:
         print "安装成功"
     else:
         print "安装失败:%s" % ret[1]
     return ret
示例#5
0
 def file_write(self, handle, data):
     MAXIMUM_WRITE_SIZE = 1 << 15
     hh = struct.pack("<Q", handle)
     segments = len(data) / MAXIMUM_WRITE_SIZE
     try:
         for i in xrange(segments):
             self.dispatch_packet(
                 AFC_OP_WRITE,
                 hh +
                 data[i * MAXIMUM_WRITE_SIZE:(i + 1) * MAXIMUM_WRITE_SIZE],
                 this_length=48)
             s, d = self.receive_data()
             if s != AFC_E_SUCCESS:
                 self.logger.error("file_write error: %d", s)
                 break
         if len(data) % MAXIMUM_WRITE_SIZE:
             self.dispatch_packet(AFC_OP_WRITE,
                                  hh + data[segments * MAXIMUM_WRITE_SIZE:],
                                  this_length=48)
             s, d = self.receive_data()
     except:
         self.lockdown = LockdownClient()
         self.service = self.lockdown.startService(self.serviceName)
         self.file_write(handle, data)
     return s
示例#6
0
 def do_operation(self, opcode, data=""):
     try:
         self.dispatch_packet(opcode, data)
         return self.receive_data()
     except:
         self.lockdown = LockdownClient()
         self.service = self.lockdown.startService(self.serviceName)
         return self.do_operation(opcode, data)
示例#7
0
    def __init__(self, lockdown=None, serviceName="com.apple.mobile.diagnostics_relay"):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        self.service = self.lockdown.startService(serviceName)
        self.packet_num = 0
示例#8
0
    def __init__(self, lockdown=None):

        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        self.service = self.lockdown.startService(
            "com.apple.mobile.installation_proxy")
示例#9
0
 def __init__(self, lockdown=None):
     if lockdown:
         self.lockdown = lockdown
     else:
         self.lockdown = LockdownClient()
     self.c = self.lockdown.startService("com.apple.syslog_relay")
     if self.c:
         self.c.send("watch")
     else:
         sys.exit(1)
示例#10
0
 def start(self):
     lockdown = LockdownClient(self.udid)
     ios_version = lockdown.allValues['ProductVersion']
     if DT.compare_version(ios_version, '11.0') >= 0:  # iOS11真机以上不支持数据分割
         self._partial_supported = False
     self.web_inspector = lockdown.startService("com.apple.webinspector")
     self._sock = self.web_inspector.s
     self._sock.setblocking(False)
     self._sock.settimeout(5)
     self.init_inspector()
示例#11
0
 def test_get_device_info(self):
     udid = self._get_device()
     print('udid:%s' % udid)
     if udid is None:
         print("no real device found")
         return
     lockdown = LockdownClient(udid)
     lockdown.startService("com.apple.afc")
     info = lockdown.allValues
     print(info)
     self.assertIsInstance(info, dict, 'Query device information error')
示例#12
0
 def __init__(self, bundle_id, udid):
     super(RealDeviceProtocol, self).__init__(bundle_id, udid)
     self._partial_supported = True
     lockdown = LockdownClient(self.udid)
     ios_version = lockdown.allValues['ProductVersion']
     if DT.compare_version(ios_version, '11.0') >= 0:  # iOS11真机以上不支持数据分割
         self._partial_supported = False
     self.web_inspector = lockdown.startService("com.apple.webinspector")
     self._sock = self.web_inspector.s
     self._sock.setblocking(False)
     self._sock.settimeout(5)
示例#13
0
 def test_get_device_info(self):
     udid = self._get_device()
     print('udid:%s' % udid)
     if udid is None:
         print("no real device found")
         return
     lockdown = LockdownClient(udid)
     lockdown.startService("com.apple.afc")
     info = lockdown.allValues
     print(info)
     self.assertIsInstance(info, dict, 'Query device information error')
 def setUp(self):
     mux = USBMux()
     if not mux.devices:
         mux.process(0.1)
     if len(mux.devices) == 0:
         print("no real device found")
         self.no_device = True
         return
     self.udid = mux.devices[0].serial
     self.lockdownclient = LockdownClient(self.udid)
     self.service = self.lockdownclient.startService("com.apple.mobile.installation_proxy")
示例#15
0
    def __init__(self, lockdown=None, serviceName="com.apple.mobile.file_relay"):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        ProductVersion = self.lockdown.getValue("", "ProductVersion")

        if ProductVersion[0] >= "8":
            raise DeviceVersionNotSupported

        self.service = self.lockdown.startService(serviceName)
        self.packet_num = 0
示例#16
0
    def __init__(self, filename, lockdown=None):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        self.service = self.lockdown.startService("com.apple.pcapd")

        self.f = open(filename, "wb")
        self.f.write(
            struct.pack("<LHHLLLL", 0xa1b2c3d4, 2, 4, 0, 0, 65535,
                        LINKTYPE_ETHERNET))

        self._stop = False
示例#17
0
    def __init__(self, lockdown=None, serviceName='com.apple.mobile.screenshotr'):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()
        # Starting Screenshot service
        self.service = self.lockdown.startService(serviceName)

        # hand check
        DLMessageVersionExchange = self.service.recvPlist()
        #assert len(DLMessageVersionExchange) == 2
        version_major = DLMessageVersionExchange[1]
        self.service.sendPlist(
            ["DLMessageVersionExchange", "DLVersionsOk", version_major])
        DLMessageDeviceReady = self.service.recvPlist()
示例#18
0
def get_device_info(udid=None, keyname=None):
    '''获取iOS设备的相关属性信息
    
    :param udid: iOS设备的udid
    :type udid: str
    :param keyname: iOS设备的特定信息字段的名称
    :type keyname: str
    :returns: str - iOS设备的信息
    '''
    lockdown = LockdownClient(udid)
    lockdown.startService("com.apple.afc")
    if keyname:
        return lockdown.allValues.get(keyname)
    else:
        return lockdown.allValues
示例#19
0
def house_arrest(lockdown, applicationId):
    try:
        mis = lockdown.startService("com.apple.mobile.house_arrest")
    except:
        lockdown = LockdownClient()
        mis = lockdown.startService("com.apple.mobile.house_arrest")

    if mis == None:
        return
    mis.sendPlist({"Command": "VendDocuments", "Identifier": applicationId})
    res = mis.recvPlist()
    if res.get("Error"):
        print "Unable to Lookup the selected application: You probably trying to access to a system app..."
        return None
    return AFCClient(lockdown, service=mis)
示例#20
0
def house_arrest(lockdown, applicationId):
    try:
        mis = lockdown.startService("com.apple.mobile.house_arrest")
    except:
        lockdown = LockdownClient()
        mis = lockdown.startService("com.apple.mobile.house_arrest")

    if mis == None:
        return
    mis.sendPlist({"Command": "VendDocuments", "Identifier": applicationId})
    res = mis.recvPlist()
    if res.get("Error"):
        print("Unable to Lookup the selected application: You probably trying to access to a system app...")
        return None
    return AFCClient(lockdown, service=mis)
示例#21
0
 def file_write(self, handle, data):
     MAXIMUM_WRITE_SIZE = 1 << 15
     hh = struct.pack("<Q", handle)
     segments = int(len(data) / MAXIMUM_WRITE_SIZE)
     try:
         for i in range(segments):
             self.dispatch_packet(AFC_OP_WRITE,
                                  hh +
                                  data[
                                      i * MAXIMUM_WRITE_SIZE:(i + 1) * MAXIMUM_WRITE_SIZE],
                                  this_length=48)
             s, d = self.receive_data()
             if s != AFC_E_SUCCESS:
                 print("file_write error %d" % s)
                 break
         if len(data) % MAXIMUM_WRITE_SIZE:
             self.dispatch_packet(AFC_OP_WRITE,
                                  hh + data[segments * MAXIMUM_WRITE_SIZE:],
                                  this_length=48)
             s, d = self.receive_data()
     except ImportError:
         self.lockdown = LockdownClient()
         self.service = self.lockdown.startService(self.serviceName)
         self.file_write(handle, data)
     return s
示例#22
0
def get_screenshot(udid=None, filepath="/tmp/screenshot.png"):
    '''获取iOS设备的屏幕快照
    
    :param udid: iOS设备的udid
    :type udid: str
    :param filepath: 屏幕快照的存储路径
    :type filepath: str
    :returns: boolean - 截图是否成功
    '''
    result = False
    tiff_file = tempfile.NamedTemporaryFile(suffix='.tiff')
    tiff_file_path = tiff_file.name
    lockdown = LockdownClient(udid)
    screenshot = screenshotr(lockdown)
    data = screenshot.take_screenshot()
    with open(tiff_file_path, "wb") as fd:
        fd.write(data)
    screenshot.stop_session()
    try:
        args = [
            "/usr/bin/sips", "-s format png", tiff_file_path, "--out", filepath
        ]
        check_call(" ".join(args), shell=True, stderr=STDOUT)
        result = True
    except CalledProcessError, e:
        print e.output
示例#23
0
class screenshotr(object):

    def __init__(self, lockdown=None, serviceName='com.apple.mobile.screenshotr'):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()
        # Starting Screenshot service
        self.service = self.lockdown.startService(serviceName)

        # hand check
        DLMessageVersionExchange = self.service.recvPlist()
        #assert len(DLMessageVersionExchange) == 2
        version_major = DLMessageVersionExchange[1]
        self.service.sendPlist(
            ["DLMessageVersionExchange", "DLVersionsOk", version_major])
        DLMessageDeviceReady = self.service.recvPlist()

    def stop_session(self):
        self.service.close()

    def take_screenshot(self):
        self.service.sendPlist(
            ['DLMessageProcessMessage', {'MessageType': 'ScreenShotRequest'}])
        res = self.service.recvPlist()

        assert len(res) == 2
        assert res[0] == "DLMessageProcessMessage"

        if res[1].get('MessageType') == 'ScreenShotReply':
            data = res[1]['ScreenShotData'].data
            return data
        return None
示例#24
0
    def file_read(self, handle, sz):
        MAXIMUM_READ_SIZE = 1 << 16
        data = ""
        if PY3:
            data = b""
        while sz > 0:
            if sz > MAXIMUM_READ_SIZE:
                toRead = MAXIMUM_READ_SIZE
            else:
                toRead = sz
            try:
                self.dispatch_packet(AFC_OP_READ, struct.pack("<QQ", handle, toRead))
                s, d = self.receive_data()
            except:
                import traceback
                traceback.print_exc()
                self.lockdown = LockdownClient()
                self.service = self.lockdown.startService("com.apple.afc")
                return  self.file_read(handle, sz)

            if s != AFC_E_SUCCESS:
                break
            sz -= toRead
            data += d
        return data
 def __init__(self, lockdown=None, udid=None, logger=None):
     self.logger = logger or logging.getLogger(__name__)
     self.lockdown = lockdown if lockdown else LockdownClient(udid=udid)
     ProductVersion = self.lockdown.getValue("", "ProductVersion")
     if ProductVersion[0] >= "5":
         raise DeviceVersionNotSupported
     self.start()
示例#26
0
class Syslog(object):
    def __init__(self, lockdown=None):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()
        self.c = self.lockdown.startService("com.apple.syslog_relay")
        if self.c:
            self.c.send("watch")
        else:
            sys.exit(1)

    def watch(self, procName=None, logFile=None):

        while True:
            d = self.c.recv(4096)

            if not d:
                break

            if procName:
                procFilter = re.compile(procName, re.IGNORECASE)
                if len(d.split(" ")) > 4 and not procFilter.search(d):
                    continue

            print(d.strip(b"\n\x00\x00"))

            if logFile:
                with open(logFile, 'a') as f:
                    f.write(d.replace("\x00", ""))
示例#27
0
    def __init__(self,
                 udid=None,
                 bid='com.tencent.sng.test.gn',
                 sandbox="VendContainer",
                 lockdown=None):
        self.lockdown = lockdown if lockdown else LockdownClient(udid)
        self.bid = bid
        self.service = None
        retry = 5
        while retry > 0:
            try:
                self.service = self.lockdown.startService(
                    "com.apple.mobile.house_arrest")
                break
            except:
                import traceback
                traceback.print_exc()
                retry -= 1
                time.sleep(5)
        if self.service is None:
            raise RuntimeError('Connect to house_arrest failed')

        self.service.sendPlist({"Command": sandbox, "Identifier": bid})
        self.afc_shell = AFCShell(client=self)
        status = self.service.recvPlist()
        if status.has_key(
                'Error') and status['Error'] == "ApplicationLookupFailed":
            raise RuntimeWarning('ApplicationLookupFailed')
        if status.has_key('Status') and status['Status'] != 'Complete':
            raise RuntimeWarning('House arrest service launch failed')

        super(SandboxClient, self).__init__(self.lockdown,
                                            service=self.service)
示例#28
0
def main():
    parser = OptionParser(usage="%prog")
    parser.add_option("-l",
                      "--list",
                      dest="list",
                      action="store_true",
                      default=False,
                      help="List installed profiles")
    parser.add_option("-i",
                      "--install",
                      dest="install",
                      action="store",
                      metavar="FILE",
                      help="Install profile")
    parser.add_option("-r",
                      "--remove",
                      dest="remove",
                      action="store",
                      metavar="IDENTIFIER",
                      help="Remove profile")
    (options, args) = parser.parse_args()

    if not options.list and not options.install and not options.remove:
        parser.print_help()
        return
    lockdown = LockdownClient()
    mc = MobileConfigService(lockdown)

    if options.list:
        pprint(mc.GetProfileList())
    elif options.install:
        mc.InstallProfile(read_file(options.install))
    elif options.remove:
        pprint(mc.RemoveProfile(options.remove))
示例#29
0
class Syslog(object):

    def __init__(self, lockdown=None):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()
        self.c = self.lockdown.startService("com.apple.syslog_relay")
        if self.c:
            self.c.send("watch")
        else:
            sys.exit(1)

    def watch(self, procName=None, logFile=None):

        while True:
            d = self.c.recv(4096)

            if not d:
                break

            if procName:
                procFilter = re.compile(procName, re.IGNORECASE)
                if len(d.split(" ")) > 4 and not procFilter.search(d):
                    continue

            print(d.strip(b"\n\x00\x00"))

            if logFile:
                with open(logFile, 'a') as f:
                    f.write(d.replace("\x00", ""))
示例#30
0
 def __init__(self,
              lockdown=None,
              serviceName="com.apple.mobile.house_arrest",
              service=None):
     self.serviceName = serviceName
     self.lockdown = lockdown if lockdown else LockdownClient()
     self.service = service if service else self.lockdown.startService(
         self.serviceName)
示例#31
0
 def __init__(self, lockdown=None, udid=None, logger=None):
     self.logger = logger or logging.getLogger(__name__)
     self.lockdown = lockdown if lockdown else LockdownClient(udid=udid)
     self.c = self.lockdown.startService("com.apple.syslog_relay")
     if self.c:
         self.c.send("watch")
     else:
         exit(1)
 def test_install_app(self):
     if self.no_device:
         return
     ipa_path = os.path.join(os.path.expanduser("~"), "Downloads/app/DemoApp.ipa")
     tmp_ipa = "/t%d.ipa" % time.time()
     with open(ipa_path, "rb") as f:
         ipa_content = f.read()
         afc = AFCClient(self.lockdownclient)
         afc.set_file_contents(tmp_ipa, ipa_content)
         print("Upload completed")
     print("Starting installation")
     cmd = {"Command":"Install", "PackagePath": tmp_ipa}
     self.lockdownclient = LockdownClient(self.udid)
     self.service = self.lockdownclient.startService("com.apple.mobile.installation_proxy")
     self.service.sendPlist(cmd)
     result, err = self.wait_completion()
     self.assertTrue(result, 'install_app failed: %s' % err)
示例#33
0
 def __init__(self,
              lockdown=None,
              serviceName="com.apple.mobile.notification_proxy",
              udid=None,
              logger=None):
     self.logger = logger or logging.getLogger(__name__)
     self.lockdown = lockdown if lockdown else LockdownClient(udid=udid)
     self.service = self.lockdown.startService(serviceName)
    def __init__(self, lockdown=None, serviceName="com.apple.mobile.diagnostics_relay"):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        self.service = self.lockdown.startService(serviceName)
        self.packet_num = 0
示例#35
0
 def do_operation(self, opcode, data=""):
     try:
         self.dispatch_packet(opcode, data)
         return self.receive_data()
     except:
         self.lockdown = LockdownClient()
         self.service = self.lockdown.startService(self.serviceName)
         return  self.do_operation(opcode, data)
    def __init__(self,lockdown=None):

        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        self.service = self.lockdown.startService("com.apple.mobile.installation_proxy")
示例#37
0
    def __init__(self, lockdown=None, backupPath=None, password=""):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        ProductVersion = self.lockdown.getValue("", "ProductVersion")
        if ProductVersion[0] < "5":
            raise DeviceVersionNotSupported

        self.udid = lockdown.getValue("", "UniqueDeviceID")
        self.willEncrypt = lockdown.getValue("com.apple.mobile.backup",
                                             "WillEncrypt")
        self.escrowBag = lockdown.getValue('', 'EscrowBag')

        self.service = self.lockdown.startServiceWithEscrowBag(
            "com.apple.mobilebackup2", self.escrowBag)
        if not self.service:
            raise Exception(
                "MobileBackup2 init error : Could not start com.apple.mobilebackup2"
            )

        if backupPath:
            self.backupPath = backupPath
        else:
            self.backupPath = "backups"
        if not os.path.isdir(self.backupPath):
            os.makedirs(self.backupPath, 0o0755)

        print(
            "Starting new com.apple.mobilebackup2 service with working dir: %s"
            % self.backupPath)

        self.password = password
        DLMessageVersionExchange = self.service.recvPlist()
        version_major = DLMessageVersionExchange[1]
        self.service.sendPlist(
            ["DLMessageVersionExchange", "DLVersionsOk", version_major])
        DLMessageDeviceReady = self.service.recvPlist()
        if DLMessageDeviceReady and DLMessageDeviceReady[
                0] == "DLMessageDeviceReady":
            self.version_exchange()
        else:
            raise Exception("MobileBackup2 init error %s" %
                            DLMessageDeviceReady)
示例#38
0
 def __init__(self,
              lockdown=None,
              serviceName="com.apple.afc",
              service=None):
     self.serviceName = serviceName
     self.lockdown = lockdown if lockdown else LockdownClient()
     self.service = service if service else self.lockdown.startService(
         self.serviceName)
     self.packet_num = 0
示例#39
0
 def __init__(self, afcname='com.apple.afc', completekey='tab', stdin=None, stdout=None, client=None, udid=None, logger=None):
     Cmd.__init__(self, completekey=completekey, stdin=stdin, stdout=stdout)
     self.logger = logger or logging.getLogger(__name__)
     self.lockdown = LockdownClient()
     self.afc = client if client else AFCClient(self.lockdown, serviceName=afcname, udid=udid)
     self.curdir = '/'
     self.prompt = 'AFC$ ' + self.curdir + ' '
     self.complete_cat = self._complete
     self.complete_ls = self._complete
示例#40
0
 def __init__(self, lockdown=None):
     if lockdown:
         self.lockdown = lockdown
     else:
         self.lockdown = LockdownClient()
     self.c = self.lockdown.startService("com.apple.syslog_relay")
     if self.c:
         self.c.send("watch")
     else:
         sys.exit(1)
示例#41
0
    def __init__(self, filename, lockdown=None):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        self.service = self.lockdown.startService("com.apple.pcapd")

        self.f = open(filename, "wb")
        self.f.write(struct.pack("<LHHLLLL", 0xa1b2c3d4, 2, 4, 0, 0, 65535, LINKTYPE_ETHERNET))

        self._stop = False
示例#42
0
    def __init__(self, lockdown=None, serviceName="com.apple.mobile.file_relay"):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        ProductVersion = self.lockdown.getValue("", "ProductVersion")

        if ProductVersion[0] >= "8":
            raise DeviceVersionNotSupported

        self.service = self.lockdown.startService(serviceName)
        self.packet_num = 0
示例#43
0
class FileRelay(object):

    def __init__(self, lockdown=None, serviceName="com.apple.mobile.file_relay"):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        ProductVersion = self.lockdown.getValue("", "ProductVersion")

        if ProductVersion[0] >= "8":
            raise DeviceVersionNotSupported

        self.service = self.lockdown.startService(serviceName)
        self.packet_num = 0

    def stop_session(self):
        print("Disconecting...")
        self.service.close()

    def request_sources(self, sources=["UserDatabases"]):
        self.service.sendPlist({"Sources": sources})
        while 1:
            res = self.service.recvPlist()
            if res:
                s = res.get("Status")
                if s == "Acknowledged":
                    z = ""
                    while True:
                        x = self.service.recv()
                        if not x:
                            break
                        z += x
                    return z
                else:
                    print(res.get("Error"))
                    break
        return None
示例#44
0
class PcapClient(object):
    def __init__(self, filename, lockdown=None):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        self.service = self.lockdown.startService("com.apple.pcapd")

        self.f = open(filename, "wb")
        self.f.write(struct.pack("<LHHLLLL", 0xa1b2c3d4, 2, 4, 0, 0, 65535, LINKTYPE_ETHERNET))

        self._stop = False

    def __del__(self):
        self.stop()

    def writePacket(self, packet):
        t = time.time()
        #TODO check milisecond conversion
        pkthdr = struct.pack("<LLLL", int(t), int(t*1000000 % 1000000), len(packet), len(packet))
        data = pkthdr + packet
        self.f.write(data)
        self.f.flush()
        return True

    def capturePackets(self):
        while not self._stop:
            d = self.service.recvPlist()
            if not d:
                break
            data = d.data
            hdrsize, xxx, packet_size = struct.unpack(">LBL", data[:9])
            flags1, flags2, offset_to_ip_data, zero = struct.unpack(">LLLL", data[9:0x19])
            assert hdrsize >= 0x19
            interfacetype = data[0x19:hdrsize].strip("\x00")
            t = time.time()
            print interfacetype, packet_size, t
            packet = data[hdrsize:]
            assert packet_size == len(packet)
            if offset_to_ip_data == 0:
                #add fake ethernet header for pdp packets
                packet = "\xBE\xEF" * 6 + "\x08\x00" + packet
            if not self.writePacket(packet):
                break

    def stop(self):
        self._stop = True
        self.f.close()
示例#45
0
    def __init__(self, lockdown=None):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        ProductVersion = self.lockdown.getValue("", "ProductVersion")
        if ProductVersion[0] >= "5":
            raise DeviceVersionNotSupported

        self.service = self.lockdown.startService("com.apple.mobilebackup")
        self.udid = self.lockdown.udid
        DLMessageVersionExchange = self.service.recvPlist()
        version_major = DLMessageVersionExchange[1]
        self.service.sendPlist(["DLMessageVersionExchange", "DLVersionsOk", version_major])
        DLMessageDeviceReady = self.service.recvPlist()
        if DLMessageDeviceReady and DLMessageDeviceReady[0] == "DLMessageDeviceReady":
            print "Got DLMessageDeviceReady"
 def __init__(self, lockdown=None, serviceName="com.apple.mobile.notification_proxy"):
     if lockdown:
         self.lockdown = lockdown
     else:
         self.lockdown = LockdownClient()
     self.service = self.lockdown.startService(serviceName)
示例#47
0
    (options, args) = parser.parse_args()
    if sys.platform == "win32":
        import win32pipe
        import win32file
        output = Win32Pipe()

    else:
        if options.output:
            path = options.output
        else:
            _, path = mkstemp(prefix="device_dump_", suffix=".pcap", dir=".")
        print("Recording data to: %s" % path)
        output = PcapOut(path)

    lockdown = LockdownClient()
    pcap = lockdown.startService("com.apple.pcapd")

    while True:
        d = pcap.recvPlist()
        if not d:
            break
        data = d.data
        hdrsize, xxx, packet_size = struct.unpack(">LBL", data[:9])
        flags1, flags2, offset_to_ip_data, zero = struct.unpack(">LLLL", data[
                                                                9:0x19])

        assert hdrsize >= 0x19
        interfacetype = data[0x19:hdrsize].strip("\x00")
        t = time.time()
        print(interfacetype, packet_size, t)
示例#48
0
class MobileBackup(object):

    def __init__(self, lockdown=None):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        ProductVersion = self.lockdown.getValue("", "ProductVersion")
        if ProductVersion[0] >= "5":
            raise DeviceVersionNotSupported

        self.service = self.lockdown.startService("com.apple.mobilebackup")
        self.udid = self.lockdown.udid
        DLMessageVersionExchange = self.service.recvPlist()
        version_major = DLMessageVersionExchange[1]
        self.service.sendPlist(
            ["DLMessageVersionExchange", "DLVersionsOk", version_major])
        DLMessageDeviceReady = self.service.recvPlist()
        if DLMessageDeviceReady and DLMessageDeviceReady[0] == "DLMessageDeviceReady":
            print("Got DLMessageDeviceReady")

    def check_filename(self, name):
        if name.find("../") != -1:
            raise Exception("HAX, sneaky dots in path %s" % name)
        if not name.startswith(self.backupPath):
            if name.startswith(self.udid):
                name = os.path.join(self.backupPath, name)
                return name
            name = os.path.join(self.backupPath, self.udid, name)
            return name
        return name

    def read_file(self, filename):
        filename = self.check_filename(filename)
        if os.path.isfile(filename):
            with open(filename, 'rb') as f:
                data = f.read()
                f.close()
                return data
        return None

    def write_file(self, filename, data):
        filename = self.check_filename(filename)
        with open(filename, 'wb') as f:
            f.write(data)
            f.close()

    def create_info_plist(self):
        root_node = self.lockdown.allValues
        # print pprint(root_node)
        info = {"BuildVersion": root_node.get("BuildVersion") or "",
                "DeviceName":  root_node.get("DeviceName") or "",
                "Display Name": root_node.get("DeviceName") or "",
                "GUID": "---",
                "ProductType": root_node.get("ProductType") or "",
                "ProductVersion": root_node.get("ProductVersion") or "",
                "Serial Number": root_node.get("SerialNumber") or "",
                "Unique Identifier": self.udid.upper(),
                "Target Identifier": self.udid,
                "Target Type": "Device",
                "iTunes Version": "10.0.1"
                }
        info["ICCID"] = root_node.get("IntegratedCircuitCardIdentity") or ""
        info["IMEI"] = root_node.get(
            "InternationalMobileEquipmentIdentity") or ""
        info["Last Backup Date"] = datetime.datetime.now()

        afc = AFCClient(self.lockdown)
        iTunesFilesDict = {}
        iTunesFiles = afc.read_directory("/iTunes_Control/iTunes/")

        for i in iTunesFiles:
            data = afc.get_file_contents("/iTunes_Control/iTunes/" + i)
            if data:
                iTunesFilesDict[i] = plistlib.Data(data)
        info["iTunesFiles"] = iTunesFilesDict

        iBooksData2 = afc.get_file_contents("/Books/iBooksData2.plist")
        if iBooksData2:
            info["iBooks Data 2"] = plistlib.Data(iBooksData2)

        info["iTunes Settings"] = self.lockdown.getValue("com.apple.iTunes")
        print("Creating %s" % os.path.join(self.udid, "Info.plist"))
        self.write_file(os.path.join(self.udid, "Info.plist"),
                        plistlib.dumps(info))

    def ping(self, message):
        self.service.sendPlist(["DLMessagePing", message])
        print("ping response", self.service.recvPlist())

    def device_link_service_send_process_message(self, msg):
        return self.service.sendPlist(["DLMessageProcessMessage", msg])

    def device_link_service_receive_process_message(self):
        req = self.service.recvPlist()
        if req:
            assert req[0] == "DLMessageProcessMessage"
            return req[1]

    def send_file_received(self):
        return self.device_link_service_send_process_message({"BackupMessageTypeKey": "kBackupMessageBackupFileReceived"})

    def request_backup(self):
        req = {"BackupComputerBasePathKey": "/",
               "BackupMessageTypeKey": "BackupMessageBackupRequest",
               "BackupProtocolVersion": "1.6"
               }
        self.create_info_plist()
        self.device_link_service_send_process_message(req)
        res = self.device_link_service_receive_process_message()
        if not res:
            return
        if res["BackupMessageTypeKey"] != "BackupMessageBackupReplyOK":
            print(res)
            return
        self.device_link_service_send_process_message(res)

        filedata = ""
        f = None
        outpath = None
        while True:
            res = self.service.recvPlist()
            if not res or res[0] != "DLSendFile":
                if res[0] == "DLMessageProcessMessage":
                    if res[1].get("BackupMessageTypeKey") == "BackupMessageBackupFinished":
                        print("Backup finished OK !")
                        # TODO BackupFilesToDeleteKey
                        plistlib.writePlist(
                            res[1]["BackupManifestKey"], self.check_filename("Manifest.plist"))
                break
            data = res[1].data
            info = res[2]
            if not f:
                outpath = self.check_filename(info.get("DLFileDest"))
                print(info["DLFileAttributesKey"][
                      "Filename"], info.get("DLFileDest"))
                f = open(outpath + ".mddata", "wb")
            f.write(data)
            if info.get("DLFileStatusKey") == DEVICE_LINK_FILE_STATUS_LAST_HUNK:
                self.send_file_received()
                f.close()
                if not info.get("BackupManifestKey", False):
                    plistlib.writePlist(
                        info.get("BackupFileInfo"), outpath + ".mdinfo")
                f = None
示例#49
0
class AFCClient(object):
    def __init__(self, lockdown=None, serviceName="com.apple.afc", service=None):
        self.serviceName = serviceName
        self.lockdown = lockdown if lockdown else LockdownClient()
        self.service = service if service else self.lockdown.startService(self.serviceName)
        self.packet_num = 0


    def stop_session(self):
        print "Disconecting..."
        self.service.close()


    def dispatch_packet(self, operation, data, this_length=0):
        afcpack = Container(magic=AFCMAGIC,
                   entire_length=40 + len(data),
                   this_length=40 + len(data),
                   packet_num=self.packet_num,
                   operation=operation)
        if this_length:
            afcpack.this_length = this_length
        header = AFCPacket.build(afcpack)
        self.packet_num += 1
        self.service.send(header + data)


    def receive_data(self):
        res = self.service.recv(40)
        status = AFC_E_SUCCESS
        data = ""
        if res:
            res = AFCPacket.parse(res)
            assert res["entire_length"] >= 40
            length = res["entire_length"] - 40
            data = self.service.recv_exact(length)
            if res.operation == AFC_OP_STATUS:
                if length != 8:
                    print "Status length != 8"
                status = struct.unpack("<Q", data[:8])[0]
            elif res.operation != AFC_OP_DATA:
                pass#print "error ?", res
        return status, data


    def do_operation(self, opcode, data=""):
        try:
            self.dispatch_packet(opcode, data)
            return self.receive_data()
        except:
            self.lockdown = LockdownClient()
            self.service = self.lockdown.startService(self.serviceName)
            return  self.do_operation(opcode, data)


    def list_to_dict(self, d):
        t = d.split("\x00")
        t = t[:-1]

        assert len(t) % 2 == 0
        res = {}
        for i in xrange(len(t)/2):
            res[t[i*2]] = t[i*2 + 1]
        return res


    def get_device_infos(self):
        status, infos = self.do_operation(AFC_OP_GET_DEVINFO)
        if status == AFC_E_SUCCESS:
            return self.list_to_dict(infos)


    def read_directory(self, dirname):
        status, data = self.do_operation(AFC_OP_READ_DIR, dirname)
        if status == AFC_E_SUCCESS:
            return filter(lambda x:x!="", data.split("\x00"))
        return []


    def make_directory(self, dirname):
        status, data = self.do_operation(AFC_OP_MAKE_DIR, dirname)
        return status


    def remove_directory(self, dirname):
        info = self.get_file_info(dirname)
        if not info or info.get("st_ifmt") != "S_IFDIR":
            print "remove_directory: %s not S_IFDIR" % dirname
            return

        for d in self.read_directory(dirname):
            if d == "." or d == ".." or d == "":
                continue

            info = self.get_file_info(dirname + "/" + d)
            if info.get("st_ifmt") == "S_IFDIR":
                self.remove_directory(dirname + "/" + d)
            else:
                print dirname + "/" + d
                self.file_remove(dirname + "/" + d)
        assert len(self.read_directory(dirname)) == 2 #.. et .
        return self.file_remove(dirname)


    def get_file_info(self, filename):
        status, data = self.do_operation(AFC_OP_GET_FILE_INFO, filename)
        if status == AFC_E_SUCCESS:
            return self.list_to_dict(data)


    def make_link(self, target, linkname, type=AFC_SYMLINK):
        status, data = self.do_operation(AFC_OP_MAKE_LINK, struct.pack("<Q", type) + target + "\x00" + linkname + "\x00")
        print "make_link", status
        return status


    def file_open(self, filename, mode=AFC_FOPEN_RDONLY):
        status, data = self.do_operation(AFC_OP_FILE_OPEN, struct.pack("<Q", mode) + filename + "\x00")
        return struct.unpack("<Q", data)[0] if data else None


    def file_close(self, handle):
        status, data = self.do_operation(AFC_OP_FILE_CLOSE, struct.pack("<Q", handle))
        return status


    def file_remove(self, filename):
        status, data = self.do_operation(AFC_OP_REMOVE_PATH, filename + "\x00")
        return status


    def file_rename(self, old, new):
        status, data = self.do_operation(AFC_OP_RENAME_PATH, old + "\x00" + new + "\x00")
        return status


    def file_read(self, handle, sz):
        MAXIMUM_READ_SIZE = 1 << 16
        data = ""
        while sz > 0:
            if sz > MAXIMUM_READ_SIZE:
                toRead = MAXIMUM_READ_SIZE
            else:
                toRead = sz
            try:
                self.dispatch_packet(AFC_OP_READ, struct.pack("<QQ", handle, toRead))
                s, d = self.receive_data()
            except:
                self.lockdown = LockdownClient()
                self.service = self.lockdown.startService("com.apple.afc")
                return  self.file_read(handle, sz)

            if s != AFC_E_SUCCESS:
                break
            sz -= toRead
            data += d
        return data


    def file_write(self, handle, data):
        MAXIMUM_WRITE_SIZE = 1 << 15
        hh = struct.pack("<Q", handle)
        segments = len(data) / MAXIMUM_WRITE_SIZE
        try:
            for i in xrange(segments):
                self.dispatch_packet(AFC_OP_WRITE,
                                 hh + data[i*MAXIMUM_WRITE_SIZE:(i+1)*MAXIMUM_WRITE_SIZE],
                                     this_length=48)
                s, d = self.receive_data()
                if s != AFC_E_SUCCESS:
                    print "file_write error %d" % s
                    break
            if len(data) % MAXIMUM_WRITE_SIZE:
                self.dispatch_packet(AFC_OP_WRITE,
                                     hh + data[segments*MAXIMUM_WRITE_SIZE:],
                                     this_length=48)
                s, d = self.receive_data()
        except:
            self.lockdown = LockdownClient()
            self.service = self.lockdown.startService(self.serviceName)
            self.file_write(handle,data)
        return s


    def get_file_contents(self, filename):
        info = self.get_file_info(filename)
        if info:
            if info['st_ifmt'] == 'S_IFLNK':
                filename =  info['LinkTarget']

            if info['st_ifmt'] == 'S_IFDIR':
                print "%s is directory..." % filename
                return

            print "Reading %s" % filename
            h = self.file_open(filename)
            if not h:
                return
            d = self.file_read(h, int(info["st_size"]))
            self.file_close(h)
            return d
        return


    def set_file_contents(self, filename, data):
        h = self.file_open(filename, AFC_FOPEN_WR)
        if not h:
            return
        d = self.file_write(h, data)
        self.file_close(h)


    def dir_walk(self, dirname):
        dirs = []
        files = []
        for fd in self.read_directory(dirname):
            if fd in ('.', '..', ''):
                continue
            infos = self.get_file_info(posixpath.join(dirname, fd))
            if infos and infos.get('st_ifmt') == 'S_IFDIR':
                dirs.append(fd)
            else:
                files.append(fd)

        yield dirname, dirs, files

        if dirs:
            for d in dirs:
                for walk_result in self.dir_walk(posixpath.join(dirname, d)):
                    yield walk_result
class NPClient(object):

    def __init__(self, lockdown=None, serviceName="com.apple.mobile.notification_proxy"):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()
        self.service = self.lockdown.startService(serviceName)

    def stop_session(self):
        print("Disconecting...")
        self.service.close()

    def post_notification(self, notification):
        # Sends a notification to the device's notification_proxy.

        self.service.sendPlist({"Command": "PostNotification",
                                "Name": notification})

        self.service.sendPlist({"Command": "Shutdown"})
        res = self.service.recvPlist()
        pprint(res)
        if res:
            if res.get("Command") == "ProxyDeath":
                return res.get("Command")
            else:
                print("Got unknown NotificationProxy command %s" %
                      res.get("Command"))
                pprint(res)
        return None

    def observe_notification(self, notification):
        # Tells the device to send a notification on the specified event

        print("Observing %s" % notification)
        self.service.sendPlist({"Command": "ObserveNotification",
                                "Name": notification})

    def get_notification(self, notification):
        # Checks if a notification has been sent by the device

        res = self.service.recvPlist()
        if res:
            if res.get("Command") == "RelayNotification":
                if res.get("Name"):
                    return res.get("Name")

            elif res.get("Command") == "ProxyDeath":
                print("NotificationProxy died!")
            else:
                print("Got unknown NotificationProxy command %s" %
                      res.get("Command"))
                pprint(res)
        return None

    def notifier(self, name, args=None):

        if args == None:
            return None

        self.observe_notification(args.get("notification"))

        while args.get("running") == True:
            np_name = self.get_notification(args.get("notification"))
            if np_name:
                userdata = args.get("userdata")
                try:
                    _thread.start_new_thread(
                        args.get("callback"), (np_name, userdata, ))
                except:
                    print("Error: unable to start thread")

    def subscribe(self, notification, cb, data=None):

        np_data = {
            "running": True,
            "notification": notification,
            "callback": cb,
            "userdata": data,
        }

        try:
            _thread.start_new_thread(
                self.notifier, ("NotificationProxyNotifier_" + notification, np_data, ))
        except:
            print("Error: unable to start thread")

        while(1):
            time.sleep(1)
class installation_proxy(object):

    def __init__(self,lockdown=None):

        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        self.service = self.lockdown.startService("com.apple.mobile.installation_proxy")


    def watch_completion(self,handler=None,*args):
        while True:
            z =  self.service.recvPlist()
            if not z:
                break
            completion = z.get("PercentComplete")
            if completion:
                if handler:
                    print "calling handler"
                    handler(completion,*args)
                print "%s %% Complete" % z.get("PercentComplete")
            if z.get("Status") == "Complete":
                return z.get("Status")
        return "Error"

    def send_cmd_for_bid(self,bundleID, cmd="Archive", options=None, handler=None, *args):
        cmd = {"Command": cmd, "ApplicationIdentifier": bundleID }
        if options:
            cmd.update(options)
        self.service.sendPlist(cmd)
        #print "%s : " % (cmd, bundleID)
        print "%s : %s\n" % (cmd, self.watch_completion(handler, *args))


    def uninstall(self,bundleID, options=None, handler=None, *args):
        self.send_cmd_for_bid(bundleID, "Uninstall", options, handler, args)

    def install_or_upgrade(self, ipaPath, cmd="Install", options=None, handler=None, *args):
        afc = AFCClient(self.lockdown)
        afc.set_file_contents("/" + os.path.basename(ipaPath), open(ipaPath,"rb").read())
        cmd = {"Command":cmd, "PackagePath": os.path.basename(ipaPath)}
        if options:
            cmd.update(options)
        self.service.sendPlist(cmd)
#         print "%s : " % (cmd, bundleID)
        print "%s : %s\n" % (cmd, self.watch_completion(handler, args))


    def install(self,ipaPath, options=None, handler=None, *args):
        return self.install_or_upgrade(ipaPath, "Install", client_options, handler, args)


    def upgrade(self,ipaPath, options=None, handler=None, *args):
        return self.install_or_upgrade(ipaPath, "Upgrade", client_options, handler, args)


    def apps_info(self):
        self.service.sendPlist({"Command": "Lookup"})
        return self.service.recvPlist().get('LookupResult')


    def archive(self,bundleID, options=None, handler=None, *args):
        self.send_cmd_for_bid(bundleID, "Archive", options, handler, args)


    def restore_archive(self,bundleID, options=None, handler=None, *args):
        self.send_cmd_for_bid(bundleID, "Restore", client_options, handler, args)


    def remove_archive(self,bundleID, options={}, handler=None, *args):
        self.send_cmd_for_bid(bundleID, "RemoveArchive", options, handler, args)


    def archives_info(self):
        return self.service.sendRequest({"Command": "LookupArchive"}).get("LookupResult")


    def search_path_for_bid(self, bid):
        path = None
        for a in self.get_apps(appTypes=["User","System"]):
            if a.get("CFBundleIdentifier") == bid:
                path = a.get("Path")+"/"+a.get("CFBundleExecutable")
        return path


    def get_apps(self,appTypes=["User"]):
        return [app for app in self.apps_info().values()
                if app.get("ApplicationType") in appTypes]


    def print_apps(self, appType=["User"]):
        for app in self.get_apps(appType):
            print ("%s : %s => %s" %  (app.get("CFBundleDisplayName"),
                                      app.get("CFBundleIdentifier"),
                                      app.get("Path") if app.get("Path")
                                      else app.get("Container"))).encode('utf-8')


    def get_apps_bid(self,appTypes=["User"]):
        return [app["CFBundleIdentifier"]
                for app in self.get_apps()
                if app.get("ApplicationType") in appTypes]


    def close(self):
        self.service.close()

    def __del__(self):
        self.close()
class InstallationProxyTest(unittest.TestCase):

    def setUp(self):
        mux = USBMux()
        if not mux.devices:
            mux.process(0.1)
        if len(mux.devices) == 0:
            print("no real device found")
            self.no_device = True
            return
        self.udid = mux.devices[0].serial
        self.lockdownclient = LockdownClient(self.udid)
        self.service = self.lockdownclient.startService("com.apple.mobile.installation_proxy")

    def wait_completion(self, handler=None, *args):
        while True:
            z = self.service.recvPlist()
            print(type(z), z)
            if not z:
                break
            completion = z.get("PercentComplete")
            if completion:
                if handler:
                    handler(completion, *args)
                print("%s: %s%% Complete" % (z.get("Status"), completion))
            else:
                if z.get("Status") == "Complete" or ("Status" not in z and "CFBundleIdentifier" in z):
                    return (True, "")
                else:
                    return (False, z.get("ErrorDescription"))

    def test_install_app(self):
        if self.no_device:
            return
        ipa_path = os.path.join(os.path.expanduser("~"), "Downloads/app/DemoApp.ipa")
        tmp_ipa = "/t%d.ipa" % time.time()
        with open(ipa_path, "rb") as f:
            ipa_content = f.read()
            afc = AFCClient(self.lockdownclient)
            afc.set_file_contents(tmp_ipa, ipa_content)
            print("Upload completed")
        print("Starting installation")
        cmd = {"Command":"Install", "PackagePath": tmp_ipa}
        self.lockdownclient = LockdownClient(self.udid)
        self.service = self.lockdownclient.startService("com.apple.mobile.installation_proxy")
        self.service.sendPlist(cmd)
        result, err = self.wait_completion()
        self.assertTrue(result, 'install_app failed: %s' % err)

    def test_uninstall_app(self):
        if self.no_device:
            return
        bundle_id = "com.gotohack.test.demo"
        cmd = {"Command": "Uninstall", "ApplicationIdentifier": bundle_id}
        self.service.sendPlist(cmd)
        result, err = self.wait_completion()
        self.assertTrue(result, 'uninstall_app failed: %s' % err)

    def test_apps_info(self):
        if self.no_device:
            return
        self.service.sendPlist({"Command": "Lookup"})
        print(self.service.recvPlist())

    def test_list_apps(self, app_type='user'):
        if self.no_device:
            return
        options = {}
        if app_type == 'system':
            options["ApplicationType"] = "System"
        elif app_type == 'user':
            options["ApplicationType"] = "User"
        options["ReturnAttributes"] = ["CFBundleIdentifier",
                                       "CFBundleName", ]
        self.service.sendPlist({"Command": "Browse", "ClientOptions": options})
        apps = []
        while True:
            z = self.service.recvPlist()
            if z.get("Status") == "BrowsingApplications":
                apps.extend(z["CurrentList"])
            elif z.get("Status") == "Complete":
                break
            else:
                raise Exception(z.get("ErrorDescription"))
        print(apps)

    def tearDown(self):
        if not self.no_device and self.service:
            self.service.close()
class DIAGClient(object):
    def __init__(self, lockdown=None, serviceName="com.apple.mobile.diagnostics_relay"):
        if lockdown:
            self.lockdown = lockdown
        else:
            self.lockdown = LockdownClient()

        self.service = self.lockdown.startService(serviceName)
        self.packet_num = 0


    def stop_session(self):
        print "Disconecting..."
        self.service.close()


    def query_mobilegestalt(self, MobileGestalt=MobileGestaltKeys.split("\n")):
        self.service.sendPlist({"Request": "MobileGestalt",
                                "MobileGestaltKeys": MobileGestalt})

        res = self.service.recvPlist()
        d = res.get("Diagnostics")
        if d:
            return d.get("MobileGestalt")
        return None


    def action(self, action="Shutdown", flags=None):
        self.service.sendPlist({"Request": action })
        res = self.service.recvPlist()
        return res.get("Diagnostics")


    def restart(self):
        return self.action("Restart")


    def shutdown(self):
        return self.action("Shutdown")


    def diagnostics(self, diagType="All"):
        self.service.sendPlist({"Request": diagType})
        res = self.service.recvPlist()
        if res:
            return res.get("Diagnostics")
        return None


    def ioregistry_entry(self, name=None, ioclass=None):
        d = {}
        if name:
            d["EntryName"] = name

        if ioclass:
            d["EntryClass"] = ioclass

        d["Request"] = "IORegistry"

        self.service.sendPlist(d)
        res = self.service.recvPlist()
        pprint(res)
        if res:
            return res.get("Diagnostics")
        return None


    def ioregistry_plane(self, plane=""):
        d = {}
        if plane:
            d["CurrentPlane"] = plane

        else:
            d["CurrentPlane"] = ""
        d["Request"] = "IORegistry"

        self.service.sendPlist(d)
        res = self.service.recvPlist()
        dd = res.get("Diagnostics")
        if dd:
            return dd.get("IORegistry")
        return None