256 lines
8.2 KiB
ObjectPascal
256 lines
8.2 KiB
ObjectPascal
{*******************************************************}
|
|
{ MiTeC Common Routines }
|
|
{ NT Native API }
|
|
{ }
|
|
{ }
|
|
{ Copyright (c) 1997-2021 Michal Mutl }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
{$INCLUDE Compilers.inc}
|
|
|
|
unit MiTeC_NativeAPI;
|
|
|
|
interface
|
|
|
|
uses {$IFDEF RAD9PLUS}
|
|
WinAPI.Windows, System.SysUtils,
|
|
{$ELSE}
|
|
Windows, SysUtils,
|
|
{$ENDIF}
|
|
MiTeC_Windows, MiTeC_NativeDefs;
|
|
|
|
var
|
|
NTDLLHandle: THandle = 0;
|
|
UnloadNTDLL: Boolean;
|
|
|
|
NtOpenSection: TNativeOpenSection = nil;
|
|
NtClose: TNativeClose = nil;
|
|
NtQueryInformationToken: TNativeQueryInformationToken = nil;
|
|
NtOpenProcessToken: TNativeOpenProcessToken = nil;
|
|
NtOpenProcess: TNativeOpenProcess = nil;
|
|
NtQuerySystemInformation: TNativeQuerySystemInformation = nil;
|
|
NtCreateSection: TNativeCreateSection = nil;
|
|
NtMapViewOfSection: TNativeMapViewOfSection = nil;
|
|
NtUnmapViewOfSection: TNativeUnmapViewOfSection = nil;
|
|
NtCreateFile: TNativeCreateFile = nil;
|
|
NtOpenFile: TNativeOpenFile = nil;
|
|
NtQueryObject: TNativeQueryObject = nil;
|
|
NtQueryInformationProcess: TNativeQueryInformationProcess = nil;
|
|
NtQueryInformationThread: TNativeQueryInformationThread = nil;
|
|
NtQueryInformationFile: TNativeQueryInformationFile = nil;
|
|
NtDuplicateObject: TNativeDuplicateObject = nil;
|
|
NtCreateToken: TNativeCreateToken = nil;
|
|
NtDeviceIoControlFile: TNativeDeviceIoControlFile = nil;
|
|
NtSystemDebugControl: TNativeSystemDebugControl = nil;
|
|
NtCreateProcess: TNativeCreateProcess = nil;
|
|
NtTerminateProcess: TNativeTerminateProcess = nil;
|
|
RtlAdjustPrivilege: TRtlAdjustPrivilege = nil;
|
|
NtOpenThread: TNtOpenThread = nil;
|
|
RtlIpv4AddressToString: TRtlIpv4AddressToString = nil;
|
|
RtlIpv6AddressToString: TRtlIpv6AddressToString = nil;
|
|
NtReadVirtualMemory: TNtReadVirtualMemory = nil;
|
|
RtlGetCompressionWorkSpaceSize: TRtlGetCompressionWorkSpaceSize = nil;
|
|
RtlDeCompressBuffer: TRtlDeCompressBuffer = nil;
|
|
RtlDeCompressBufferEx: TRtlDeCompressBufferEx = nil;
|
|
RtlCompressBuffer: TRtlCompressBuffer = nil;
|
|
NtSuspendProcess: TNtSuspendProcess = nil;
|
|
NtResumeProcess: TNtResumeProcess = nil;
|
|
|
|
function InitNativeAPI: boolean;
|
|
procedure FreeNativeAPI;
|
|
|
|
//function NativeGetCPUCount: Byte;
|
|
function NativeQueryProcessorPerformanceDistribution(out ABuffer: PSystemProcessorPerformanceDistribution): boolean;
|
|
|
|
const
|
|
cKWaitReason: array[TKWaitReason] of string = (
|
|
'Executive',
|
|
'FreePage',
|
|
'PageIn',
|
|
'PoolAllocation',
|
|
'DelayExecution',
|
|
'Suspended',
|
|
'UserRequest',
|
|
'WrExecutive',
|
|
'WrFreePage',
|
|
'WrPageIn',
|
|
'WrPoolAllocation',
|
|
'WrDelayExecution',
|
|
'WrSuspended',
|
|
'WrUserRequest',
|
|
'WrEventPair',
|
|
'WrQueue',
|
|
'WrLpcReceive',
|
|
'WrLpcReply',
|
|
'WrVirtualMemory',
|
|
'WrPageOut',
|
|
'WrRendezvous',
|
|
'WrKeyedEvent',
|
|
'WrTerminated',
|
|
'WrProcessInSwap',
|
|
'WrCpuRateControl',
|
|
'WrCalloutStack',
|
|
'WrKernel',
|
|
'WrResource',
|
|
'WrPushLock',
|
|
'WrMutex',
|
|
'WrQuantumEnd',
|
|
'WrDispatchInt',
|
|
'WrPreempted',
|
|
'WrYieldExecution',
|
|
'WrFastMutex',
|
|
'WrGuardedMutex',
|
|
'WrRundown',
|
|
'WrAlertByThreadId',
|
|
'WrDeferredPreempt',
|
|
'WrPhysicalFault',
|
|
'MaximumWaitReason');
|
|
|
|
cThreadState: array[TThreadState] of string = (
|
|
'Initialized',
|
|
'Ready',
|
|
'Running',
|
|
'Standby',
|
|
'Terminated',
|
|
'Wait',
|
|
'Transition',
|
|
'DeferredReady',
|
|
'GateWaitObsolete',
|
|
'WaitingForProcessInSwap',
|
|
'MaximumThreadState');
|
|
|
|
cSystemHandleType: array[TSystemHandleType] of string = (
|
|
'Unknown',
|
|
'Type',
|
|
'Directory',
|
|
'SymbolicLink',
|
|
'Token',
|
|
'Process',
|
|
'Thread',
|
|
'Job',
|
|
'DebugObject',
|
|
'Event',
|
|
'EventPair',
|
|
'Mutant',
|
|
'Callback',
|
|
'Semaphore',
|
|
'Timer',
|
|
'Profile',
|
|
'KeyedEvent',
|
|
'WindowStation',
|
|
'Desktop',
|
|
'Section',
|
|
'Key',
|
|
'Port',
|
|
'WaitablePort',
|
|
'Adapter',
|
|
'Controller',
|
|
'Device',
|
|
'Driver',
|
|
'IOCompletion',
|
|
'File',
|
|
'WMIGUID');
|
|
|
|
//function CreateSystemToken: THandle;
|
|
|
|
implementation
|
|
|
|
//uses MiTeC_NtSecAPI, MiTeC_Routines;
|
|
|
|
function InitNativeAPI;
|
|
begin
|
|
NTDLLHandle:=GetModuleHandle(NTDLL_DLL);
|
|
UnloadNTDLL:=NTDLLHandle=0;
|
|
if NTDLLHandle=0 then
|
|
NTDLLHandle:=LoadLibrary(NTDLL_DLL);
|
|
if (NTDLLHandle<>0) and not Assigned(NtQueryObject) then begin
|
|
@NtQueryInformationToken:=GetProcAddress(NTDLLHandle,'NtQueryInformationToken');
|
|
@NtOpenProcessToken:=GetProcAddress(NTDLLHandle,'NtOpenProcessToken');
|
|
@NtOpenSection:=GetProcAddress(NTDLLHandle,'NtOpenSection');
|
|
@NtClose:=GetProcAddress(NTDLLHandle,'NtClose');
|
|
@NtOpenProcess:=GetProcAddress(NTDLLHandle,'NtOpenProcess');
|
|
@NtCreateProcess:=GetProcAddress(NTDLLHandle,'NtCreateProcess');
|
|
@NtQuerySystemInformation:=GetProcAddress(NTDLLHandle,'NtQuerySystemInformation');
|
|
@NtCreateSection:=GetProcAddress(NTDLLHandle,'NtCreateSection');
|
|
@NtCreateToken:=GetProcAddress(NTDLLHandle,'NtCreateToken');
|
|
@NtMapViewOfSection:=GetProcAddress(NTDLLHandle,'NtMapViewOfSection');
|
|
@NtUnmapViewOfSection:=GetProcAddress(NTDLLHandle,'NtUnmapViewOfSection');
|
|
@NtOpenFile:=GetProcAddress(NTDLLHandle,'NtOpenFile');
|
|
@NtCreateFile:=GetProcAddress(NTDLLHandle,'NtCreateFile');
|
|
@NtQueryObject:=GetProcAddress(NTDLLHandle,'NtQueryObject');
|
|
@NtQueryInformationProcess:=GetProcAddress(NTDLLHandle,'NtQueryInformationProcess');
|
|
@NtQueryInformationThread:=GetProcAddress(NTDLLHandle,'NtQueryInformationThread');
|
|
@NtQueryInformationFile:=GetProcAddress(NTDLLHandle,'NtQueryInformationFile');
|
|
@NtDuplicateObject:=GetProcAddress(NTDLLHandle,'NtDuplicateObject');
|
|
@NtDeviceIoControlFile:=GetProcAddress(NTDLLHandle,'NtDeviceIoControlFile');
|
|
@NtSystemDebugControl:=GetProcAddress(NTDLLHandle,'ZwSystemDebugControl');
|
|
@NtTerminateProcess:=GetProcAddress(NTDLLHandle,'ZwTerminateProcess');
|
|
@RtlAdjustPrivilege:=GetProcAddress(NTDLLHandle,'RtlAdjustPrivilege');
|
|
@NtOpenThread:=GetProcAddress(NTDLLHandle,'NtOpenThread');
|
|
@RtlIpv4AddressToString:=GetProcAddress(NTDLLHandle,{$IFDEF UNICODE}'RtlIpv4AddressToStringW'{$ELSE}'RtlIpv4AddressToStringA'{$ENDIF});
|
|
@RtlIpv6AddressToString:=GetProcAddress(NTDLLHandle,{$IFDEF UNICODE}'RtlIpv6AddressToStringW'{$ELSE}'RtlIpv6AddressToStringA'{$ENDIF});
|
|
@NtReadVirtualMemory:=GetProcAddress(NTDLLHandle,'NtReadVirtualMemory');
|
|
@RtlGetCompressionWorkSpaceSize:=GetProcAddress(NTDLLHandle,'RtlGetCompressionWorkSpaceSize');
|
|
@RtlCompressBuffer:=GetProcAddress(NTDLLHandle,'RtlCompressBuffer');
|
|
@RtlDeCompressBuffer:=GetProcAddress(NTDLLHandle,'RtlDecompressBuffer');
|
|
@RtlDeCompressBufferEx:=GetProcAddress(NTDLLHandle,'RtlDecompressBufferEx');
|
|
@NtSuspendProcess:=GetProcAddress(NTDLLHandle,'NtSuspendProcess');
|
|
@NtResumeProcess:=GetProcAddress(NTDLLHandle,'NtResumeProcess');
|
|
end;
|
|
Result:=(NTDLLHandle<>0) and Assigned(NtQueryObject);
|
|
end;
|
|
|
|
procedure FreeNativeAPI;
|
|
begin
|
|
if (NTDLLHandle<>0) and UnloadNTDLL then begin
|
|
if not FreeLibrary(NTDLLHandle) then
|
|
raise Exception.Create(Format('Unload Error: %s - 0x%x',[NTDLL_DLL,GetModuleHandle(NTDLL_DLL)]))
|
|
else
|
|
NTDLLHandle:=0;
|
|
end;
|
|
end;
|
|
|
|
{function NativeGetCPUCount: Byte;
|
|
var
|
|
sbi: TSystemBasicInformation;
|
|
r: NTSTATUS;
|
|
begin
|
|
r:=NtQuerySystemInformation(SystemBasicInformation,@sbi,SizeOf(sbi),nil);
|
|
if r<>STATUS_SUCCESS then
|
|
Result:=1
|
|
else
|
|
Result:=sbi.NumberOfProcessors;
|
|
end;}
|
|
|
|
function NativeQueryProcessorPerformanceDistribution(out ABuffer: PSystemProcessorPerformanceDistribution): boolean;
|
|
var
|
|
status: Cardinal;
|
|
buffer: Pointer;
|
|
bufferSize, n: Cardinal;
|
|
begin
|
|
ABuffer:=nil;
|
|
bufferSize:=$100;
|
|
buffer:=AllocMem(bufferSize);
|
|
|
|
status:=NtQuerySystemInformation(SystemProcessorPerformanceDistribution,buffer,bufferSize,@bufferSize);
|
|
n:=0;
|
|
while (status=STATUS_INFO_LENGTH_MISMATCH) and (n<8) do begin
|
|
ReallocMem(buffer,bufferSize);
|
|
status:=NtQuerySystemInformation(SystemProcessorPerformanceDistribution,buffer,bufferSize,@bufferSize);
|
|
inc(n);
|
|
end;
|
|
Result:=status=S_OK;
|
|
if Result then
|
|
ABuffer:=PSystemProcessorPerformanceDistribution(buffer)
|
|
else
|
|
FreeMem(buffer);
|
|
end;
|
|
|
|
initialization
|
|
InitNativeAPI;
|
|
finalization
|
|
FreeNativeAPI;
|
|
end.
|
|
|