public void CacheMemoryRegions() { memoryRegions.Clear(); InitMemoryRegions(); MemoryProtectionFlags MemFlagsExecutable = MemoryProtectionFlags.PAGE_EXECUTE | MemoryProtectionFlags.PAGE_EXECUTE_READ | MemoryProtectionFlags.PAGE_EXECUTE_READWRITE | MemoryProtectionFlags.PAGE_EXECUTE_WRITECOPY; MemoryProtectionFlags MemFlagsWriteable = MemoryProtectionFlags.PAGE_EXECUTE_READWRITE | MemoryProtectionFlags.PAGE_EXECUTE_WRITECOPY | MemoryProtectionFlags.PAGE_READWRITE | MemoryProtectionFlags.PAGE_WRITECOPY; int regionInfoSize = Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)); for (long scanAddress = 0; scanAddress < Int64.MaxValue;) { MEMORY_BASIC_INFORMATION regionInfo; int result = VirtualQueryEx(cachedProcessHandle, (IntPtr)scanAddress, out regionInfo, (uint)regionInfoSize); if (result != regionInfoSize) { break; } bool bIsCommited = (regionInfo.State & MemoryStateFlags.MEM_COMMIT) != 0; bool bIsGuarded = (regionInfo.Protect & MemoryProtectionFlags.PAGE_GUARD) != 0; bool bIsWritebale = (regionInfo.Protect & MemFlagsWriteable) != 0; bool bIsExecutable = (regionInfo.Protect & MemFlagsExecutable) != 0; bool bShouldCacheRegion = bIsCommited && !bIsGuarded && (bIsWritebale || bIsExecutable); Logger.WriteLine("scan:0x{0}, size:0x{1}, state:[{2}], protect:[{3}], type:0x{4} => {5}", scanAddress.ToString("x"), regionInfo.RegionSize.ToString("x"), regionInfo.State, regionInfo.Protect, regionInfo.Type.ToString("x"), bShouldCacheRegion ? "CACHE" : "meh"); if (bShouldCacheRegion) { MemoryRegionFlags storeType = (bIsWritebale ? MemoryRegionFlags.Writeable : 0) | (bIsExecutable ? MemoryRegionFlags.Executable : 0); MemoryRegionInfo storeInfo = new MemoryRegionInfo { BaseAddress = regionInfo.BaseAddress, Size = regionInfo.RegionSize, Type = storeType, }; memoryRegions.Add(storeInfo); } scanAddress = (long)regionInfo.BaseAddress + (long)regionInfo.RegionSize; } }
public long FindPatternInMemory(byte[] patternBytes, byte[] patternMask, MemoryRegionFlags regionFlags) { foreach (MemoryRegionInfo regionInfo in memoryRegions) { if ((regionInfo.Type & regionFlags) != 0) { byte[] regionMemory = ReadRegionMemory(regionInfo); if (regionMemory != null) { long matchOffset = FindPatternInBuffer(regionMemory, patternBytes, patternMask); if (matchOffset != 0) { matchOffset += (long)regionInfo.BaseAddress; return(matchOffset); } } } } return(0); }
public bool LoadMemoryRegions() { useCachedMemory = false; using (BinaryReader reader = new BinaryReader(File.Open("memory.cache", FileMode.Open))) { int numRegions = reader.ReadInt32(); memoryRegions.Clear(); for (int regIdx = 0; regIdx < numRegions; regIdx++) { long regBaseAddr = reader.ReadInt64(); long regSize = reader.ReadInt64(); MemoryRegionFlags regType = (MemoryRegionFlags)reader.ReadUInt32(); if (regIdx == 0) { regType |= MemoryRegionFlags.MainModule; cachedProcessBase = regBaseAddr; } MemoryRegionInfo regInfo = new MemoryRegionInfo() { BaseAddress = new IntPtr(regBaseAddr), Size = new IntPtr(regSize), Type = regType }; regInfo.CachedData = reader.ReadBytes((int)regSize); memoryRegions.Add(regInfo); } useCachedMemory = true; } return(useCachedMemory); }
public List <long> FindPatternInMemoryAll(byte[] patternBytes, byte[] patternMask, MemoryRegionFlags regionFlags) { List <long> results = new List <long>(); foreach (MemoryRegionInfo regionInfo in memoryRegions) { if ((regionInfo.Type & regionFlags) != 0) { byte[] regionMemory = ReadRegionMemory(regionInfo); if (regionMemory != null) { long matchOffset = FindPatternInBuffer(regionMemory, patternBytes, patternMask); while (matchOffset != 0) { long matchAddr = matchOffset + (long)regionInfo.BaseAddress; results.Add(matchAddr); matchOffset = FindPatternInBuffer(regionMemory, patternBytes, patternMask, matchOffset + patternBytes.Length); } } } } return(results); }