public static IEnumerable <Tuple <MEMORY_BASIC_INFORMATION, byte[]> > ScanProcess(Process process) { byte[] dataBuffer = null; SYSTEM_INFO sys_info; GetSystemInfo(out sys_info); IntPtr proc_min_address = sys_info.minimumApplicationAddress; IntPtr proc_max_address = sys_info.maximumApplicationAddress; long proc_min_address_l = (long)proc_min_address; long proc_max_address_l = (long)proc_max_address; long sys_min_address_l = (long)proc_min_address; IntPtr processHandle = MemoryReader.OpenProcess(process); MEMORY_BASIC_INFORMATION mem_basic_info; int bytesRead = 0; // number of bytes read with ReadProcessMemory while (proc_min_address_l < proc_max_address_l) { proc_min_address = new IntPtr(proc_min_address_l); // 28 = sizeof(MEMORY_BASIC_INFORMATION) VirtualQueryEx(processHandle, proc_min_address, out mem_basic_info, 28); long addr = (long)proc_min_address; // check if this memory chunk is accessible if (mem_basic_info.Protect == PAGE_READWRITE && mem_basic_info.State == MEM_COMMIT) { if (dataBuffer == null || dataBuffer.Length < mem_basic_info.RegionSize) { dataBuffer = new byte[mem_basic_info.RegionSize]; } // read everything in the buffer above ReadProcessMemory((int)processHandle, (int)mem_basic_info.BaseAddress, dataBuffer, mem_basic_info.RegionSize, ref bytesRead); yield return(new Tuple <MEMORY_BASIC_INFORMATION, byte[]>(mem_basic_info, dataBuffer)); } // move to the next memory chunk proc_min_address_l += mem_basic_info.RegionSize; } //CloseHandle(processHandle); yield break; }
public static void ReadMemoryWhiteList(Process process, Dictionary <int, HashSet <long> > newWhitelistedAddresses, bool flashClient, ReadMemoryResults results) { HashSet <long> whitelist; if (!newWhitelistedAddresses.TryGetValue(process.Id, out whitelist)) { return; } IntPtr processHandle = MemoryReader.OpenProcess(process); int bytesRead = 0; // number of bytes read with ReadProcessMemory foreach (long addr in whitelist) { IntPtr proc_min_address = new IntPtr(addr); MEMORY_BASIC_INFORMATION mem_basic_info; VirtualQueryEx(processHandle, proc_min_address, out mem_basic_info, 28); if (mem_basic_info.Protect == PAGE_READWRITE && mem_basic_info.State == MEM_COMMIT) { if (memoryBuffer == null || memoryBuffer.Length < mem_basic_info.RegionSize) { memoryBuffer = new byte[mem_basic_info.RegionSize]; } // read everything in the buffer above ReadProcessMemory((int)processHandle, mem_basic_info.BaseAddress, memoryBuffer, mem_basic_info.RegionSize, ref bytesRead); // scan the memory for strings that start with timestamps and end with the null terminator ('\0') IEnumerable <string> timestampLines; if (!flashClient) { timestampLines = Parser.FindTimestamps(memoryBuffer, bytesRead); } else { timestampLines = Parser.FindTimestampsFlash(memoryBuffer, bytesRead); } SearchChunk(timestampLines, results); } } }
public static void ReadMemoryInternal(Process process, ReadMemoryResults results) { int currentAddress = process.MainModule.BaseAddress.ToInt32(); IntPtr ptr = MemoryReader.OpenProcess(process); if (ptr == null) { return; } int processHandle = ptr.ToInt32(); currentAddress += (int)MemoryReader.TabsBaseAddress; currentAddress = MemoryReader.ReadInt32(currentAddress, processHandle); currentAddress = MemoryReader.ReadInt32(currentAddress + 0x24, processHandle); currentAddress = MemoryReader.ReadInt32(currentAddress + 0x10, processHandle); currentAddress = MemoryReader.ReadInt32(currentAddress + 0x10, processHandle); int tabsAddress = MemoryReader.ReadInt32(currentAddress + 0x30, processHandle); //first tab node address is tabsAddress + 0x24 int tabNodeAddress = MemoryReader.ReadInt32(tabsAddress + 0x24, processHandle); int tabCount = 0; //repeat until tab node address = 0x0 while (tabNodeAddress != 0x0) { tabCount++; //use 0x30 for longer name (possibly upto 30 bytes) //0x2C will use '...' for names longer than 15 chars int tabNamePointer = MemoryReader.ReadInt32(tabNodeAddress + 0x2C, processHandle); string tabName = MemoryReader.ReadString(tabNamePointer, 16, processHandle); int tabMessagesDataStructure = MemoryReader.ReadInt32(tabNodeAddress + 0x24, processHandle); bool serverLog = tabName == "Server Log"; // only read log messages from the server log; only read chat messages from other tabs IEnumerable <string> tabMessages = ReadTabMessages(processHandle, tabMessagesDataStructure); SearchChunk(tabMessages, results, !serverLog, serverLog); //next tab node pointer is current tab node address + 0x10 tabNodeAddress = MemoryReader.ReadInt32(tabNodeAddress + 0x10, processHandle); } }
/// <summary> /// Scan the memory for any chunks that are missing from the whitelist table /// </summary> public static void ScanMissingChunks() { SYSTEM_INFO sys_info; GetSystemInfo(out sys_info); IntPtr proc_min_address = sys_info.minimumApplicationAddress; IntPtr proc_max_address = sys_info.maximumApplicationAddress; long proc_min_address_l = (long)proc_min_address; long proc_max_address_l = (long)proc_max_address; long sys_min_address_l = (long)proc_min_address; Process[] processes = ProcessManager.GetTibiaProcesses(); if (processes == null || processes.Length == 0) { return; } var newWhitelistedAddresses = whiteListedAddresses.ToDictionary(x => x.Key, x => new HashSet <long>(x.Value)); foreach (Process process in processes) { HashSet <long> whitelist; if (!newWhitelistedAddresses.TryGetValue(process.Id, out whitelist)) { whitelist = new HashSet <long>(); newWhitelistedAddresses[process.Id] = whitelist; } proc_min_address_l = sys_min_address_l; IntPtr processHandle = MemoryReader.OpenProcess(process); MEMORY_BASIC_INFORMATION mem_basic_info; List <int> stamps = TimestampManager.getLatestStamps(3, ignoreStamp); int bytesRead = 0; // number of bytes read with ReadProcessMemory try { while (proc_min_address_l < proc_max_address_l) { proc_min_address = new IntPtr(proc_min_address_l); // 28 = sizeof(MEMORY_BASIC_INFORMATION) VirtualQueryEx(processHandle, proc_min_address, out mem_basic_info, 28); long addr = (long)proc_min_address; // check if this memory chunk is accessible if (mem_basic_info.Protect == PAGE_READWRITE && mem_basic_info.State == MEM_COMMIT) { if (!whitelist.Contains(addr)) { if (missingChunksBuffer == null || missingChunksBuffer.Length < mem_basic_info.RegionSize) { missingChunksBuffer = new byte[mem_basic_info.RegionSize]; } // read everything in the buffer above ReadProcessMemory((int)processHandle, mem_basic_info.BaseAddress, missingChunksBuffer, mem_basic_info.RegionSize, ref bytesRead); // scan the memory for strings that start with timestamps and end with the null terminator ('\0') IEnumerable <string> timestampLines; if (!FlashClient) { timestampLines = Parser.FindTimestamps(missingChunksBuffer, bytesRead); // if there are any timestamps found, add the address to the list of whitelisted addresses if (timestampLines.Any(x => stamps.Contains(TimestampManager.getStamp(int.Parse(x.Substring(0, 2)), int.Parse(x.Substring(3, 2)))))) { whitelist.Add(addr); } } else { if (Parser.HasAnyValidTimestampsFlash(missingChunksBuffer, bytesRead, stamps)) { whitelist.Add(addr); } } } } // move to the next memory chunk proc_min_address_l += mem_basic_info.RegionSize; } } catch (Exception ex) { Console.WriteLine(ex.Message); return; } } Interlocked.Exchange(ref whiteListedAddresses, newWhitelistedAddresses); }
public static Process[] GetTibiaProcesses() { if (TibiaClientName == null) { Dictionary <int, string> candidateProcess = new Dictionary <int, string>(); foreach (Process proc in Process.GetProcesses()) { string name = proc.ProcessName.ToLower(); if (TibiaClientType == "Flash-Firefox") { if (proc.ProcessName.Contains("flashplayerplugin", StringComparison.InvariantCultureIgnoreCase)) { if (!candidateProcess.ContainsKey(3)) { candidateProcess.Add(3, proc.ProcessName); } } else if (proc.ProcessName.Contains("flashplayer", StringComparison.InvariantCultureIgnoreCase)) { if (!candidateProcess.ContainsKey(2)) { candidateProcess.Add(2, proc.ProcessName); } } else if (proc.ProcessName.Contains("flash", StringComparison.InvariantCultureIgnoreCase)) { if (!candidateProcess.ContainsKey(1)) { candidateProcess.Add(1, proc.ProcessName); } } } else if (TibiaClientType == "Flash-Chrome") { if (proc.ProcessName.Contains("chrome", StringComparison.InvariantCultureIgnoreCase)) { if (!candidateProcess.ContainsKey(3)) { candidateProcess.Add(3, proc.ProcessName); } } } } if (candidateProcess.Count == 0) { return(null); } TibiaClientName = candidateProcess[candidateProcess.Keys.Max()]; } Process[] p = Process.GetProcessesByName(TibiaClientName); if (p.Length > 0) { if (ReadMemoryManager.FlashClient) { return(p); } if (TibiaClientName.Contains("tibia", StringComparison.OrdinalIgnoreCase)) { MemoryReader.OpenProcess(p[0]); } return(new Process[1] { p[0] }); } return(null); }