252 lines
12 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|