public static PatternByte[] Parse(string pattern) { // check pattern if (pattern.Split(' ').Any(a => a.Length % 2 != 0)) { throw new Exception("Bad pattern"); } string withoutSpaces = pattern.Replace(" ", string.Empty); if (withoutSpaces.Length % 2 != 0) { throw new Exception("Bad pattern"); } int byteCount = withoutSpaces.Length / 2; var arr = new PatternByte[byteCount]; for (int i = 0; i < byteCount; i++) { arr[i] = byte.TryParse(withoutSpaces.Substring(i * 2, 2), NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, out byte b) ? Normal(b) : Wildcard; } return(arr); }
/// <summary> /// Scans a memory region for a pattern. /// </summary> /// <param name="proc">A process to scan</param> /// <param name="pattern">The pattern array to scan for</param> /// <param name="baseAddress">The address to start at</param> /// <param name="size">The size of the region to scan</param> /// <param name="result">The address (on success)</param> /// <returns>Whether the scan was successful or not</returns> public static bool Scan(Process proc, PatternByte[] pattern, ulong baseAddress, ulong size, out ulong result) { result = default; uint step = (uint)Math.Min(size, ScanStep); ulong min = baseAddress; ulong max = min + size; byte[] buffer = new byte[step + pattern.Length - 1]; // skip wildcards, since they would always match uint firstNonWildcard = PatternByte.FirstNonWildcardByte(pattern); for (ulong i = min; i < max; i += step) { // read buffer // TODO: limit to not go outside region? proc.Read(i, buffer, buffer.Length); // loop through buffer for (uint j = 0; j < step; ++j) { bool match = true; // loop through pattern for (uint k = firstNonWildcard; k < pattern.Length; ++k) { if (pattern[k].Match(buffer[j + k])) { continue; } match = false; break; } if (match) { result = (ulong)(i + j); return(true); } } } return(false); }