def populateUI(self):

        self.historyRecords = plistutils.readPlist(self.filename)["WebHistoryDates"]

        index = 0
        for record in self.historyRecords:

            element = QtGui.QTreeWidgetItem(None)
            element.setText(0, str(index))

            if "lastVisitedDate" in record.keys():
                dateUnix = float(record["lastVisitedDate"]) + 978307200  # JAN 1 1970
                dateStr = datetime.fromtimestamp(dateUnix).strftime("%Y-%m-%d %H:%M:%S")
                element.setText(1, dateStr)

            if "title" in record.keys():
                title = record["title"]
            else:
                title = record[""]
            element.setText(2, title)

            # url saved in hidden column for context menu
            element.setText(3, record[""])

            self.ui.historyTree.addTopLevelItem(element)

            index += 1
Example #2
0
	def populateUI(self):
	
		self.historyRecords = plistutils.readPlist(self.filename)['WebHistoryDates']
		
		index = 0
		for record in self.historyRecords:

			element = QtGui.QTreeWidgetItem(None)
			element.setText(0, str(index))			
			
			if ('lastVisitedDate' in record.keys()):
				dateUnix = float(record['lastVisitedDate']) + 978307200 #JAN 1 1970
				dateStr = datetime.fromtimestamp(dateUnix).strftime('%Y-%m-%d %H:%M:%S')
				element.setText(1, dateStr)	
			
			if ('title' in record.keys()):
				title = record['title']
			else:
				title = record['']
			element.setText(2, title)
			
			# url saved in hidden column for context menu
			element.setText(3, record[''])
			
			self.ui.historyTree.addTopLevelItem(element)
			
			index += 1			
	def retrieveStatusKeys(self):
		statusProperties = []
		statusPlist = plistutils.readPlist(self.statusFileName)
		
		for key in statusPlist.keys():
			statusProperties.append([key, statusPlist[key]])
		
		return statusProperties
	def retrieveApps(self):
		appsList = []
		manifestPlist = plistutils.readPlist(self.manifestFileName)
		
		for key in manifestPlist['Applications'].keys():
			appsList.append([key, manifestPlist['Applications'][key]['CFBundleVersion'] ])
		
		return appsList
	def retrieveManifestKeys(self):
		manifestProperties = []
		manifestPlist = plistutils.readPlist(self.manifestFileName)
		
		manifestProperties.append(["Backup Computer Name", manifestPlist['Lockdown']['com.apple.iTunes.backup']['LastBackupComputerName'] ])
		manifestProperties.append(["Encrypted Backup", manifestPlist['IsEncrypted'] ])
		manifestProperties.append(["Passcode Set", manifestPlist['WasPasscodeSet'] ])
		
		return manifestProperties
