Advertisement
Guest User

iphonels.py

a guest
Apr 20th, 2011
3,622
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.83 KB | None | 0 0
  1. #!/usr/bin/env python
  2. import sys
  3.  
  4. def getint(data, offset, intsize):
  5.     """Retrieve an integer (big-endian) and new offset from the current offset"""
  6.     value = 0
  7.     while intsize > 0:
  8.         value = (value<<8) + ord(data[offset])
  9.         offset = offset + 1
  10.         intsize = intsize - 1
  11.     return value, offset
  12.  
  13. def getstring(data, offset):
  14.     """Retrieve a string and new offset from the current offset into the data"""
  15.     if data[offset] == chr(0xFF) and data[offset+1] == chr(0xFF):
  16.         return '', offset+2 # Blank string
  17.     length, offset = getint(data, offset, 2) # 2-byte length
  18.     value = data[offset:offset+length]
  19.     return value, (offset + length)
  20.  
  21. def process_mbdb_file(filename):
  22.     mbdb = {} # Map offset of info in this file => file info
  23.     data = open(filename).read()
  24.     if data[0:4] != "mbdb": raise Exception("This does not look like an MBDB file")
  25.     offset = 4
  26.     offset = offset + 2 # value x05 x00, not sure what this is
  27.     while offset < len(data):
  28.         fileinfo = {}
  29.         fileinfo['start_offset'] = offset
  30.         fileinfo['domain'], offset = getstring(data, offset)
  31.         fileinfo['filename'], offset = getstring(data, offset)
  32.         fileinfo['linktarget'], offset = getstring(data, offset)
  33.         fileinfo['datahash'], offset = getstring(data, offset)
  34.         fileinfo['unknown1'], offset = getstring(data, offset)
  35.         fileinfo['mode'], offset = getint(data, offset, 2)
  36.         fileinfo['unknown2'], offset = getint(data, offset, 4)
  37.         fileinfo['unknown3'], offset = getint(data, offset, 4)
  38.         fileinfo['userid'], offset = getint(data, offset, 4)
  39.         fileinfo['groupid'], offset = getint(data, offset, 4)
  40.         fileinfo['mtime'], offset = getint(data, offset, 4)
  41.         fileinfo['atime'], offset = getint(data, offset, 4)
  42.         fileinfo['ctime'], offset = getint(data, offset, 4)
  43.         fileinfo['filelen'], offset = getint(data, offset, 8)
  44.         fileinfo['flag'], offset = getint(data, offset, 1)
  45.         fileinfo['numprops'], offset = getint(data, offset, 1)
  46.         fileinfo['properties'] = {}
  47.         for ii in range(fileinfo['numprops']):
  48.             propname, offset = getstring(data, offset)
  49.             propval, offset = getstring(data, offset)
  50.             fileinfo['properties'][propname] = propval
  51.         mbdb[fileinfo['start_offset']] = fileinfo
  52.     return mbdb
  53.  
  54. def process_mbdx_file(filename):
  55.     mbdx = {} # Map offset of info in the MBDB file => fileID string
  56.     data = open(filename).read()
  57.     if data[0:4] != "mbdx": raise Exception("This does not look like an MBDX file")
  58.     offset = 4
  59.     offset = offset + 2 # value 0x02 0x00, not sure what this is
  60.     filecount, offset = getint(data, offset, 4) # 4-byte count of records
  61.     while offset < len(data):
  62.         # 26 byte record, made up of ...
  63.         fileID = data[offset:offset+20] # 20 bytes of fileID
  64.         fileID_string = ''.join(['%02x' % ord(b) for b in fileID])
  65.         offset = offset + 20
  66.         mbdb_offset, offset = getint(data, offset, 4) # 4-byte offset field
  67.         mbdb_offset = mbdb_offset + 6 # Add 6 to get past prolog
  68.         mode, offset = getint(data, offset, 2) # 2-byte mode field
  69.         mbdx[mbdb_offset] = fileID_string
  70.     return mbdx
  71.  
  72. def modestr(val):
  73.     def mode(val):
  74.         if (val & 0x4): r = 'r'
  75.         else: r = '-'
  76.         if (val & 0x2): w = 'w'
  77.         else: w = '-'
  78.         if (val & 0x1): x = 'x'
  79.         else: x = '-'
  80.         return r+w+x
  81.     return mode(val>>6) + mode((val>>3)) + mode(val)
  82.  
  83. def fileinfo_str(f, verbose=False):
  84.     if not verbose: return "(%s)%s::%s" % (f['fileID'], f['domain'], f['filename'])
  85.     if (f['mode'] & 0xE000) == 0xA000: type = 'l' # symlink
  86.     elif (f['mode'] & 0xE000) == 0x8000: type = '-' # file
  87.     elif (f['mode'] & 0xE000) == 0x4000: type = 'd' # dir
  88.     else:
  89.         print >> sys.stderr, "Unknown file type %04x for %s" % (f['mode'], fileinfo_str(f, False))
  90.         type = '?' # unknown
  91.     info = ("%s%s %08x %08x %7d %10d %10d %10d (%s)%s::%s" %
  92.             (type, modestr(f['mode']&0x0FFF) , f['userid'], f['groupid'], f['filelen'],
  93.              f['mtime'], f['atime'], f['ctime'], f['fileID'], f['domain'], f['filename']))
  94.     if type == 'l': info = info + ' -> ' + f['linktarget'] # symlink destination
  95.     for name, value in f['properties'].items(): # extra properties
  96.         info = info + ' ' + name + '=' + repr(value)
  97.     return info
  98.  
  99. verbose = True
  100. if __name__ == '__main__':
  101.     mbdb = process_mbdb_file("Manifest.mbdb")
  102.     mbdx = process_mbdx_file("Manifest.mbdx")
  103.     for offset, fileinfo in mbdb.items():
  104.         if offset in mbdx:
  105.             fileinfo['fileID'] = mbdx[offset]
  106.         else:
  107.             fileinfo['fileID'] = "<nofileID>"
  108.             print >> sys.stderr, "No fileID found for %s" % fileinfo_str(fileinfo)
  109.         print fileinfo_str(fileinfo, verbose)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement