/// <summary> /// Calculates the SHA1 hash of the entire memory file. /// </summary> /// <param name="filePath">The path to the phone's memory file.</param> /// <returns>The SHA1 hash of the memory file.</returns> public static string CalculateFileSha1(string filePath) { string fileSha1 = null; try { FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); fileSha1 = DcUtils.BytesToHex((new SHA1Managed()).ComputeHash(fs)); fs.Close(); } catch (ThreadAbortException) { return(null); } catch (Exception ex) { MessageBox.Show(ex.Message, "File Hash", MessageBoxButtons.OK, MessageBoxIcon.Error); return(null); } return(fileSha1); }
/// <summary> /// This is where all of the work is done to extract information from /// the phone's binary file. /// It calls methods for image block identification, removal, block hash filtering, field and record level Viterbi infrerence, postprocessing of results. /// </summary> private void Run() { bool success = false; PostProcessor postProcess = null; PhoneInfo phoneInfo = null; try { // Use the SHA1 of the binary file to identify it. _canAbort = true; StartStep(1); write("Calculating file SHA1"); fileSha1 = DcUtils.CalculateFileSha1(this.filePath); if (_cancel) { return; } NextStep(1); // We scan the file to locate images. This is done independent // of block hashes. write("Extracting graphical images"); #if LOADONLY || SKIPIMAGES ImageFiles imageFiles = new ImageFiles(); #else ImageFiles imageFiles = ImageFiles.LocateImages(this.filePath); if (_cancel) { return; } _canAbort = false; write("Extracted {0} graphical images", imageFiles.ImageBlocks.Count); #endif NextStep(2); if (_cancel) { return; } // Load the block hashes into the DB (if they're not already // there). HashLoader.HashLoader hashloader = HashLoader.HashLoader.LoadHashesIntoDB(fileSha1, this.filePath, this.manufacturer, this.model, this.note, this.doNotStoreHashes); if (_cancel || (hashloader == null)) { return; } int phoneId = hashloader.PhoneId; #if LOADONLY _cancel = true; return; #endif _canAbort = true; NextStep(3); if (_cancel) { return; } // Identify block hashes that are already in the DB, which we // will then filter out. FilterResult filterResult = RunBlockHashFilter(fileSha1, phoneId, hashloader.GetAndForgetStoredHashes()); hashloader = null; NextStep(4); // Since images were located before block hash filter, forget // about any image that overlaps a filtered block hash. write("Filtering image locations"); //filterResult = ImageFiles.FilterOutImages(filterResult, imageFiles); //Dump_Filtered_Blocks(filterResult, filePath); NextStep(5); // Finally, we're ready to use the Viterbi state machine. // Start by identifying fields. ViterbiResult viterbiResultFields = RunViterbi(filterResult, fileSha1); // Allow garbage collection. filterResult.UnfilteredBlocks.Clear(); NextStep(6); List <MetaField> addressBookEntries = new List <MetaField>(); List <MetaField> callLogs = new List <MetaField>(); List <MetaField> sms = new List <MetaField>(); // Second run of Viterbi, this time for records. //ViterbiResult viterbiResultRecord = RunMetaViterbi(viterbiResultFields,addressBookEntries,callLogs,sms); RunMetaViterbi(viterbiResultFields, addressBookEntries, callLogs, sms); viterbiResultFields = null; NextStep(7); // Perform post processing. This may remove some records. postProcess = new PostProcessor(callLogs, addressBookEntries, sms, imageFiles.ImageBlocks); success = PerformPostProcessing(postProcess); NextStep(8); GTC_CSV_Writer wr = new GTC_CSV_Writer(this.metaResults, postProcess, filePath); wr.Write_CSV(); wr.Write_Field_Paths(this.fieldPaths); // Finished. phoneInfo = new PhoneInfo(manufacturer, model, note, doNotStoreHashes); write("Finished work"); FinishedStep(9); } finally { if (_cancel) { MainForm.Program.EndWork(false, null, null, null); } else { MainForm.Program.EndWork(success, postProcess, this.filePath, phoneInfo); } } }