Example #1
0
        static void GetLongestPrefixSuffices(BytePattern pattern, ref Int32[] longestPrefixSuffices)
        {
            Int32 patternLength = pattern.Bytes.Length;
            Int32 length        = 0;
            Int32 patternIndex  = 1;

            longestPrefixSuffices[0] = 0;

            while (patternIndex < patternLength)
            {
                if (pattern.Bytes[patternIndex] == pattern.Bytes[length])
                {
                    length++;
                    longestPrefixSuffices[patternIndex] = length;
                    patternIndex++;
                }
                else
                {
                    if (length == 0)
                    {
                        longestPrefixSuffices[patternIndex] = 0;
                        patternIndex++;
                    }
                    else
                    {
                        length = longestPrefixSuffices[length - 1];
                    }
                }
            }
        }
Example #2
0
        public List <UInt64> FindFirstPatternAddresses(AddressRange addressRange, BytePattern pattern)
        {
            List <UInt64> matchAddresses = new List <UInt64>();

            UInt64 currentAddress = addressRange.Start;

            List <Byte[]> byteArrays = new List <Byte[]>();

            while (currentAddress < addressRange.End)
            {
                if (VirtualQueryEx(process.Handle, (IntPtr)currentAddress, out MEMORY_BASIC_INFORMATION64 memoryRegion, (UInt32)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION64))) > 0 &&
                    memoryRegion.RegionSize > 0 &&
                    memoryRegion.State == 0x1000 &&                     // MEM_COMMIT
                    (memoryRegion.Protect & 0x20) > 0)                           // PAGE_EXECUTE_READ

                {
                    var regionStartAddress = memoryRegion.BaseAddress;
                    if (addressRange.Start > regionStartAddress)
                    {
                        regionStartAddress = addressRange.Start;
                    }

                    var regionEndAddress = memoryRegion.BaseAddress + memoryRegion.RegionSize;
                    if (addressRange.End < regionEndAddress)
                    {
                        regionEndAddress = addressRange.End;
                    }

                    UInt64 regionBytesToRead = regionEndAddress - regionStartAddress;
                    Byte[] regionBytes       = new Byte[regionBytesToRead];

                    Int32 lpNumberOfBytesRead = 0;
                    ReadProcessMemory(process.Handle, (IntPtr)regionStartAddress, regionBytes, regionBytes.Length, ref lpNumberOfBytesRead);

                    byteArrays.Add(regionBytes);

                    if (regionBytes.Length == 0 || pattern.Bytes.Length == 0 || regionBytes.Length < pattern.Bytes.Length)
                    {
                        continue;
                    }

                    List <Int32> matchedIndices        = new List <Int32>();
                    Int32[]      longestPrefixSuffices = new Int32[pattern.Bytes.Length];
                    GetLongestPrefixSuffices(pattern, ref longestPrefixSuffices);

                    Int32 textIndex    = 0;
                    Int32 patternIndex = 0;
                    while (textIndex < regionBytes.Length)
                    {
                        if (!pattern.Bytes[patternIndex].HasValue ||
                            regionBytes[textIndex] == pattern.Bytes[patternIndex])
                        {
                            textIndex++;
                            patternIndex++;
                        }

                        if (patternIndex == pattern.Bytes.Length)
                        {
                            matchedIndices.Add(textIndex - patternIndex);
                            patternIndex = longestPrefixSuffices[patternIndex - 1];
                            break;
                        }
                        else if (textIndex < regionBytes.Length &&
                                 (pattern.Bytes[patternIndex].HasValue &&
                                  regionBytes[textIndex] != pattern.Bytes[patternIndex]))
                        {
                            if (patternIndex != 0)
                            {
                                patternIndex = longestPrefixSuffices[patternIndex - 1];
                            }
                            else
                            {
                                textIndex++;
                            }
                        }
                    }

                    if (matchedIndices.Any())
                    {
                        matchAddresses.Add(regionStartAddress + (UInt64)matchedIndices.First());
                    }
                }
                currentAddress = memoryRegion.BaseAddress + memoryRegion.RegionSize;
            }

            return(matchAddresses);
        }