Beispiel #1
0
        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)
            });
        }
    }
Beispiel #2
0
        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]));
        }