def __init__(self, lockdown=None): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() self.service = self.lockdown.startService( "com.apple.springboardservices")
def __init__(self, lockdown=None): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() self.c = self.lockdown.startService("com.apple.syslog_relay") self.c.send("watch")
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() #print s,d except: self.lockdown = LockdownClient() self.service = lockdown.startService(serviceName) self.file_write(handle, data) return s
def __init__(self, lockdown=None, serviceName='com.apple.afc', service=None): """ Constructor method of `AFCClient`. Note: `serviceName` is obsolete when `service` parameter is used. Although it will be saved as attribute. Args: `lockdown` (optional): The `LockdownClient` class that should be used for almost everything. `serviceName` (optional): Service ID of the protocol, defaults to 'com.apple.afc'. Used for abstract class purposes although you can modify if you have good reasons. `service` (optional): Useful when you already have a service running. """ if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() if service: self.service = service else: self.service = self.lockdown.startService(serviceName) self.serviceName = serviceName self.packet_num = 0
def __init__(self, lockdown = None,backupPath = None): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() try: self.udid = lockdown.getValue("", "UniqueDeviceID")#lockdown.udid except: self.lockdown = LockdownClient() self.udid = self.lockdown.getValue("", "UniqueDeviceID") self.service = self.lockdown.startService("com.apple.mobilebackup2") if not self.service: raise Exception("MobileBackup2Client init error : Could not start com.apple.mobilebackup2") if backupPath: self.backupPath = backupPath else: self.backupPath = "backups" #self.udid 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 = "" DLMessageVersionExchange = self.service.recvPlist() #print DLMessageVersionExchange version_major = DLMessageVersionExchange[1] self.service.sendPlist(["DLMessageVersionExchange", "DLVersionsOk", version_major]) DLMessageDeviceReady = self.service.recvPlist() #print DLMessageDeviceReady if DLMessageDeviceReady and DLMessageDeviceReady[0] == "DLMessageDeviceReady": #print "Got DLMessageDeviceReady" self.version_exchange() else: raise Exception("MobileBackup2Client init error %s" % 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)
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 __init__(self, lockdown=None, serviceName="com.apple.mobile.file_relay"): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() self.service = self.lockdown.startService(serviceName) self.packet_num = 0
def do_operation(self, opcode, data=""): try: self.dispatch_packet(opcode, data) return self.receive_data() except: self.lockdown = LockdownClient() self.service = lockdown.startService(serviceName) return self.do_operation(opcode, data)
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 __init__(self, lockdown=None, serviceName="com.apple.afc", service=None): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() if service: self.service = service else: self.service = self.lockdown.startService(serviceName) self.packet_num = 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()
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)
def __init__(self, lockdown=None): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() self.service = self.lockdown.startService('com.apple.mobile.installation_proxy')
class SpringboardClient(object): def __init__(self, lockdown=None): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() self.service = self.lockdown.startService( "com.apple.springboardservices") def get_iconstate(self): return self.service.sendRequest({ 'command': 'getIconState', 'formatVersion': '2' })[0] def set_iconstate(self, state): self.service.sendPlist({'command': 'setIconState', 'iconState': state}) def get_iconpngdata(self, bundleid): return self.service.sendRequest({ 'command': 'getIconPNGData', 'bundleId': bundleid })['pngData'].data def get_interface_orientation(self): response = self.service.sendRequest( {'command': 'getInterfaceOrientation'}) if response is None or 'interfaceOrientation' not in response: raise RuntimeError('Unable to retrieve interface orientation') return response['interfaceOrientation'] def get_wallpaper_pngdata(self): return self.service.sendRequest( {'command': 'getHomeScreenWallpaperPNGData'})['pngData'].data
class SpringboardClient(object): def __init__(self, lockdown=None): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() self.service = self.lockdown.startService("com.apple.springboardservices") def get_iconstate(self): return self.service.sendRequest({ 'command': 'getIconState', 'formatVersion': '2' })[0] def set_iconstate(self, state): self.service.sendPlist({ 'command': 'setIconState', 'iconState': state }) def get_iconpngdata(self, bundleid): return self.service.sendRequest({ 'command': 'getIconPNGData', 'bundleId': bundleid })['pngData'].data def get_interface_orientation(self): response = self.service.sendRequest({'command': 'getInterfaceOrientation'}) if response is None or 'interfaceOrientation' not in response: raise RuntimeError('Unable to retrieve interface orientation') return response['interfaceOrientation'] def get_wallpaper_pngdata(self): return self.service.sendRequest({'command': 'getHomeScreenWallpaperPNGData'})['pngData'].data
def __init__(self, lockdown = None,backupPath = None): 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.service = self.lockdown.startService("com.apple.mobilebackup2") 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 = "" 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)
class screenshotrClient(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
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() error = res.get("Error") if error: print res["Error"] return None return AFCClient(lockdown, service=mis)
class FileRelayClient(object): def __init__(self, lockdown=None, serviceName="com.apple.mobile.file_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 request_sources(self, sources=["UserDatabases"]): print "Downloading sources ", sources self.service.sendPlist({"Sources":sources}) res = self.service.recvPlist() if res: if res.has_key("Status"): if res["Status"] == "Acknowledged": z = "" while True: x = self.service.recv() if not x: break z += x return z return None
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("\n\x00\x00") if logFile: with open(logFile, 'a') as f: f.write(d.replace("\x00", ""))
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") self.c.send("watch") 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("\n\x00\x00") if logFile: with open(logFile, 'a') as f: f.write(d.replace("\x00", ""))
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
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))
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 __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) self.packet_num = 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)
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, afcname='com.apple.afc', completekey='tab', stdin=None, stdout=None, client=None): Cmd.__init__(self, completekey=completekey, stdin=stdin, stdout=stdout) self.lockdown = LockdownClient() self.afc = client if client else AFCClient(self.lockdown, serviceName=afcname) self.curdir = '/' self.prompt = 'AFC$ ' + self.curdir + ' ' self.complete_cat = self._complete self.complete_ls = self._complete
def __init__(self, completekey='tab', stdin=None, stdout=None, afc=None): Cmd.__init__(self, completekey=completekey, stdin=stdin, stdout=stdout) self.lockdown = LockdownClient() if afc: self.afc = afc else: self.afc = AFCClient(self.lockdown, "com.apple.afc") self.prompt = "(AFC) / " self.curdir = "/" self.complete_cat = self._complete self.complete_ls = self._complete
def __init__(self, lockdown=None, backupPath=None): 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.service = self.lockdown.startService("com.apple.mobilebackup2") 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 = "" 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)
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 __init__(self, completekey='tab', stdin=None, stdout=None, afc=None): super(AFCShell, self).__init__(self, completekey=completekey, stdin=stdin, stdout=stdout) if afc: self.afc = afc else: self.lockdown = LockdownClient() self.afc = AFCClient(self.lockdown) self.prompt = "(AFC) / " self.curdir = "/" self.complete_cat = self._complete self.complete_ls = self._complete
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() pprint(res) 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
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
def __init__(self, completekey='tab', stdin=None, stdout=None, client=None): Cmd.__init__(self, completekey=completekey, stdin=stdin, stdout=stdout) self.lockdown = LockdownClient() if client: self.afc = client else: self.afc = AFCClient(self.lockdown, "com.apple.afc") self.curdir = "/" self.prompt = "AFC$ " + self.curdir + " " self.complete_cat = self._complete self.complete_ls = self._complete
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) self.packet_num = 0 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 }) res = self.service.recvPlist() pprint(res) return res def observe_notification(self, notification): #Tells the device to send a notification on the specified event self.service.sendPlist({ "Command": "ObserveNotification", #} "Name": notification }) res = self.service.recvPlist() pprint(res) return res def get_notification(self, notification): #Checks if a notification has been sent by the device res = self.service.recvPlist() pprint(res) return res
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
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) self.packet_num = 0 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}) res = self.service.recvPlist() pprint(res) return res def observe_notification(self, notification): #Tells the device to send a notification on the specified event self.service.sendPlist({"Command": "ObserveNotification",#} "Name": notification}) res = self.service.recvPlist() pprint(res) return res def get_notification(self, notification): #Checks if a notification has been sent by the device res = self.service.recvPlist() pprint(res) return res
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"), "DeviceName": root_node.get("DeviceName"), "Display Name": root_node.get("DeviceName"), "GUID": "---", "ProductType": root_node.get("ProductType"), "ProductVersion": root_node.get("ProductVersion"), # "Serial Number": root_node.get("SerialNumber"), "Unique Identifier": self.udid.upper(), "Target Identifier": self.udid, "Target Type": "Device", "iTunes Version": "10.0.1", } info["ICCID"] = root_node.get("IntegratedCircuitCardIdentity") info["IMEI"] = root_node.get("InternationalMobileEquipmentIdentity") info["Last Backup Date"] = datetime.datetime.now() iTunesFiles = [ "ApertureAlbumPrefs", "IC-Info.sidb", "IC-Info.sidv", "PhotosFolderAlbums", "PhotosFolderName", "PhotosFolderPrefs", "iPhotoAlbumPrefs", "iTunesApplicationIDs", "iTunesPrefs", "iTunesPrefs.plist", ] 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.writePlistToString(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
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() pprint(res) 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
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 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
self.service.sendPlist({"Command": "PostNotification",#} "Name": notification}) res = self.service.recvPlist() pprint(res) return res def observe_notification(self, notification): #Tells the device to send a notification on the specified event self.service.sendPlist({"Command": "ObserveNotification",#} "Name": notification}) res = self.service.recvPlist() pprint(res) return res def get_notification(self, notification): #Checks if a notification has been sent by the device res = self.service.recvPlist() pprint(res) return res if __name__ == "__main__": lockdown = LockdownClient() ProductVersion = lockdown.getValue("", "ProductVersion") assert ProductVersion[0] >= "4" np = NPClient() np.get_notification()
class MobileBackup2Client(MobileBackupClient): def __init__(self, lockdown = None,backupPath = None): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() try: self.udid = lockdown.getValue("", "UniqueDeviceID")#lockdown.udid except: self.lockdown = LockdownClient() self.udid = self.lockdown.getValue("", "UniqueDeviceID") self.service = self.lockdown.startService("com.apple.mobilebackup2") if not self.service: raise Exception("MobileBackup2Client init error : Could not start com.apple.mobilebackup2") if backupPath: self.backupPath = backupPath else: self.backupPath = "backups" #self.udid 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 = "" DLMessageVersionExchange = self.service.recvPlist() #print DLMessageVersionExchange version_major = DLMessageVersionExchange[1] self.service.sendPlist(["DLMessageVersionExchange", "DLVersionsOk", version_major]) DLMessageDeviceReady = self.service.recvPlist() #print DLMessageDeviceReady if DLMessageDeviceReady and DLMessageDeviceReady[0] == "DLMessageDeviceReady": #print "Got DLMessageDeviceReady" self.version_exchange() else: raise Exception("MobileBackup2Client init error %s" % DLMessageDeviceReady) def __del__(self): if self.service: #print "Disconnecting" self.service.sendPlist(["DLMessageDisconnect", "___EmptyParameterString___"]) #print self.service.recvPlist() def internal_mobilebackup2_send_message(self, name, data): data["MessageName"] = name self.device_link_service_send_process_message(data) def internal_mobilebackup2_receive_message(self, name=None): res = self.device_link_service_receive_process_message() if res: if name and res["MessageName"] != name: print "MessageName does not match %s %s" % (name, str(res)) return res def version_exchange(self): self.internal_mobilebackup2_send_message("Hello", {"SupportedProtocolVersions": [2.0,2.1]}) return self.internal_mobilebackup2_receive_message("Response") def mobilebackup2_send_request(self, request, target, source, options={}): d = {"TargetIdentifier": target, "SourceIdentifier": source, "Options": options} #pprint(d) self.internal_mobilebackup2_send_message(request, d) def mobilebackup2_receive_message(self): return self.service.recvPlist() def mobilebackup2_send_status_response(self, status_code, status1="___EmptyParameterString___", status2={}): a = ["DLMessageStatusResponse", status_code, status1, status2] self.service.sendPlist(a) def mb2_handle_free_disk_space(self,msg): #DRK s = os.statvfs(self.backupPath) freeSpace = s.f_bsize * s.f_bavail #print "freeSpage %s" % freeSpace a = ["DLMessageStatusResponse", 0, freeSpace] self.service.sendPlist(a) def mb2_multi_status_add_file_error(self, errplist, path, error_code, error_message): errplist[path] = {"DLFileErrorCode": error_code, "DLFileErrorString": error_message} def mb2_handle_copy_item(self, msg): src = self.check_filename(msg[1]) dst = self.check_filename(msg[2]) if os.path.isfile(src): data = self.read_file(src) self.write_file(dst, data) else: os.makedirs(dst) self.mobilebackup2_send_status_response(0) def mb2_handle_send_file(self, filename, errplist): self.service.send_raw(filename) if not filename.startswith(self.udid): filename = self.udid + "/" + filename #print "Reading",self.check_filename(filename) #FIXME data = self.read_file(self.check_filename(filename)) if data != None: #print hexdump(data) print "Sending %s to device" % filename self.service.send_raw(chr(CODE_FILE_DATA) + data) self.service.send_raw(chr(CODE_SUCCESS)) else: #print "DATA %s" % hexdump(data) print "File %s requested from device not found" % filename self.service.send_raw(chr(CODE_ERROR_LOCAL)) self.mb2_multi_status_add_file_error(errplist, filename, ERROR_ENOENT, "Could not find the droid you were looking for ;)") def mb2_handle_send_files(self, msg): errplist = {} for f in msg[1]: self.mb2_handle_send_file(f, errplist) self.service.send("\x00\x00\x00\x00") if len(errplist): self.mobilebackup2_send_status_response(-13, "Multi status", errplist) else: self.mobilebackup2_send_status_response(0) def mb2_handle_list_directory(self, msg): path = msg[1] dirlist = {} self.mobilebackup2_send_status_response(0, status2=dirlist); def mb2_handle_make_directory(self, msg): dirname = self.check_filename(msg[1]) print "Creating directory %s" % dirname if not os.path.isdir(dirname): os.makedirs(dirname) self.mobilebackup2_send_status_response(0, "") def mb2_handle_receive_files(self, msg): done = 0 while not done: device_filename = self.service.recv_raw() if device_filename == "": break backup_filename = self.service.recv_raw() #print device_filename, backup_filename filedata = "" while True: stuff = self.service.recv_raw() if ord(stuff[0]) == CODE_FILE_DATA: filedata += stuff[1:] elif ord(stuff[0]) == CODE_SUCCESS: #print "Success" self.write_file(self.check_filename(backup_filename), filedata) break else: print "Unknown code", ord(stuff[0]) break self.mobilebackup2_send_status_response(0) def mb2_handle_move_files(self, msg): for k,v in msg[1].items(): print "Renaming %s to %s" % (self.check_filename(k),self.check_filename(v)) os.rename(self.check_filename(k),self.check_filename(v)) self.mobilebackup2_send_status_response(0) def mb2_handle_remove_files(self, msg): for filename in msg[1]: print "Removing ", self.check_filename(filename) try: filename = self.check_filename(filename) if os.path.isfile(filename): os.unlink(filename) except Exception, e: print e self.mobilebackup2_send_status_response(0)
class AFCClient(object): """ Creates a connection to the iDevice using AFC protocol. Attributes: `lockdown`: The `LockdownClient` class that should be used for almost everything. `serviceName`: The service ID of the protocol. `service`: The plist service which is running in the background. `packet_num`: Used to track number of packets sent during lifetime of the client. """ def __init__(self, lockdown=None, serviceName='com.apple.afc', service=None): """ Constructor method of `AFCClient`. Note: `serviceName` is obsolete when `service` parameter is used. Although it will be saved as attribute. Args: `lockdown` (optional): The `LockdownClient` class that should be used for almost everything. `serviceName` (optional): Service ID of the protocol, defaults to 'com.apple.afc'. Used for abstract class purposes although you can modify if you have good reasons. `service` (optional): Useful when you already have a service running. """ if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() if service: self.service = service else: self.service = self.lockdown.startService(serviceName) self.serviceName = serviceName self.packet_num = 0 def stop_session(self): """Disconnects from iDevice.""" print "Disconecting..." self.service.close() def __del__(self): self.stop_session() def dispatch_packet(self, operation, data, this_length=0): """ Dispatches an AFC packet over a client. Args: `operation`: The operation to do. See the source code for the list of constants. `data`: The data to send with header. `this_length` (optional): Not sure but, according to C libimobiledevice, it looks like size of packet + data length. """ 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): """ Receives data through an AFC client. Returns: The response of the iDevice. Raises: `AFCError` if the operation was not successful. """ 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: assert length == 8 status = int(struct.unpack("<Q", data[:8])[0]) if status != AFC_E_SUCCESS: raise AFCError(status) elif res.operation != AFC_OP_DATA: pass # print "error ?", res return data def do_operation(self, operation, data="", this_length=0): """ Dispatches a packet and returns the response. Args: `operation`: The operation to perform. `data` (optional): The data to send. `this_length` (optional): Not sure but, according to C libimobiledevice, it looks like size of packet + data length. Returns: The data that is recieved after the operation is done. """ self.dispatch_packet(operation, data, this_length) return self.receive_data() def list_to_dict(self, d): """Converts a primitive key, value array to Python compatible dictionary.""" it = iter(d.rstrip("\x00").split("\x00")) return dict(zip(it, it)) def get_device_infos(self): infos = self.do_operation(AFC_OP_GET_DEVINFO) return self.list_to_dict(infos) def get_file_info(self, filename): data = self.do_operation(AFC_OP_GET_FILE_INFO, filename) return self.list_to_dict(data) def file_open(self, filename, mode=AFC_FOPEN_RDONLY): #if filename.startswith('/var/Mobile/Media') and self.serviceName == 'com.apple.afc': # filename = filename.replace('/var/Mobile/Media', '') data = self.do_operation(AFC_OP_FILE_OPEN, struct.pack("<Q", mode) + filename + "\x00") return struct.unpack("<Q", data)[0] def file_close(self, handle): self.do_operation(AFC_OP_FILE_CLOSE, struct.pack("<Q", handle)) def file_seek(self, handle, offset, whence=os.SEEK_SET): self.do_operation(AFC_OP_FILE_SEEK, struct.pack("<QQq", handle, whence, offset)) def file_tell(self, handle): data = self.do_operation(AFC_OP_FILE_TELL, struct.pack("<Q", handle)) return struct.unpack("<Q", data)[0] def file_truncate(self, handle, size=None): if size is None: size = self.file_tell(handle) self.do_operation(AFC_OP_FILE_SET_SIZE, struct.pack("<QQ", handle, size)) 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 d = self.do_operation(AFC_OP_READ, struct.pack("<QQ", handle, toRead)) 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 for i in xrange(segments): self.do_operation(AFC_OP_WRITE, hh + data[i*MAXIMUM_WRITE_SIZE:(i+1)*MAXIMUM_WRITE_SIZE], this_length=48) if len(data) % MAXIMUM_WRITE_SIZE: self.do_operation(AFC_OP_WRITE, hh + data[segments*MAXIMUM_WRITE_SIZE:], this_length=48) def make_link(self, target, linkname, link_type=AFC_SYMLINK): self.do_operation(AFC_OP_MAKE_LINK, struct.pack("<Q", link_type) + target + "\x00" + linkname + "\x00") def remove_path(self, path): self.do_operation(AFC_OP_REMOVE_PATH, path + "\x00") def rename_path(self, old, new): self.do_operation(AFC_OP_RENAME_PATH, old + "\x00" + new + "\x00") def read_directory(self, dirname): data = self.do_operation(AFC_OP_READ_DIR, dirname) return data.rstrip("\x00").split("\x00") def make_directory(self, dirname): self.do_operation(AFC_OP_MAKE_DIR, dirname) def dir_walk(self, dirname): # root = dirname dirs = [] files = [] for fd in self.read_directory(dirname): if fd in ('.', '..', ''): # is it ever be '' ? continue if self.get_file_info(posixpath.join(dirname, fd)).get('st_ifmt') == 'S_IFDIR': dirs.append(fd) else: files.append(fd) yield dirname, dirs, files # if dirs != [], continue iterating using recursion if dirs: for d in dirs: for walk_result in self.dir_walk(posixpath.join(dirname, d)): yield walk_result def remove_directory(self, dirname): for d in self.read_directory(dirname): if d in ('.', '..', ''): continue path = posixpath.join(dirname, d) if self.get_file_info(path).get("st_ifmt") == "S_IFDIR": self.remove_directory(path) else: self.remove_path(path) assert len(self.read_directory(dirname)) == 2 # "." and ".." self.remove_path(dirname)
help="Output location", type="string") (options, args) = parser.parse_args() if options.output: output = options.output elif sys.platform == "win32": import win32pipe, win32file output = Win32Pipe() 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
class AFCClient(object): def __init__(self, lockdown=None, serviceName="com.apple.afc", service=None): if lockdown: self.lockdown = lockdown else: self.lockdown = LockdownClient() if service: self.service = service else: self.service = self.lockdown.startService(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 = lockdown.startService(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") if data: handle = struct.unpack("<Q", data)[0] return handle 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() #print s,d except: self.lockdown = LockdownClient() self.service = lockdown.startService(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,dir,file_list=[]): d = os.path.abspath(dir) file_list = [] for file in [file for file in self.read_directory(d) if not file in [".",".."]]: path = os.path.join(d,file) info = self.get_file_info(path) if info: if info['st_ifmt'] == 'S_IFDIR': file_list += self.dir_walk(path,file_list) info['path'] = path file_list.append(info) return file_list