Example #6
0
    def onTreeClick(self):

        # retrieving selected network
        currentSelectedElement = self.ui.documentsTree.currentItem()
        if (currentSelectedElement): pass
        else: return

        documents = plistutils.readPlist(self.filename)['SafariStateDocuments']

        currentTabIndex = int(currentSelectedElement.text(0))
        currentTab = documents[currentTabIndex]
        currentList = currentTab['SafariStateDocumentBackForwardList']

        currentOpenElement = currentTab['SafariStateDocumentBackForwardList'][
            'current']

        self.ui.listTree.clear()

        index = 0
        for element in currentList['entries']:

            try:
                title = element['title']
            except:
                title = "<non title>"

            titleElement = QtGui.QTreeWidgetItem(None)
            titleElement.setText(0, title)
            titleElement.setText(1, element[''])
            self.ui.listTree.addTopLevelItem(titleElement)

            urlElement = QtGui.QTreeWidgetItem(titleElement)
            urlElement.setText(0, element[''])
            self.ui.listTree.addTopLevelItem(urlElement)

            if (index == currentOpenElement):
                titleElement.setBackground(0, QtCore.Qt.yellow)

            index = index + 1

        # look for page appearance cache
        cacheFileName = "%s.png" % currentTab['SafariStateDocumentUUID']
        cacheFile = os.path.join(
            self.backup_path,
            plugins_utils.realFileName(self.cursor,
                                       filename=cacheFileName,
                                       domaintype="HomeDomain"))
        if (os.path.isfile(cacheFile)):
            pic = QtGui.QPixmap(cacheFile).scaled(200, 200,
                                                  QtCore.Qt.KeepAspectRatio)
            self.ui.thumbLabel.setPixmap(pic)
            self.ui.thumbLabel.show()
        else:
            self.ui.thumbLabel.hide()
	def populateUI(self):
	
		self.networks = plistutils.readPlist(self.filename)['List of known networks']
		
		index = 0
		for network in self.networks:
			element = QtGui.QTreeWidgetItem(None)
			element.setText(0, str(index))			
			element.setText(1, self.getNetworkName(network))
			self.ui.networksTree.addTopLevelItem(element)
			
			index += 1
    def populateUI(self):

        self.networks = plistutils.readPlist(
            self.filename)['List of known networks']

        index = 0
        for network in self.networks:
            element = QtGui.QTreeWidgetItem(None)
            element.setText(0, str(index))
            element.setText(1, self.getNetworkName(network))
            self.ui.networksTree.addTopLevelItem(element)

            index += 1
	def retrieveInfoKeys(self):
		infoProperties = []
		infoPlist = plistutils.readPlist(self.infoFileName)
		
		keysToBlockInInfoPlist = [
			"iBooks Data 2",
			"iTunes Settings",
			"iTunes Files"
		]
		
		for key in infoPlist.keys():
			if (key not in keysToBlockInInfoPlist):
				infoProperties.append([key, infoPlist[key]])
		
		return infoProperties
	def onTreeClick(self):
		
		# retrieving selected network
		currentSelectedElement = self.ui.documentsTree.currentItem()
		if (currentSelectedElement): pass
		else: return
		
		documents = plistutils.readPlist(self.filename)['SafariStateDocuments']
		
		currentTabIndex = int(currentSelectedElement.text(0))
		currentTab = documents[currentTabIndex]
		currentList = currentTab['SafariStateDocumentBackForwardList']
		
		currentOpenElement = currentTab['SafariStateDocumentBackForwardList']['current']
		
		self.ui.listTree.clear()
		
		index = 0
		for element in currentList['entries']:
		
			try:
				title = element['title']
			except:
				title = "<non title>"

			titleElement = QtGui.QTreeWidgetItem(None)
			titleElement.setText(0, title)
			titleElement.setText(1, element[''])
			self.ui.listTree.addTopLevelItem(titleElement)

			urlElement = QtGui.QTreeWidgetItem(titleElement)
			urlElement.setText(0, element[''])			
			self.ui.listTree.addTopLevelItem(urlElement)
			
			if (index == currentOpenElement):
				titleElement.setBackground(0, QtCore.Qt.yellow)		
			
			index = index + 1
		
		# look for page appearance cache
		cacheFileName = "%s.png"%currentTab['SafariStateDocumentUUID']
		cacheFile = os.path.join(self.backup_path, plugins_utils.realFileName(self.cursor, filename=cacheFileName, domaintype="HomeDomain"))
		if (os.path.isfile(cacheFile)):
			pic = QtGui.QPixmap(cacheFile).scaled(200, 200, QtCore.Qt.KeepAspectRatio)	
			self.ui.thumbLabel.setPixmap(pic) 
			self.ui.thumbLabel.show() 
		else:
			self.ui.thumbLabel.hide()
    def onTreeClick(self):

        # retrieving selected network
        currentSelectedElement = self.ui.networksTree.currentItem()
        if (currentSelectedElement): pass
        else: return

        signatures = plistutils.readPlist(self.filename)['Signatures']

        currentNetworkIndex = int(currentSelectedElement.text(0))
        currentNetworkServices = signatures[currentNetworkIndex]['Services']

        networkDescr = signatures[currentNetworkIndex]['Identifier']
        networkDescrParts = networkDescr.split(";")
        networkDescr = "\n".join(networkDescrParts)
        self.ui.networkLabel.setText(networkDescr)

        self.ui.servicesTree.clear()

        for service in currentNetworkServices:

            serviceNode = QtGui.QTreeWidgetItem(None)
            serviceNode.setText(0, "service")
            self.ui.servicesTree.addTopLevelItem(serviceNode)
            serviceNode.setExpanded(True)

            for serviceKey in service.keys():

                subserviceNode = QtGui.QTreeWidgetItem(serviceNode)
                subserviceNode.setText(0, serviceKey)
                self.ui.servicesTree.addTopLevelItem(subserviceNode)
                subserviceNode.setExpanded(True)

                if (serviceKey == "ServiceID"):
                    subserviceNode.setText(1, service['ServiceID'])
                    continue

                for element in service[serviceKey].keys():

                    elementNode = QtGui.QTreeWidgetItem(subserviceNode)
                    elementNode.setText(0, element)
                    text = service[serviceKey][element]
                    if (type(text) == type([1, 2])):
                        text = ", ".join(text)
                    elementNode.setText(1, text)
                    self.ui.servicesTree.addTopLevelItem(elementNode)
                    elementNode.setExpanded(True)
	def onTreeClick(self):
		
		# retrieving selected network
		currentSelectedElement = self.ui.networksTree.currentItem()
		if (currentSelectedElement): pass
		else: return
		
		signatures = plistutils.readPlist(self.filename)['Signatures']
		
		currentNetworkIndex = int(currentSelectedElement.text(0))
		currentNetworkServices = signatures[currentNetworkIndex]['Services']
		
		networkDescr = signatures[currentNetworkIndex]['Identifier']
		networkDescrParts = networkDescr.split(";")
		networkDescr = "\n".join(networkDescrParts)
		self.ui.networkLabel.setText(networkDescr)
		
		self.ui.servicesTree.clear()
		
		for service in currentNetworkServices:
			
			serviceNode = QtGui.QTreeWidgetItem(None)
			serviceNode.setText(0, "service")
			self.ui.servicesTree.addTopLevelItem(serviceNode)
			serviceNode.setExpanded(True)
			
			for serviceKey in service.keys():
				
				subserviceNode = QtGui.QTreeWidgetItem(serviceNode)
				subserviceNode.setText(0, serviceKey)
				self.ui.servicesTree.addTopLevelItem(subserviceNode)
				subserviceNode.setExpanded(True)

				if (serviceKey == "ServiceID"): 
					subserviceNode.setText(1, service['ServiceID'])
					continue
				
				for element in service[serviceKey].keys():
				
					elementNode = QtGui.QTreeWidgetItem(subserviceNode)
					elementNode.setText(0, element)
					text = service[serviceKey][element]
					if (type(text) == type([1,2])):
						text = ", ".join(text)
					elementNode.setText(1, text)
					self.ui.servicesTree.addTopLevelItem(elementNode)
					elementNode.setExpanded(True)
	def populateUI(self):
		
		documents = plistutils.readPlist(self.filename)['SafariStateDocuments']
		
		index = 0
		for document in documents:
		
			documentTitle = document['SafariStateDocumentTitle']
			documentTimestamp = document['SafariStateDocumentLastViewedTime'] + 978307200 #JAN 1 1970
			documentTimestamp = datetime.fromtimestamp(documentTimestamp).strftime('%Y-%m-%d %H:%M:%S')
			
			newElement = QtGui.QTreeWidgetItem(None)
			newElement.setText(0, str(index))
			newElement.setText(1, documentTimestamp)
			newElement.setText(2, documentTitle)
			self.ui.documentsTree.addTopLevelItem(newElement)
			
			index += 1
