Пример #1
0
        public HeaderBruteForcer(uint[] updateCrcs, SortedList <uint, bool> checkCrcs, Tuple <byte[], int[]>[] regionData, params byte[][] headers)
        {
            _updateCrcs = updateCrcs;
            _checkCrcs  = checkCrcs;

            //DateTime dt = DateTime.Now;

            _hdrs = headers.Select(a => new headerCrc()
            {
                Crc = Crc.Compute(a), CrcPreRegion = Crc.Compute(a, 0, 0x4e000), CrcRegion = Crc.Compute(a, 0x4e000, 0x20), CrcPostRegion = Crc.Compute(a, 0x4e020, 0x1fe0), Data = a
            }).ToList();

            MemorySection ms = new MemorySection(headers[0]);

            _origRegion     = (int)ms.ReadUInt32B(0x4e000);
            _origRegionData = ms.Read(0x4e010, 0x10);

            _origHeaderCrcs = _hdrs.Select(a => a.Crc).ToArray(); //original header Crcs

            for (int h = _hdrs.Count - 1; h >= 1; h--)
            {
                if (_hdrs[h].Crc == _hdrs[h - 1].Crc)
                {
                    _hdrs.RemoveAt(h); //remove duplicate headers
                }
            }

            _regionData = new List <regionCrc>();
            for (int h = 0; h < _hdrs.Count; h++)
            {
                for (int i = 0; i < regionData.Length; i++)
                {
                    for (int r = 0; r < regionData[i].Item2.Length; r++)
                    {
                        _regionData.Add(new regionCrc()
                        {
                            Crc = 0, Header = _hdrs[h], RegionData = regionData[i].Item1, Region = (int)regionData[i].Item2[r]
                        });
                    }
                }
            }


            //parallel precalculate the crcs for the matching
            Parallel.ForEach(_regionData, rgn =>
            {
                MemorySection rg = new MemorySection(new byte[0x20]);
                rg.WriteUInt32B(0, (uint)rgn.Region);
                rg.Write(0x10, rgn.RegionData);
                rgn.Crc = ~Crc.Combine(Crc.Combine(~rgn.Header.CrcPreRegion, ~Crc.Compute(rg.Data), 0x20), ~rgn.Header.CrcPostRegion, 0x1fe0);
            });

            //Trace.WriteLine(string.Format("Crc Headers: {0} - Took: {1}", _regionData.Count.ToString(), (DateTime.Now - dt).TotalMilliseconds.ToString()));
        }
Пример #2
0
        public uint FullCrc(bool patched)
        {
            if (_crcs.Count == 0)
            {
                return(0);
            }

            uint crc = (patched && _crcs[0].PatchCrc != 0) ? _crcs[0].PatchCrc : _crcs[0].Value;

            for (int i = 1; i < _crcs.Count; i++)
            {
                crc = ~Crc.Combine(~crc, (patched && _crcs[i].PatchCrc != 0) ? ~_crcs[i].PatchCrc : ~_crcs[i].Value, _crcs[i].Length);
            }

            return(crc);
        }
Пример #3
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]));
        }