winmr-api/Services/WinApi.cs
2025-07-02 18:13:00 +03:00

252 lines
12 KiB
C#

// File: Services/WinApi.cs
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text.Json.Serialization;
using WebmrAPI.Utils;
namespace WebmrAPI.Services
{
[SupportedOSPlatform("windows")]
public static class WinApi
{
public const uint PROCESS_QUERY_INFORMATION = 0x00000400;
public const uint PROCESS_VM_READ = 0x00000010;
public const uint PROCESS_VM_OPERATION = 0x00000008;
public static int LastError { get => Marshal.GetLastWin32Error(); }
public static uint MBISize { get => (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)); }
[JsonConverter(typeof(JsonEnumConverter<MemoryState>))]
public enum MemoryState : uint
{
Undefined = 0,
Commit = 0x00001000,
Reserve = 0x00002000,
Free = 0x00010000,
}
[JsonConverter(typeof(JsonEnumConverter<MemoryType>))]
public enum MemoryType : uint
{
Undefined = 0,
Image = 0x01000000,
Mapped = 0x00040000,
Private = 0x00020000,
}
[JsonConverter(typeof(JsonEnumConverter<MemoryPageProtectionState>))]
public enum MemoryPageProtectionState : uint
{
Undefined = 0,
NoAccess = 0x0001,
ReadOnly = 0x0002,
ReadWrite = 0x0004,
WriteCopy = 0x0008,
Execute = 0x0010,
ExecuteRead = 0x0020,
ExecuteReadWrite = 0x0040,
ExecuteWriteCopy = 0x0080,
Guard = 0x0100,
NoCache = 0x0200,
WriteCombine = 0x0400,
}
// --- P/Invoke Declarations ---
// 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;
public UIntPtr RegionSize;
public MemoryState State;
public MemoryPageProtectionState PageProtection;
public MemoryType Type;
}
// 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
);
// --- Module-related P/Invokes (from psapi.dll and kernel32.dll) ---
// https://learn.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-enumprocessmodulesex
[DllImport("psapi.dll", SetLastError = true)]
public static extern bool EnumProcessModulesEx(
IntPtr hProcess,
[Out] IntPtr[] lphModule, // Array to receive module handles
uint cb, // Size of the lphModule array, in bytes
out uint lpcbNeeded, // Number of bytes required to store all module handles
uint dwFilterFlag // Filter for modules (e.g., LIST_MODULES_ALL)
);
// https://learn.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmodulefilenameexw
[DllImport("psapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint GetModuleFileNameEx(
IntPtr hProcess,
IntPtr hModule,
[Out] System.Text.StringBuilder lpFilename,
uint nSize
);
// https://learn.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmodulebasenamew
[DllImport("psapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint GetModuleBaseName(
IntPtr hProcess,
IntPtr hModule,
[Out] System.Text.StringBuilder lpBaseName,
uint nSize
);
// https://learn.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-_moduleinfo
[StructLayout(LayoutKind.Sequential)]
public struct MODULEINFO
{
public IntPtr lpBaseOfDll;
public uint SizeOfImage;
public IntPtr EntryPoint;
}
// https://learn.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getmoduleinformation
[DllImport("psapi.dll", SetLastError = true)]
public static extern bool GetModuleInformation(
IntPtr hProcess,
IntPtr hModule,
out MODULEINFO lpmodinfo,
uint cb
);
// --- Thread-related P/Invokes (from kernel32.dll and ntdll.dll) ---
// https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openthread
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenThread(
uint dwDesiredAccess,
[MarshalAs(UnmanagedType.Bool)] bool bInheritHandle,
uint dwThreadId
);
// https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationthread
[DllImport("ntdll.dll", SetLastError = true)]
public static extern int NtQueryInformationThread(
IntPtr ThreadHandle,
THREAD_INFO_CLASS ThreadInformationClass,
IntPtr ThreadInformation, // Pointer to buffer
uint ThreadInformationLength,
out uint ReturnLength
);
// Enum for ThreadInformationClass in NtQueryInformationThread
// https://ntdoc.m417z.com/threadinfoclass
public enum THREAD_INFO_CLASS : int
{
ThreadBasicInformation, // q: THREAD_BASIC_INFORMATION
ThreadTimes, // q: KERNEL_USER_TIMES
ThreadPriority, // s: KPRIORITY (requires SeIncreaseBasePriorityPrivilege)
ThreadBasePriority, // s: KPRIORITY
ThreadAffinityMask, // s: KAFFINITY
ThreadImpersonationToken, // s: HANDLE
ThreadDescriptorTableEntry, // q: DESCRIPTOR_TABLE_ENTRY (or WOW64_DESCRIPTOR_TABLE_ENTRY)
ThreadEnableAlignmentFaultFixup, // s: BOOLEAN
ThreadEventPair, // Obsolete
ThreadQuerySetWin32StartAddress, // qs: PVOID (requires THREAD_Set_LIMITED_INFORMATION)
ThreadZeroTlsCell, // s: ULONG // TlsIndex // 10
ThreadPerformanceCount, // q: LARGE_INTEGER
ThreadAmILastThread, // q: ULONG
ThreadIdealProcessor, // s: ULONG
ThreadPriorityBoost, // qs: ULONG
ThreadSetTlsArrayAddress, // s: ULONG_PTR
ThreadIsIoPending, // q: ULONG
ThreadHideFromDebugger, // q: BOOLEAN; s: void
ThreadBreakOnTermination, // qs: ULONG
ThreadSwitchLegacyState, // s: void // NtCurrentThread // NPX/FPU
ThreadIsTerminated, // q: ULONG // 20
ThreadLastSystemCall, // q: THREAD_LAST_SYSCALL_INFORMATION
ThreadIoPriority, // qs: IO_PRIORITY_HINT (requires SeIncreaseBasePriorityPrivilege)
ThreadCycleTime, // q: THREAD_CYCLE_TIME_INFORMATION (requires THREAD_QUERY_LIMITED_INFORMATION)
ThreadPagePriority, // qs: PAGE_PRIORITY_INFORMATION
ThreadActualBasePriority, // s: LONG (requires SeIncreaseBasePriorityPrivilege)
ThreadTebInformation, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_SET_CONTEXT)
ThreadCSwitchMon, // Obsolete
ThreadCSwitchPmu, // Obsolete
ThreadWow64Context, // qs: WOW64_CONTEXT, ARM_NT_CONTEXT since 20H1
ThreadGroupInformation, // qs: GROUP_AFFINITY // 30
ThreadUmsInformation, // q: THREAD_UMS_INFORMATION // Obsolete
ThreadCounterProfiling, // q: BOOLEAN; s: THREAD_PROFILING_INFORMATION?
ThreadIdealProcessorEx, // qs: PROCESSOR_NUMBER; s: previous PROCESSOR_NUMBER on return
ThreadCpuAccountingInformation, // q: BOOLEAN; s: HANDLE (NtOpenSession) // NtCurrentThread // since WIN8
ThreadSuspendCount, // q: ULONG // since WINBLUE
ThreadHeterogeneousCpuPolicy, // q: KHETERO_CPU_POLICY // since THRESHOLD
ThreadContainerId, // q: GUID
ThreadNameInformation, // qs: THREAD_NAME_INFORMATION (requires THREAD_SET_LIMITED_INFORMATION)
ThreadSelectedCpuSets, // q: ULONG[]
ThreadSystemThreadInformation, // q: SYSTEM_THREAD_INFORMATION // 40
ThreadActualGroupAffinity, // q: GROUP_AFFINITY // since THRESHOLD2
ThreadDynamicCodePolicyInfo, // q: ULONG; s: ULONG (NtCurrentThread)
ThreadExplicitCaseSensitivity, // qs: ULONG; s: 0 disables, otherwise enables // (requires SeDebugPrivilege and PsProtectedSignerAntimalware)
ThreadWorkOnBehalfTicket, // ALPC_WORK_ON_BEHALF_TICKET // RTL_WORK_ON_BEHALF_TICKET_EX // NtCurrentThread
ThreadSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
ThreadDbgkWerReportActive, // s: ULONG; s: 0 disables, otherwise enables
ThreadAttachContainer, // s: HANDLE (job object) // NtCurrentThread
ThreadManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
ThreadPowerThrottlingState, // qs: POWER_THROTTLING_THREAD_STATE // since REDSTONE3 (set), WIN11 22H2 (query)
ThreadWorkloadClass, // THREAD_WORKLOAD_CLASS // since REDSTONE5 // 50
ThreadCreateStateChange, // since WIN11
ThreadApplyStateChange,
ThreadStrongerBadHandleChecks, // s: ULONG // NtCurrentThread // since 22H1
ThreadEffectiveIoPriority, // q: IO_PRIORITY_HINT
ThreadEffectivePagePriority, // q: ULONG
ThreadUpdateLockOwnership, // THREAD_LOCK_OWNERSHIP // since 24H2
ThreadSchedulerSharedDataSlot, // SCHEDULER_SHARED_DATA_SLOT_INFORMATION
ThreadTebInformationAtomic, // q: THREAD_TEB_INFORMATION (requires THREAD_GET_CONTEXT + THREAD_QUERY_INFORMATION)
ThreadIndexInformation, // THREAD_INDEX_INFORMATION
MaxThreadInfoClass
}
// Structure for ThreadBasicInformation (if needed, though ThreadQuerySetWin32StartAddress directly gives address)
// https://ntdoc.m417z.com/thread_basic_information
[StructLayout(LayoutKind.Sequential)]
public struct THREAD_BASIC_INFORMATION
{
public int ExitStatus;
public IntPtr TebBaseAddress;
public CLIENT_ID ClientId;
public IntPtr AffinityMask;
public int Priority;
public int BasePriority;
}
// https://ntdoc.m417z.com/client_id
[StructLayout(LayoutKind.Sequential)]
public struct CLIENT_ID
{
public IntPtr UniqueProcess;
public IntPtr UniqueThread;
}
}
}