using System.Runtime.InteropServices; using WebmrAPI.Exceptions; namespace WebmrAPI.Services { public static class WinApi { // --- Константы и флаги --- // Флаги доступа к процессу для OpenProcess public const uint PROCESS_QUERY_INFORMATION = 0x0400; // Required to retrieve certain information about a process, such as its token, exit code, and priority class. public const uint PROCESS_VM_READ = 0x0010; // Required to read memory in a process. public const uint PROCESS_VM_OPERATION = 0x0008; // Required to perform an operation on the address space of a process (e.g., VirtualQueryEx). // Состояния памяти public const uint MEM_COMMIT = 0x1000; // Allocated and committed public const uint MEM_FREE = 0x10000; // Free (not reserved or committed) public const uint MEM_RESERVE = 0x2000; // Reserved // Типы памяти public const uint MEM_IMAGE = 0x1000000; // Mapped into the view of an image section public const uint MEM_MAPPED = 0x40000; // Mapped into the view of a data section public const uint MEM_PRIVATE = 0x20000; // Private (non-shared) // --- Структуры данных --- // https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-memory_basic_information [StructLayout(LayoutKind.Sequential)] public struct MEMORY_BASIC_INFORMATION { public IntPtr BaseAddress; public IntPtr AllocationBase; public uint AllocationProtect; public ushort PartitionId; // Added in Windows 10, version 1709 public UIntPtr RegionSize; // Use UIntPtr for size, as it's pointer-sized public uint State; public uint Protect; public uint Type; } // --- P/Invoke Объявления Функций --- // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr OpenProcess( uint dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, uint dwProcessId ); // https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool CloseHandle(IntPtr hObject); // https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-virtualqueryex [DllImport("kernel32.dll", SetLastError = true)] public static extern int VirtualQueryEx( IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength ); // --- Вспомогательные Методы --- /// /// Получает человекочитаемое строковое представление для флага защиты памяти. /// public static string GetMemoryProtectString(uint protect) { // Здесь можно реализовать более детальное отображение флагов защиты. // Для простоты, пока просто возвращаем шестнадцатеричное значение. // В дальнейшем можно расширить для PAGE_READONLY, PAGE_READWRITE и т.д. return $"0x{protect:X}"; } /// /// Получает человекочитаемое строковое представление для состояния памяти. /// public static string GetMemoryStateString(uint state) { switch (state) { case MEM_COMMIT: return "MEM_COMMIT"; case MEM_FREE: return "MEM_FREE"; case MEM_RESERVE: return "MEM_RESERVE"; default: return $"Unknown (0x{state:X})"; } } /// /// Получает человекочитаемое строковое представление для типа памяти. /// public static string GetMemoryTypeString(uint type) { switch (type) { case MEM_IMAGE: return "MEM_IMAGE"; case MEM_MAPPED: return "MEM_MAPPED"; case MEM_PRIVATE: return "MEM_PRIVATE"; default: return $"Unknown (0x{type:X})"; } } /// /// Проверяет последнюю ошибку WinAPI и выбрасывает исключение, если ошибка есть. /// public static void ThrowWinApiErrorIfAny(string methodName) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode != 0) { throw new ExternalException($"WinAPI call {methodName} failed with error code {errorCode}."); } } } }