from crypto.aes import AESencryptCBC, AESdecryptCBC from emf import cprotect_xattr, EMFFile from structs import * from util import write_file, sizeof_fmt import hashlib """ Implementation of the following paper : Using the HFS+ Journal For Deleted File Recovery. Aaron Burghardt, Adam Feldman. DFRWS 2008 http://www.dfrws.org/2008/proceedings/p76-burghardt.pdf http://www.dfrws.org/2008/proceedings/p76-burghardt_pres.pdf """ def carveBtreeNode(node, kClass, dClass): try: btnode = BTNodeDescriptor.parse(node) if btnode.kind == kBTLeafNode: off = BTNodeDescriptor.sizeof() recs = [] offsets = Array(btnode.numRecords, UBInt16("off")).parse(node[-2*btnode.numRecords:]) for i in xrange(btnode.numRecords): off = offsets[btnode.numRecords-i-1] k = kClass.parse(node[off:]) off += 2 + k.keyLength d = dClass.parse(node[off:]) recs.append((k,d)) return recs return [] except: return [] """ for standard HFS volumes """ def carveHFSVolumeJournal(volume): journal = volume.readJournal() hdr = journal_header.parse(journal) sector_size = hdr.jhdr_size nodeSize = volume.catalogTree.nodeSize f={} for i in xrange(0,len(journal), sector_size): for k,v in carveBtreeNode(journal[i:i+nodeSize],HFSPlusCatalogKey, HFSPlusCatalogData): if v.recordType == kHFSPlusFileRecord: name = getString(k) h = hashlib.sha1(HFSPlusCatalogKey.build(k)).digest() if f.has_key(h): continue if volume.catalogTree.searchByCNID(v.data.fileID) == (None, None): if volume.isBlockInUse(v.data.dataFork.HFSPlusExtentDescriptor[0].startBlock) == False: print "deleted file", v.data.fileID, name fileid = v.data.fileID f[h]=(name, v) return f.values() magics=["SQLite", "bplist", "