private BruteForceCrcResult results(headerCrc matchHdr, regionCrc matchRgn, uint updateCrc, uint matchCrc, bool isRedump) { if (matchHdr == null && matchRgn == null) { return new BruteForceCrcResult() { Region = _origRegion } } ; //create the header byte[] header = (matchHdr ?? matchRgn.Header).Data; bool regionDataChanged = false; if (matchRgn != null) { MemorySection ms = new MemorySection(header); regionDataChanged = !matchRgn.Region.Equals(_origRegionData); ms.WriteUInt32B(0x4e000, (uint)matchRgn.Region); ms.Write(0x4e010, matchRgn.RegionData); } uint headerCrc = Crc.Compute(header); if (headerCrc == _origHeaderCrc) { header = null; } return(new BruteForceCrcResult() { MatchedCrc = matchCrc, MatchedCrcIsRedump = isRedump, HeaderChanged = header != null && _origHeaderCrc != headerCrc, Header = header, HeaderCrc = Crc.Compute(header), UpdateChanged = updateCrc != 0 && _origUpdateCrc != updateCrc, UpdateCrc = updateCrc, Region = matchRgn?.Region ?? _origRegion, OriginalRegion = _origRegion, RegionData = matchRgn?.RegionData, RegionChanged = matchRgn != null && (regionDataChanged || matchRgn.Region != _origRegion) }); } }
public BruteForceCrcResult Match(CrcItem[] crcs) { //reduce crcs to 3 - header, update, postUpdate _origHeaderCrc = crcs[0].Value; _origUpdateCrc = crcs[1].Value; long updateSize = (crcs.Length > 2 ? crcs[2].Offset - crcs[1].Offset : 0); uint postUpdateCrc = (crcs.Length > 2 ? crcs[2].Value : 0); long postUpdateSize = (crcs.Length > 2 ? crcs[2].Length : 0); for (int x = 3; x < crcs.Length; x++) { postUpdateCrc = ~Crc.Combine(~postUpdateCrc, ~crcs[x].Value, crcs[x].Length); postUpdateSize += crcs[x].Length; } //DateTime dt = DateTime.Now; //quick test without region brute force (which can take a while) headerCrc headerMatch = null; regionCrc regionMatch = null; uint matchCrc = 0; uint matchUpdateCrc = 0; uint u = _updateCrcs.AsParallel().FirstOrDefault(uCrc => { headerCrc m = _hdrs.AsParallel().FirstOrDefault(hdr => { uint crc = ~Crc.Combine(Crc.Combine(~hdr.Crc, ~uCrc, updateSize), ~postUpdateCrc, postUpdateSize); if (_checkCrcs.ContainsKey(crc)) { matchCrc = crc; headerMatch = hdr; matchUpdateCrc = uCrc; } return(matchCrc != 0); }); return(matchCrc != 0); }); //Trace.WriteLine(string.Format("Crc Update Combos: {0} - Took: {1}", _updateCrcs.Length.ToString(), (DateTime.Now - dt).TotalMilliseconds.ToString())); if (headerMatch == null) { //dt = DateTime.Now; //region brute force tests - FirstOrDefault is used and the results are discarded as nesting them causes threading issues uint u2 = _updateCrcs.AsParallel().FirstOrDefault(uCrc => { //combine the update crc with the post update crc uint updDataCrc = ~Crc.Combine(~uCrc, ~postUpdateCrc, postUpdateSize); long updDataSize = updateSize + postUpdateSize; //compare the header/region with the update and post update combines crc regionCrc m = _regionData.AsParallel().FirstOrDefault(rgn => { uint crc = ~Crc.Combine(~rgn.Crc, ~updDataCrc, updDataSize); if (_checkCrcs.ContainsKey(crc)) { matchCrc = crc; regionMatch = rgn; matchUpdateCrc = uCrc; } return(matchCrc != 0); }); return(matchCrc != 0); }); //Trace.WriteLine(string.Format("Crc Header / Update Combos: {0} - Took: {1}", (_updateCrcs.Length * _regionData.Count).ToString(), (DateTime.Now - dt).TotalMilliseconds.ToString())); } return(results(headerMatch, regionMatch, matchUpdateCrc, matchCrc, matchCrc == 0 ? false : _checkCrcs[matchCrc])); }