Example #14
0
    def populateUI(self):

        documents = plistutils.readPlist(self.filename)['SafariStateDocuments']

        index = 0
        for document in documents:

            documentTitle = document['SafariStateDocumentTitle']
            documentTimestamp = document[
                'SafariStateDocumentLastViewedTime'] + 978307200  #JAN 1 1970
            documentTimestamp = datetime.fromtimestamp(
                documentTimestamp).strftime('%Y-%m-%d %H:%M:%S')

            newElement = QtGui.QTreeWidgetItem(None)
            newElement.setText(0, str(index))
            newElement.setText(1, documentTimestamp)
            newElement.setText(2, documentTitle)
            self.ui.documentsTree.addTopLevelItem(newElement)

            index += 1
    def populateUI(self):

        signatures = plistutils.readPlist(self.filename)['Signatures']

        index = 0
        for element in signatures:
            ident = element['Identifier']
            identParts = ident.split(";")
            if (len(identParts) == 1):
                ident = identParts[0]
            else:
                ident = identParts[1].split("=")[1]

            timestamp = element['Timestamp']
            timestamp = timestamp.strftime('%b %d %Y %H:%M UTC')

            newElement = QtGui.QTreeWidgetItem(None)
            newElement.setText(0, str(index))
            newElement.setText(1, ident)
            newElement.setText(2, str(timestamp))
            self.ui.networksTree.addTopLevelItem(newElement)

            index += 1
	def populateUI(self):
		
		signatures = plistutils.readPlist(self.filename)['Signatures']
		
		index = 0
		for element in signatures:
			ident = element['Identifier']
			identParts = ident.split(";")
			if (len(identParts) == 1):
				ident = identParts[0]
			else:
				ident = identParts[1].split("=")[1]
			
			timestamp = element['Timestamp']
			timestamp = timestamp.strftime('%b %d %Y %H:%M UTC')

			newElement = QtGui.QTreeWidgetItem(None)
			newElement.setText(0, str(index))
			newElement.setText(1, ident)
			newElement.setText(2, str(timestamp))
			self.ui.networksTree.addTopLevelItem(newElement)
			
			index += 1
