Update WinApi
This commit is contained in:
parent
49abc808a4
commit
09af9d5091
@ -22,7 +22,7 @@ namespace WebmrAPI.Models
|
||||
}
|
||||
public string? BaseAddress
|
||||
{
|
||||
get => (MemoryAddress > 0) ? $"0x{MemoryAddress:X12}" : null;
|
||||
get => (MemoryAddress > 0) ? $"0x{MemoryAddress:X16}" : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,26 @@
|
||||
// File: Models/MemoryRegionInfo.cs
|
||||
|
||||
using WebmrAPI.Services;
|
||||
|
||||
namespace WebmrAPI.Models
|
||||
{
|
||||
public class MemoryRegionInfo : MemoryRegion
|
||||
{
|
||||
private string _state = String.Empty;
|
||||
private string _protect = String.Empty;
|
||||
private string _type = String.Empty;
|
||||
private WinApi.MemoryState _state = 0;
|
||||
private WinApi.MemoryPageProtectionState _protect = 0;
|
||||
private WinApi.MemoryType _type = 0;
|
||||
|
||||
public string State
|
||||
public WinApi.MemoryState MemoryState
|
||||
{
|
||||
get => LockedGet(ref _state);
|
||||
set => LockedSet(ref _state, value);
|
||||
}
|
||||
public string Protect
|
||||
public WinApi.MemoryPageProtectionState MemoryPageProtection
|
||||
{
|
||||
get => LockedGet(ref _protect);
|
||||
set => LockedSet(ref _protect, value);
|
||||
}
|
||||
public string Type
|
||||
public WinApi.MemoryType MemoryType
|
||||
{
|
||||
get => LockedGet(ref _type);
|
||||
set => LockedSet(ref _type, value);
|
||||
|
@ -34,7 +34,7 @@ namespace WebmrAPI.Models
|
||||
[JsonIgnore]
|
||||
public double ProcessorTime
|
||||
{
|
||||
get { lock (_lock) return (_lastPTime - _curPTime).TotalMilliseconds; }
|
||||
get { lock (_lock) return (_curPTime - _lastPTime).TotalMilliseconds; }
|
||||
}
|
||||
public int PID
|
||||
{
|
||||
|
@ -128,15 +128,15 @@ namespace WebmrAPI.Services
|
||||
break;
|
||||
}
|
||||
|
||||
if (mbi.State == WinApi.MEM_COMMIT || mbi.State == WinApi.MEM_RESERVE)
|
||||
if (mbi.State == WinApi.MemoryState.Commit || mbi.State == WinApi.MemoryState.Reserve)
|
||||
{
|
||||
regions.Add(new MemoryRegionInfo
|
||||
{
|
||||
MemoryAddress = mbi.BaseAddress.ToInt64(),
|
||||
MemorySize = mbi.RegionSize.ToUInt64(),
|
||||
State = WinApi.GetStateString(mbi.State),
|
||||
Protect = WinApi.GetProtectString(mbi.Protect),
|
||||
Type = WinApi.GetTypeString(mbi.Type)
|
||||
MemoryState = mbi.State,
|
||||
MemoryPageProtection = mbi.PageProtection,
|
||||
MemoryType = mbi.Type
|
||||
});
|
||||
}
|
||||
|
||||
@ -153,7 +153,7 @@ namespace WebmrAPI.Services
|
||||
private void PopulateBaseProcessInfo(ProcessInfo dst, System.Diagnostics.Process process, Dictionary<int, (string? Name, string? CommandLine, int ParentPID)> wmiData)
|
||||
{
|
||||
dst.PID = process.Id;
|
||||
dst.MemorySize = (ulong)process.VirtualMemorySize64;
|
||||
dst.MemorySize = (ulong)process.WorkingSet64;
|
||||
dst.ThreadCount = process.Threads.Count;
|
||||
dst.TotalProcessorTime = process.TotalProcessorTime;
|
||||
dst.MemoryAddress = 0x000000000000;
|
||||
|
@ -1,60 +1,58 @@
|
||||
// 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 const uint MEM_COMMIT = 0x00001000;
|
||||
public const uint MEM_FREE = 0x00010000;
|
||||
public const uint MEM_RESERVE = 0x00002000;
|
||||
|
||||
public const uint MEM_IMAGE = 0x01000000;
|
||||
public const uint MEM_MAPPED = 0x00040000;
|
||||
public const uint MEM_PRIVATE = 0x00020000;
|
||||
|
||||
public static int LastError { get => Marshal.GetLastWin32Error(); }
|
||||
public static uint MBISize { get => (uint)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION)); }
|
||||
|
||||
private static string GetHexValue(uint data)
|
||||
[JsonConverter(typeof(JsonEnumConverter<MemoryState>))]
|
||||
public enum MemoryState : uint
|
||||
{
|
||||
return $"0x{data:X8}";
|
||||
Undefined = 0,
|
||||
Commit = 0x00001000,
|
||||
Reserve = 0x00002000,
|
||||
Free = 0x00010000,
|
||||
}
|
||||
|
||||
public static string GetStateString(uint state)
|
||||
[JsonConverter(typeof(JsonEnumConverter<MemoryType>))]
|
||||
public enum MemoryType : uint
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case MEM_COMMIT: return "MEM_COMMIT";
|
||||
case MEM_FREE: return "MEM_FREE";
|
||||
case MEM_RESERVE: return "MEM_RESERVE";
|
||||
default: return GetHexValue(state);
|
||||
}
|
||||
Undefined = 0,
|
||||
Image = 0x01000000,
|
||||
Mapped = 0x00040000,
|
||||
Private = 0x00020000,
|
||||
}
|
||||
|
||||
public static string GetProtectString(uint protect)
|
||||
[JsonConverter(typeof(JsonEnumConverter<MemoryPageProtectionState>))]
|
||||
public enum MemoryPageProtectionState : uint
|
||||
{
|
||||
switch (protect)
|
||||
{
|
||||
default: return GetHexValue(protect);
|
||||
}
|
||||
Undefined = 0,
|
||||
NoAccess = 0x0001,
|
||||
ReadOnly = 0x0002,
|
||||
ReadWrite = 0x0004,
|
||||
WriteCopy = 0x0008,
|
||||
Execute = 0x0010,
|
||||
ExecuteRead = 0x0020,
|
||||
ExecuteReadWrite = 0x0040,
|
||||
ExecuteWriteCopy = 0x0080,
|
||||
Guard = 0x0100,
|
||||
NoCache = 0x0200,
|
||||
WriteCombine = 0x0400,
|
||||
}
|
||||
|
||||
public static string GetTypeString(uint type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MEM_IMAGE: return "MEM_IMAGE";
|
||||
case MEM_MAPPED: return "MEM_MAPPED";
|
||||
case MEM_PRIVATE: return "MEM_PRIVATE";
|
||||
default: return GetHexValue(type);
|
||||
}
|
||||
}
|
||||
// --- P/Invoke Declarations ---
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-memory_basic_information
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
@ -65,9 +63,9 @@ namespace WebmrAPI.Services
|
||||
public uint AllocationProtect;
|
||||
public ushort PartitionId;
|
||||
public UIntPtr RegionSize;
|
||||
public uint State;
|
||||
public uint Protect;
|
||||
public uint Type;
|
||||
public MemoryState State;
|
||||
public MemoryPageProtectionState PageProtection;
|
||||
public MemoryType Type;
|
||||
}
|
||||
|
||||
|
||||
@ -92,5 +90,162 @@ namespace WebmrAPI.Services
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
54
Utils/JsonEnumConverter.cs
Normal file
54
Utils/JsonEnumConverter.cs
Normal file
@ -0,0 +1,54 @@
|
||||
// File: Utils/JsonEnumConverter.cs
|
||||
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace WebmrAPI.Utils
|
||||
{
|
||||
public class JsonEnumConverter<T> : JsonConverter<T> where T : Enum
|
||||
{
|
||||
private T GetDefaultValue(Type type)
|
||||
{
|
||||
if (Enum.TryParse(type, "Undefined", true, out object? result) && result != null)
|
||||
{
|
||||
return (T)result;
|
||||
}
|
||||
return (T)Enum.ToObject(type, 0);
|
||||
}
|
||||
|
||||
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.String)
|
||||
{
|
||||
if (Enum.TryParse(typeToConvert, reader.GetString(), true, out object? result) && result != null)
|
||||
{
|
||||
return (T)result;
|
||||
}
|
||||
}
|
||||
else if (reader.TokenType == JsonTokenType.Number)
|
||||
{
|
||||
if (reader.TryGetInt32(out int intValue))
|
||||
{
|
||||
T status = (T)Enum.ToObject(typeToConvert, intValue);
|
||||
if (Enum.IsDefined(typeof(T), status))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
return GetDefaultValue(typeToConvert);
|
||||
}
|
||||
|
||||
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
|
||||
{
|
||||
if (Enum.IsDefined(typeof(T), value))
|
||||
{
|
||||
writer.WriteStringValue(value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteStringValue("Undefined");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user