Example #1
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;
        }
Example #2
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)
                        && (uint)(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;
                        MetaValueGuess 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;
                }
            }
        }