Example #17
0
	def OnClick(event=None):
	
		global fileNameForViewer
		global old_label_image
	
		if not tree.selection():
			return;
		
		# remove everything from tables tree
		for item in tablestree.get_children():
			tablestree.delete(item)
		
		# clear notebook additional panes
		notebook.hide(previewcolumn)
		notebook.hide(exifcolumn)
		
		item = tree.selection()[0]
		item_text = tree.item(item, "text")
		item_type = tree.set(item, "type")
		item_id = tree.set(item, "id")
		
		#skip "folders"
		if not item_type:
			return
		
		#clears textarea
		clearmaintext()
		
		# managing "standard" files
		if (item_type == "X"):	
			item_realpath = os.path.join(backup_path, item_text)
			fileNameForViewer = item_realpath
			maintext(u'Selected: ' + item_realpath)
			log(u'Opening file %s' % item_realpath)
			
			if (os.path.exists(item_realpath)):		
				
				filemagic = magic.file(item_realpath)
				
				#print file content (if text file) otherwise only first 50 chars
				if (filemagic == "ASCII text" or filemagic.partition("/")[0] == "text"):
					with open(item_realpath, 'rb') as fh:
						maintext("\n\nASCII content:\n\n")
						line = fh.readline()
						while line:
							line = fh.readline()
							maintext(line)
				else:
					with open(item_realpath, 'rb') as fh:
						text = fh.read(30)
						maintext("\n\nFirst 30 chars from file (string): ")
						maintext("\n" + hex2string(text))
			
				#if binary plist:
				if (filemagic.partition("/")[2] == "binary_plist"):					
					maintext("\n\nDecoding binary Plist file:\n\n")
					maintext(plistutils.readPlist(item_realpath))
			
			else:
				log(u'...troubles while opening file %s (does not exist)' % item_realpath)
			
			return

		maintext(u'Selected: %s (id %s)' % (item_text, item_id))
		
		data = mbdb.fileInformation(item_id)
		if not data:
			return
		
		item_permissions = data['permissions']
		item_userid      = data['userid']
		item_groupid     = data['groupid']
		item_mtime       = unicode(datetime.fromtimestamp(int(data['mtime'])))
		item_atime       = unicode(datetime.fromtimestamp(int(data['atime'])))
		item_ctime       = unicode(datetime.fromtimestamp(int(data['ctime'])))
		item_fileid      = data['fileid']
		item_link_target = data['link_target']
		item_datahash    = data['datahash']
		item_flag        = data['flag']
		
		maintext(u'\n\nElement type: ' + item_type)
		maintext(u'\nPermissions: ' + item_permissions)
		maintext(u'\nData hash: ')
		maintext(u'\n ' + item_datahash)
		maintext(u'\nUser id: ' + item_userid)
		maintext(u'\nGroup id: ' + item_groupid)
		maintext(u'\nLast modify time: ' + item_mtime)
		maintext(u'\nLast access Time: ' + item_atime)
		maintext(u'\nCreation time: ' + item_ctime)
		maintext(u'\nFile Key (obfuscated file name): ' + item_fileid)
		maintext(u'\nFlag: ' + item_flag)

		maintext(u'\n\nElement properties (from mdbd file):')
		for name, value in data['properties'].items():
			maintext(u'\n%s: %s' % (name, value))
		
		# treat sym links
		if (item_type == u'l'):
			maintext(u'\n\nThis item is a symbolic link to another file.')
			maintext(u'\nLink Target: ' + item_link_target)
			fileNameForViewer = u''
			return
			
		# treat directories
		if (item_type == u'd'):
			maintext(u'\n\nThis item represents a directory.')
			fileNameForViewer = u''
			return
		
		# last modification date of the file in the backup directory
		last_mod_time = time.strftime(u'%m/%d/%Y %I:%M:%S %p',time.localtime(os.path.getmtime(os.path.join(backup_path, item_fileid))))
		maintext(u'\n\nLast modification time (in backup dir): %s' % last_mod_time)
		
		maintext(u'\n\nAnalize file: ')
		
		item_realpath = os.path.join(backup_path, item_fileid)
		fileNameForViewer = item_realpath
		
		log(u'Opening file %s (%s)' % (item_realpath, item_text))
		
		# check for existence 
		if (not os.path.exists(item_realpath)):
			maintext(u'unable to analyze file')
			return			
		
		# print file type (from magic numbers)
		filemagic = magic.file(item_realpath)
		maintext(u'\nFile type (from magic numbers): %s' % filemagic)
		
		# print file MD5 hash
		maintext(u'\nFile MD5 hash: ')
		maintext(md5(item_realpath))
		
		#print first 30 bytes from file
		with open(item_realpath, u'rb') as fh:
			first30bytes = fh.read(30)
			maintext(u'\n\nFirst 30 hex bytes from file: ')
			maintext(u'\n' + hex2nums(first30bytes))
			
		#print file content (if ASCII file) otherwise only first 30 bytes
		if (filemagic == u'ASCII text' or filemagic.partition('/')[0] == u'text'):
			with open(item_realpath, 'rb') as fh:
				maintext(u'\n\nASCII content:\n\n')
				line = fh.readline()
				while line:
					line = fh.readline()
					maintext(line)
		else:
			maintext("\n\nFirst 30 chars from file (string): ")
			maintext("\n" + hex2string(first30bytes))					
		
		#if image file:
		if (filemagic.partition("/")[0] == "image"):		
			try:
				del photoImages[:]
				
				im = Image.open(item_realpath)
					
				#tkim = ImageTk.PhotoImage(im)
				#photoImages.append(tkim)
				maintext("\n\nImage preview available.")
				#textarea.image_create(END, image=tkim)
				
				# put image in the "preview" tab
				
				colwidth = 600
				imwidth = im.size[0]
				dimratio1 = (colwidth + 0.0) / (imwidth + 0.0)
				
				colheight = 500
				imheight = im.size[1]
				dimratio2 = (colheight + 0.0) / (imheight + 0.0)
				
				if (dimratio1 >= dimratio2):
					dimratio = dimratio2
				else:
					dimratio = dimratio1
				
				if (dimratio >= 1):
					dimratio = 1
				
				newwidth = int(im.size[0] * dimratio)
				newheight = int(im.size[1] * dimratio)

				im2 = im.resize((newwidth,newheight), Image.ANTIALIAS)
				tkim2 = ImageTk.PhotoImage(im2)
				photoImages.append(tkim2)
				
				label_image = Label(previewcolumn, image=tkim2)
				label_image.place(x=0,y=0)#,width=newwidth,height=newheight)
				if old_label_image is not None:
					old_label_image.destroy()
				old_label_image = label_image
				
				notebook.add(previewcolumn)
				
			except:
				print("Warning: error while trying to analyze image file \"%s\""%item_realpath)
				print sys.exc_info()
			
		#decode EXIF (only JPG)
		if (filemagic == "image/jpeg"):
			exifs = im._getexif()
			
			if (exifs is not None):
				maintext("\nJPG EXIF tags available.")
				exifcolumn_label.delete(1.0, END)
				exifcolumn_label.insert(END, "JPG EXIF tags for file \"%s\":"%item_text)
				exifcolumn_label.insert(END, "\n")
				for tag, value in exifs.items():
					decoded = TAGS.get(tag, tag)
					if (type(value) == type((1,2))):
						value = "%.3f (%i / %i)"%(float(value[0]) / float(value[1]), value[0], value[1])
					exifcolumn_label.insert(END, "\nTag: %s, value: %s"%(decoded, value))
				notebook.add(exifcolumn)
			
			#maintext("\n\nJPG EXIF tags:")
			#for tag, value in exifs.items():
			#	decoded = TAGS.get(tag, tag)
			#	maintext("\nTag: %s, value: %s"%(decoded, value))
				
		#if binary plist:
		if (filemagic.partition("/")[2] == "binary_plist"):			
			maintext("\n\nDecoding binary Plist file:\n\n")
			maintext(plistutils.readPlist(item_realpath))
		
		#if sqlite, print tables list
		if (filemagic.partition("/")[2] == "sqlite"):	
			tempdb = sqlite3.connect(item_realpath) 
			
			try:
				tempcur = tempdb.cursor() 
				tempcur.execute("SELECT name FROM sqlite_master WHERE type=\"table\"")
				tables_list = tempcur.fetchall();
				
				maintext("\n\nTables in database: ")
				
				for i in tables_list:
					table_name = str(i[0])
					maintext("\n- " + table_name);
					
					try:
						tempcur.execute("SELECT count(*) FROM %s" % table_name);
						elem_count = tempcur.fetchone()
						maintext(" (%i elements) " % int(elem_count[0]))
						# inserts table into tables tree
						tablestree.tag_configure('base', font=globalfont)
						tablestree.insert('', 'end', text=table_name, values=(item_realpath, table_name), tag="base")	
					except:
						#probably a virtual table?
						maintext(" (unable to read) ")
						
				tempdb.close()		
				
			except:
				maintext("\n\nSorry, I'm unable to open this database file. It appears to be an issue of some databases in iOS5.")
				maintext("\nUnexpected error: %s"%sys.exc_info()[1])
				tempdb.close()
			
		# if unknown "data", dump hex
		if (filemagic == "data"):
			limit = 10000
			maintext("\n\nDumping hex data (limit %i bytes):\n"%limit)
			content = ""
			with open(item_realpath, 'rb') as fh:
				line = fh.readline()
				while line:
					line = fh.readline()
					content += line;
			
			maintext(dump(content, 16, limit))
