public static ReadMemoryResults ReadMemory() { ReadMemoryResults results = 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; Process[] processes = ProcessManager.GetTibiaProcesses(); if (processes == null || processes.Length == 0) { return(null); } results = new ReadMemoryResults(); flashClient = ProcessManager.IsFlashClient(); Dictionary <int, HashSet <long> > newWhitelistedAddresses = null; Interlocked.Exchange(ref newWhitelistedAddresses, whiteListedAddresses); foreach (Process process in processes) { HashSet <long> whitelist; if (!newWhitelistedAddresses.TryGetValue(process.Id, out whitelist)) { continue; } IntPtr processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_WM_READ, false, process.Id); int bytesRead = 0; // number of bytes read with ReadProcessMemory foreach (long addr in whitelist) { 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); } } process.Dispose(); } FinalCleanup(results); return(results); }
private void detectFlashClientButton_Click(object sender, EventArgs e) { ProcessManager.DetectFlashClient(); }
/// <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; } flashClient = ProcessManager.IsFlashClient(); 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 = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_WM_READ, false, process.Id); 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 void ShowNotification(NotificationForm f, string command, string screenshot_path = "") { if (f == null) { return; } if (screenshot_path == "") { TibialyzerCommand cmd = new TibialyzerCommand(command); command_stack.Push(cmd); f.command = cmd; } f.Visible = false; int richX = -1; int richY = -1; int anchor = 0; int duration = 5; int group = 0; for (int it = 0; it < Constants.NotificationTypeObjects.Count; it++) { if (f.GetType() == Constants.NotificationTypeObjects[it]) { string settingObject = Constants.NotificationTypes[it].Replace(" ", ""); richX = SettingsManager.getSettingInt(settingObject + "XOffset"); richY = SettingsManager.getSettingInt(settingObject + "YOffset"); anchor = SettingsManager.getSettingInt(settingObject + "Anchor"); duration = SettingsManager.getSettingInt(settingObject + "Duration"); group = Math.Min(Math.Max(SettingsManager.getSettingInt(settingObject + "Group"), 0), 9); break; } } f.notificationDuration = duration; f.LoadForm(); if (screenshot_path != "") { Bitmap bitmap = new Bitmap(f.Width, f.Height); f.DrawToBitmap(bitmap, new Rectangle(0, 0, f.Width, f.Height)); foreach (Control c in f.Controls) { c.DrawToBitmap(bitmap, new Rectangle(new Point(Math.Min(Math.Max(c.Location.X, 0), f.Width), Math.Min(Math.Max(c.Location.Y, 0), f.Height)), c.Size)); } bitmap.Save(screenshot_path); bitmap.Dispose(); f.Dispose(); return; } if (NotificationFormGroups[group] != null) { NotificationFormGroups[group].close(); } int position_x = 0, position_y = 0; Screen screen; Process tibia_process = ProcessManager.GetTibiaProcess(); if (tibia_process == null) { screen = Screen.FromControl(MainForm.mainForm); } else { screen = Screen.FromHandle(tibia_process.MainWindowHandle); } int xOffset = richX == -1 ? 30 : richX; int yOffset = richY == -1 ? 30 : richY; switch (anchor) { case 3: position_x = screen.WorkingArea.Right - xOffset - f.Width; position_y = screen.WorkingArea.Bottom - yOffset - f.Height; break; case 2: position_x = screen.WorkingArea.Left + xOffset; position_y = screen.WorkingArea.Bottom - yOffset - f.Height; break; case 1: position_x = screen.WorkingArea.Right - xOffset - f.Width; position_y = screen.WorkingArea.Top + yOffset; break; default: position_x = screen.WorkingArea.Left + xOffset; position_y = screen.WorkingArea.Top + yOffset; break; } f.StartPosition = FormStartPosition.Manual; f.SetDesktopLocation(position_x, position_y); f.TopMost = true; f.Show(); NotificationFormGroups[group] = f; }