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; } } }