예제 #1
0
        public void Fold(int firstBlockSize)
        {
            if (firstBlockSize <= 0)
            {
                return;
            }

            // Repeatedly fold the last guess in the list until the key is less than firstBlockSize
            while (_guesses.Count > 0 && _guesses.Keys[_guesses.Count - 1] >= firstBlockSize)
            {
                // Grab the guess at the end and remove it along with its submap
                MetaValueGuess guess = _guesses.Values[_guesses.Count - 1];
                _guesses.RemoveAt(_guesses.Count - 1);

                MetaMap subMap = GetSubMap(guess.Offset);
                if (subMap != null)
                {
                    _submaps.Remove(guess.Offset);
                }

                // Wrap its offset
                guess.Offset %= firstBlockSize;

                // Add them back in
                if (AddGuess(guess))
                {
                    AssociateSubMap(guess.Offset, subMap);
                }
            }
        }
예제 #2
0
        public bool AddGuess(MetaValueGuess guess)
        {
            // Don't overwrite good guesses with null pointers
            if (_guesses.ContainsKey(guess.Offset))
            {
                if (guess.Pointer == 0 || guess.Pointer == 0xFFFFFFFF || guess.Pointer == 0xCDCDCDCD)
                    return false;
            }

            /*if (_submaps.ContainsKey(guess.Offset))
                return;*/

            // Just store it
            _guesses[guess.Offset] = guess;
            return true;
        }
예제 #3
0
        public bool AddGuess(MetaValueGuess guess)
        {
            // Don't overwrite good guesses with null pointers
            if (_guesses.ContainsKey(guess.Offset))
            {
                if (guess.Pointer == 0 || guess.Pointer == 0xFFFFFFFF || guess.Pointer == 0xCDCDCDCD)
                {
                    return(false);
                }
            }

            /*if (_submaps.ContainsKey(guess.Offset))
             * return;*/

            // Just store it
            _guesses[guess.Offset] = guess;
            return(true);
        }
예제 #4
0
        public void AnalyzeArea(IReader reader, long startAddress, MetaMap resultMap)
        {
            // Right now, this method only searches for the signatures of a few complex meta values.
            // Reflexives:      int32 entry count + uint32 address     + 4 bytes of padding
            // Data references: int32 size        + 8 bytes of padding + uint32 address
            // Tag references:  int32 class id    + 8 bytes of padding + uint32 datum index
            // ASCII strings:   characters with the values 0 or 0x20 - 0x7F

            // End at the next-highest address
            long endAddress = _memMap.GetNextHighestAddress(startAddress);

            if (endAddress == 0xFFFFFFFF)
            {
                throw new InvalidOperationException("Invalid start address for area analysis");
            }

            uint size          = (uint)(endAddress - startAddress); // The size of the block of data
            int  paddingLength = 0;                                 // The number of 4-byte padding values that have been read
            uint prePadding    = 0;                                 // The last non-padding uint32 that was read

            MetaValueGuess pendingGuess = null;                     // If not null and padding is encountered, this guess is confirmed

            for (int offset = 0; offset < size; offset += 4)
            {
                uint value = reader.ReadUInt32();

                long expValue = _expander.Expand(value);

                if (IsPadding(value))
                {
                    if (paddingLength == 0 && pendingGuess != null)
                    {
                        resultMap.AddGuess(pendingGuess);

                        // Add the address to the memory map
                        long address = pendingGuess.Pointer;
                        _memMap.AddAddress(address, (int)reader.Position);
                    }

                    // More padding! :D
                    paddingLength++;
                    pendingGuess = null;
                }
                else
                {
                    pendingGuess = null;
                    if (offset <= size - 8 &&
                        prePadding > 0 &&
                        prePadding < 0x80000000
                        // && (value & 3) == 0
                        && IsValidAddress(expValue) &&
                        expValue + prePadding > value &&
                        IsValidAddress(expValue + prePadding - 1) &&
                        !_memMap.BlockCrossesBoundary(expValue, (int)prePadding))
                    {
                        // Either a reflexive or a data reference
                        // Check the padding to determine which (see the comments at the beginning of this method)
                        if (paddingLength == 2 && offset >= 12 && (prePadding & 3) == 0)
                        {
                            // Found a data reference
                            uint dataSize = prePadding;
                            pendingGuess = new MetaValueGuess(offset - 12, MetaValueType.DataReference, expValue, dataSize);
                            // Guess with Pointer = address, Data1 = data size
                        }
                        else if (paddingLength == 0 && offset >= 4)
                        {
                            // Found a reflexive!
                            uint entryCount = prePadding;
                            pendingGuess = new MetaValueGuess(offset - 4, MetaValueType.Reflexive, expValue, entryCount);
                            // Guess with Pointer = address, Data1 = entry count
                        }
                    }
                    if (paddingLength == 2 && offset >= 12 &&
                        (_classIds.Contains((int)prePadding) || (prePadding == 0xFFFFFFFF && value == 0xFFFFFFFF)))
                    {
                        // Found a tag reference
                        uint classId    = prePadding;
                        uint datumIndex = value;
                        var  guess      = new MetaValueGuess(offset - 12, MetaValueType.TagReference, datumIndex, classId);
                        // Guess with Pointer = datum index, Data1 = class id
                        resultMap.AddGuess(guess);
                    }

                    // This obviously isn't a padding value because IsPadding returned false,
                    // so update padding run information accordingly
                    prePadding    = value;
                    paddingLength = 0;
                }
            }
        }