Example #18
0
    def OnClick(event=None):

        global fileNameForViewer
        global old_label_image

        if not tree.selection():
            return

        # remove everything from tables tree
        for item in tablestree.get_children():
            tablestree.delete(item)

        # clear notebook additional panes
        notebook.hide(previewcolumn)
        notebook.hide(exifcolumn)

        item = tree.selection()[0]
        item_text = tree.item(item, "text")
        item_type = tree.set(item, "type")
        item_id = tree.set(item, "id")

        #skip "folders"
        if not item_type:
            return

        #clears textarea
        clearmaintext()

        # managing "standard" files
        if (item_type == "X"):
            item_realpath = os.path.join(backup_path, item_text)
            fileNameForViewer = item_realpath
            maintext(u'Selected: ' + item_realpath)
            log(u'Opening file %s' % item_realpath)

            if (os.path.exists(item_realpath)):

                filemagic = magic.file(item_realpath)

                #print file content (if text file) otherwise only first 50 chars
                if (filemagic == "ASCII text"
                        or filemagic.partition("/")[0] == "text"):
                    with open(item_realpath, 'rb') as fh:
                        maintext("\n\nASCII content:\n\n")
                        line = fh.readline()
                        while line:
                            line = fh.readline()
                            maintext(line)
                else:
                    with open(item_realpath, 'rb') as fh:
                        text = fh.read(30)
                        maintext("\n\nFirst 30 chars from file (string): ")
                        maintext("\n" + hex2string(text))

                #if binary plist:
                if (filemagic.partition("/")[2] == "binary_plist"):
                    maintext("\n\nDecoding binary Plist file:\n\n")
                    maintext(plistutils.readPlist(item_realpath))

            else:
                log(u'...troubles while opening file %s (does not exist)' %
                    item_realpath)

            return

        maintext(u'Selected: %s (id %s)' % (item_text, item_id))

        data = mbdb.fileInformation(item_id)
        if not data:
            return

        item_permissions = data['permissions']
        item_userid = data['userid']
        item_groupid = data['groupid']
        item_mtime = unicode(datetime.fromtimestamp(int(data['mtime'])))
        item_atime = unicode(datetime.fromtimestamp(int(data['atime'])))
        item_ctime = unicode(datetime.fromtimestamp(int(data['ctime'])))
        item_fileid = data['fileid']
        item_link_target = data['link_target']
        item_datahash = data['datahash']
        item_flag = data['flag']

        maintext(u'\n\nElement type: ' + item_type)
        maintext(u'\nPermissions: ' + item_permissions)
        maintext(u'\nData hash: ')
        maintext(u'\n ' + item_datahash)
        maintext(u'\nUser id: ' + item_userid)
        maintext(u'\nGroup id: ' + item_groupid)
        maintext(u'\nLast modify time: ' + item_mtime)
        maintext(u'\nLast access Time: ' + item_atime)
        maintext(u'\nCreation time: ' + item_ctime)
        maintext(u'\nFile Key (obfuscated file name): ' + item_fileid)
        maintext(u'\nFlag: ' + item_flag)

        maintext(u'\n\nElement properties (from mdbd file):')
        for name, value in data['properties'].items():
            maintext(u'\n%s: %s' % (name, value))

        # treat sym links
        if (item_type == u'l'):
            maintext(u'\n\nThis item is a symbolic link to another file.')
            maintext(u'\nLink Target: ' + item_link_target)
            fileNameForViewer = u''
            return

        # treat directories
        if (item_type == u'd'):
            maintext(u'\n\nThis item represents a directory.')
            fileNameForViewer = u''
            return

        # last modification date of the file in the backup directory
        last_mod_time = time.strftime(
            u'%m/%d/%Y %I:%M:%S %p',
            time.localtime(
                os.path.getmtime(os.path.join(backup_path, item_fileid))))
        maintext(u'\n\nLast modification time (in backup dir): %s' %
                 last_mod_time)

        maintext(u'\n\nAnalize file: ')

        item_realpath = os.path.join(backup_path, item_fileid)
        fileNameForViewer = item_realpath

        log(u'Opening file %s (%s)' % (item_realpath, item_text))

        # check for existence
        if (not os.path.exists(item_realpath)):
            maintext(u'unable to analyze file')
            return

        # print file type (from magic numbers)
        filemagic = magic.file(item_realpath)
        maintext(u'\nFile type (from magic numbers): %s' % filemagic)

        # print file MD5 hash
        maintext(u'\nFile MD5 hash: ')
        maintext(md5(item_realpath))

        #print first 30 bytes from file
        with open(item_realpath, u'rb') as fh:
            first30bytes = fh.read(30)
            maintext(u'\n\nFirst 30 hex bytes from file: ')
            maintext(u'\n' + hex2nums(first30bytes))

        #print file content (if ASCII file) otherwise only first 30 bytes
        if (filemagic == u'ASCII text'
                or filemagic.partition('/')[0] == u'text'):
            with open(item_realpath, 'rb') as fh:
                maintext(u'\n\nASCII content:\n\n')
                line = fh.readline()
                while line:
                    line = fh.readline()
                    maintext(line)
        else:
            maintext("\n\nFirst 30 chars from file (string): ")
            maintext("\n" + hex2string(first30bytes))

        #if image file:
        if (filemagic.partition("/")[0] == "image"):
            try:
                del photoImages[:]

                im = Image.open(item_realpath)

                #tkim = ImageTk.PhotoImage(im)
                #photoImages.append(tkim)
                maintext("\n\nImage preview available.")
                #textarea.image_create(END, image=tkim)

                # put image in the "preview" tab

                colwidth = 600
                imwidth = im.size[0]
                dimratio1 = (colwidth + 0.0) / (imwidth + 0.0)

                colheight = 500
                imheight = im.size[1]
                dimratio2 = (colheight + 0.0) / (imheight + 0.0)

                if (dimratio1 >= dimratio2):
                    dimratio = dimratio2
                else:
                    dimratio = dimratio1

                if (dimratio >= 1):
                    dimratio = 1

                newwidth = int(im.size[0] * dimratio)
                newheight = int(im.size[1] * dimratio)

                im2 = im.resize((newwidth, newheight), Image.ANTIALIAS)
                tkim2 = ImageTk.PhotoImage(im2)
                photoImages.append(tkim2)

                label_image = Label(previewcolumn, image=tkim2)
                label_image.place(x=0, y=0)  #,width=newwidth,height=newheight)
                if old_label_image is not None:
                    old_label_image.destroy()
                old_label_image = label_image

                notebook.add(previewcolumn)

            except:
                print(
                    "Warning: error while trying to analyze image file \"%s\""
                    % item_realpath)
                print sys.exc_info()

        #decode EXIF (only JPG)
        if (filemagic == "image/jpeg"):
            exifs = im._getexif()

            if (exifs is not None):
                maintext("\nJPG EXIF tags available.")
                exifcolumn_label.delete(1.0, END)
                exifcolumn_label.insert(
                    END, "JPG EXIF tags for file \"%s\":" % item_text)
                exifcolumn_label.insert(END, "\n")
                for tag, value in exifs.items():
                    decoded = TAGS.get(tag, tag)
                    if (type(value) == type((1, 2))):
                        value = "%.3f (%i / %i)" % (float(value[0]) / float(
                            value[1]), value[0], value[1])
                    exifcolumn_label.insert(
                        END, "\nTag: %s, value: %s" % (decoded, value))
                notebook.add(exifcolumn)

            #maintext("\n\nJPG EXIF tags:")
            #for tag, value in exifs.items():
            #	decoded = TAGS.get(tag, tag)
            #	maintext("\nTag: %s, value: %s"%(decoded, value))

        #if binary plist:
        if (filemagic.partition("/")[2] == "binary_plist"):
            maintext("\n\nDecoding binary Plist file:\n\n")
            maintext(plistutils.readPlist(item_realpath))

        #if sqlite, print tables list
        if (filemagic.partition("/")[2] == "sqlite"):
            tempdb = sqlite3.connect(item_realpath)

            try:
                tempcur = tempdb.cursor()
                tempcur.execute(
                    "SELECT name FROM sqlite_master WHERE type=\"table\"")
                tables_list = tempcur.fetchall()

                maintext("\n\nTables in database: ")

                for i in tables_list:
                    table_name = str(i[0])
                    maintext("\n- " + table_name)

                    try:
                        tempcur.execute("SELECT count(*) FROM %s" % table_name)
                        elem_count = tempcur.fetchone()
                        maintext(" (%i elements) " % int(elem_count[0]))
                        # inserts table into tables tree
                        tablestree.tag_configure('base', font=globalfont)
                        tablestree.insert('',
                                          'end',
                                          text=table_name,
                                          values=(item_realpath, table_name),
                                          tag="base")
                    except:
                        #probably a virtual table?
                        maintext(" (unable to read) ")

                tempdb.close()

            except:
                maintext(
                    "\n\nSorry, I'm unable to open this database file. It appears to be an issue of some databases in iOS5."
                )
                maintext("\nUnexpected error: %s" % sys.exc_info()[1])
                tempdb.close()

        # if unknown "data", dump hex
        if (filemagic == "data"):
            limit = 10000
            maintext("\n\nDumping hex data (limit %i bytes):\n" % limit)
            content = ""
            with open(item_realpath, 'rb') as fh:
                line = fh.readline()
                while line:
                    line = fh.readline()
                    content += line

            maintext(dump(content, 16, limit))