Advertisement
Guest User

Untitled

a guest
Oct 21st, 2015
190
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.52 KB | None
  1. from Foundation import NSObject, NSKeyedUnarchiver
  2. from struct import unpack
  3.  
  4. # Make our custom decoder replacement class for SFLListItem
  5. class SFLListItem(NSObject):
  6. bookmark = None
  7. name = None
  8. order = None
  9. properties = None
  10. uniqueidentifier = None
  11. def init(self):
  12. self = super(SFLListItem, self).init()
  13. return self
  14. def initWithCoder_(self, coder):
  15. self.bookmark = coder.decodeObjectForKey_(u"bookmark")
  16. self.name = coder.decodeObjectForKey_(u"name")
  17. self.order = int(coder.decodeFloatForKey_(u"order"))
  18. self.properties = coder.decodeObjectForKey_(u"properties")
  19. self.uniqueidentifier = coder.decodeObjectForKey_(u"uniqueIdentifier")
  20. return self
  21.  
  22. # Create the association for the class name
  23. NSKeyedUnarchiver.setClass_forClassName_(SFLListItem, "SFLListItem")
  24.  
  25. # This entire function is black magic of the highest order and I'll blog about it later
  26. def extract_share(bookmark_data):
  27. content_offset, = unpack('I', bookmark_data[12:16])
  28. first_TOC, = unpack('I', bookmark_data[content_offset:content_offset+4])
  29. first_TOC += content_offset
  30. TOC_len, rec_type, level, next_TOC, record_count = unpack('IIIII', bookmark_data[first_TOC:first_TOC+20])
  31. TOC_cursor = first_TOC + 20
  32. record_offsets = {}
  33. for i in range(record_count):
  34. record_id, offset = unpack('<IQ', bookmark_data[TOC_cursor:TOC_cursor+12])
  35. record_offsets[record_id] = offset + content_offset
  36. TOC_cursor += 12
  37. mount_record = record_offsets[0x2050]
  38. mount_length, rec_type = unpack('II', bookmark_data[mount_record:mount_record+8])
  39. mount_record += 8
  40. mount_URL = (bookmark_data[mount_record:mount_record+mount_length]).decode('utf-8')
  41. return mount_URL
  42.  
  43. def get_recentservers(sfl_file_path):
  44. # Read the com.apple.LSSharedFileList.RecentServers.sfl file (located in ~/Library/Application Support/com.apple.sharedfilelist on 10.11+)
  45. with open(sfl_file_path, 'rb') as f:
  46. raw_data = f.read()
  47. # It's NSKeyedArchiver data - let's decode it!
  48. recent_servers = NSKeyedUnarchiver.unarchiveObjectWithData_(buffer(raw_data))
  49. # Build an empty set
  50. server_URLs = []
  51. # Add in our discovered server URLs from the SFLListItems and return in 'SFLListItem.order' order
  52. for x in sorted(recent_servers['items'], lambda y,_: y.order):
  53. server_URLs.append(extract_share(x.bookmark[:].tobytes()))
  54. return server_URLs
  55.  
  56. # Example usage:
  57. # get_recentservers('com.apple.LSSharedFileList.RecentServers.sfl')
Advertisement
RAW Paste Data Copied
Advertisement