예제 #5
0
        public void AnalyzeArea(IReader reader, uint startAddress, MetaMap resultMap)
        {
            // Right now, this method only searches for the signatures of a few complex meta values.
            // Reflexives:      int32 entry count + uint32 address     + 4 bytes of padding
            // Data references: int32 size        + 8 bytes of padding + uint32 address
            // Tag references:  int32 class id    + 8 bytes of padding + uint32 datum index
            // ASCII strings:   characters with the values 0 or 0x20 - 0x7F

            // End at the next-highest address
            uint endAddress = _memMap.GetNextHighestAddress(startAddress);
            if (endAddress == 0xFFFFFFFF)
                throw new InvalidOperationException("Invalid start address for area analysis");

            uint size = endAddress - startAddress; // The size of the block of data
            int paddingLength = 0; // The number of 4-byte padding values that have been read
            uint prePadding = 0; // The last non-padding uint32 that was read

            MetaValueGuess pendingGuess = null; // If not null and padding is encountered, this guess is confirmed

            for (int offset = 0; offset < size; offset += 4)
            {
                uint value = reader.ReadUInt32();

                if (IsPadding(value))
                {
                    if (paddingLength == 0 && pendingGuess != null)
                    {
                        resultMap.AddGuess(pendingGuess);

                        // Add the address to the memory map
                        uint address = pendingGuess.Pointer;
                        _memMap.AddAddress(address, (int) reader.Position);
                    }

                    // More padding! :D
                    paddingLength++;
                    pendingGuess = null;
                }
                else
                {
                    pendingGuess = null;
                    if (offset <= size - 8
                        && prePadding > 0
                        && prePadding < 0x80000000
                        && (value & 3) == 0
                        && IsValidAddress(value)
                        && value + prePadding > value
                        && IsValidAddress(value + prePadding - 1)
                        && !_memMap.BlockCrossesBoundary(value, (int) prePadding))
                    {
                        // Either a reflexive or a data reference
                        // Check the padding to determine which (see the comments at the beginning of this method)
                        if (paddingLength == 2 && offset >= 12 && (prePadding & 3) == 0)
                        {
                            // Found a data reference
                            uint dataSize = prePadding;
                            uint address = value;
                            pendingGuess = new MetaValueGuess(offset - 12, MetaValueType.DataReference, address, dataSize);
                            // Guess with Pointer = address, Data1 = data size
                        }
                        else if (paddingLength == 0 && offset >= 4)
                        {
                            // Found a reflexive!
                            uint entryCount = prePadding;
                            uint address = value;
                            pendingGuess = new MetaValueGuess(offset - 4, MetaValueType.Reflexive, address, entryCount);
                            // Guess with Pointer = address, Data1 = entry count
                        }
                    }
                    if (paddingLength == 2 && offset >= 12 &&
                        (_classIds.Contains((int) prePadding) || (prePadding == 0xFFFFFFFF && value == 0xFFFFFFFF)))
                    {
                        // Found a tag reference
                        uint classId = prePadding;
                        uint datumIndex = value;
                        var guess = new MetaValueGuess(offset - 12, MetaValueType.TagReference, datumIndex, classId);
                        // Guess with Pointer = datum index, Data1 = class id
                        resultMap.AddGuess(guess);
                    }

                    // This obviously isn't a padding value because IsPadding returned false,
                    // so update padding run information accordingly
                    prePadding = value;
                    paddingLength = 0;
                }
            }
        }