118 lines
4.7 KiB
C#
118 lines
4.7 KiB
C#
|
using System.Runtime.InteropServices;
|
|||
|
using WebmrAPI.Exceptions;
|
|||
|
|
|||
|
namespace WebmrAPI.Services
|
|||
|
{
|
|||
|
public static class WinApi
|
|||
|
{
|
|||
|
// --- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> ---
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> 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).
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
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
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
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)
|
|||
|
|
|||
|
// --- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---
|
|||
|
|
|||
|
// 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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---
|
|||
|
|
|||
|
// 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
|
|||
|
);
|
|||
|
|
|||
|
// --- <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ---
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|||
|
/// </summary>
|
|||
|
public static string GetMemoryProtectString(uint protect)
|
|||
|
{
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|||
|
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|||
|
// <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> PAGE_READONLY, PAGE_READWRITE <20> <20>.<2E>.
|
|||
|
return $"0x{protect:X}";
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|||
|
/// </summary>
|
|||
|
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})";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|||
|
/// </summary>
|
|||
|
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})";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> WinAPI <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
|
|||
|
/// </summary>
|
|||
|
public static void ThrowWinApiErrorIfAny(string methodName)
|
|||
|
{
|
|||
|
int errorCode = Marshal.GetLastWin32Error();
|
|||
|
if (errorCode != 0)
|
|||
|
{
|
|||
|
throw new ExternalException($"WinAPI call {methodName} failed with error code {errorCode}.");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|