modified: nfig1.py
[GalaxyCodeBases.git] / etc / iOS / parse_manifest.py
blobb52e8a7efa8399adc0498478f924c2353b33cfc5
1 #!/usr/bin/env python
2 # From http://stackoverflow.com/questions/3085153/how-to-parse-the-manifest-mbdb-file-in-an-ios-4-0-itunes-backup
3 import sys
4 import hashlib
6 mbdx = {}
8 def getint(data, offset, intsize):
9 """Retrieve an integer (big-endian) and new offset from the current offset"""
10 value = 0
11 while intsize > 0:
12 value = (value<<8) + ord(data[offset])
13 offset = offset + 1
14 intsize = intsize - 1
15 return value, offset
17 def getstring(data, offset):
18 """Retrieve a string and new offset from the current offset into the data"""
19 if data[offset] == chr(0xFF) and data[offset+1] == chr(0xFF):
20 return '', offset+2 # Blank string
21 length, offset = getint(data, offset, 2) # 2-byte length
22 value = data[offset:offset+length]
23 return value, (offset + length)
25 def process_mbdb_file(filename):
26 mbdb = {} # Map offset of info in this file => file info
27 data = open(filename).read()
28 if data[0:4] != "mbdb": raise Exception("This does not look like an MBDB file")
29 offset = 4
30 offset = offset + 2 # value x05 x00, not sure what this is
31 while offset < len(data):
32 fileinfo = {}
33 fileinfo['start_offset'] = offset
34 fileinfo['domain'], offset = getstring(data, offset)
35 fileinfo['filename'], offset = getstring(data, offset)
36 fileinfo['linktarget'], offset = getstring(data, offset)
37 fileinfo['datahash'], offset = getstring(data, offset)
38 fileinfo['unknown1'], offset = getstring(data, offset)
39 fileinfo['mode'], offset = getint(data, offset, 2)
40 fileinfo['unknown2'], offset = getint(data, offset, 4)
41 fileinfo['unknown3'], offset = getint(data, offset, 4)
42 fileinfo['userid'], offset = getint(data, offset, 4)
43 fileinfo['groupid'], offset = getint(data, offset, 4)
44 fileinfo['mtime'], offset = getint(data, offset, 4)
45 fileinfo['atime'], offset = getint(data, offset, 4)
46 fileinfo['ctime'], offset = getint(data, offset, 4)
47 fileinfo['filelen'], offset = getint(data, offset, 8)
48 fileinfo['flag'], offset = getint(data, offset, 1)
49 fileinfo['numprops'], offset = getint(data, offset, 1)
50 fileinfo['properties'] = {}
51 for ii in range(fileinfo['numprops']):
52 propname, offset = getstring(data, offset)
53 propval, offset = getstring(data, offset)
54 fileinfo['properties'][propname] = propval
55 mbdb[fileinfo['start_offset']] = fileinfo
56 fullpath = fileinfo['domain'] + '-' + fileinfo['filename']
57 id = hashlib.sha1(fullpath)
58 mbdx[fileinfo['start_offset']] = id.hexdigest()
59 return mbdb
61 def modestr(val):
62 def mode(val):
63 if (val & 0x4): r = 'r'
64 else: r = '-'
65 if (val & 0x2): w = 'w'
66 else: w = '-'
67 if (val & 0x1): x = 'x'
68 else: x = '-'
69 return r+w+x
70 return mode(val>>6) + mode((val>>3)) + mode(val)
72 def fileinfo_str(f, verbose=False):
73 # if not verbose: return "(%s)%s::%s" % (f['fileID'], f['domain'], f['filename'])
74 if not verbose: return "%s => %s (%s)" % (f['fileID'], f['filename'], f['domain'])
75 if (f['mode'] & 0xE000) == 0xA000: type = 'l' # symlink
76 elif (f['mode'] & 0xE000) == 0x8000: type = '-' # file
77 elif (f['mode'] & 0xE000) == 0x4000: type = 'd' # dir
78 else:
79 print >> sys.stderr, "Unknown file type %04x for %s" % (f['mode'], fileinfo_str(f, False))
80 type = '?' # unknown
81 info = ("%s%s %08x %08x %7d %10d %10d %10d (%s)%s::%s" %
82 (type, modestr(f['mode']&0x0FFF) , f['userid'], f['groupid'], f['filelen'],
83 f['mtime'], f['atime'], f['ctime'], f['fileID'], f['domain'], f['filename']))
84 if type == 'l': info = info + ' -> ' + f['linktarget'] # symlink destination
85 for name, value in f['properties'].items(): # extra properties
86 info = info + ' ' + name + '=' + repr(value)
87 return info
89 verbose = True
90 if __name__ == '__main__':
91 mbdb = process_mbdb_file("Manifest.mbdb")
92 for offset, fileinfo in mbdb.items():
93 if offset in mbdx:
94 fileinfo['fileID'] = mbdx[offset]
95 else:
96 fileinfo['fileID'] = "<nofileID>"
97 print >> sys.stderr, "No fileID found for %s" % fileinfo_str(fileinfo)
98 print fileinfo_str(fileinfo)