-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathNtUtils.System.pas
More file actions
103 lines (82 loc) · 2.56 KB
/
NtUtils.System.pas
File metadata and controls
103 lines (82 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
unit NtUtils.System;
{
The module provides support for querying information about the system.
}
interface
uses
Ntapi.ntexapi, NtUtils, NtUtils.Ldr;
// Query variable-size system information
function NtxQuerySystem(
InfoClass: TSystemInformationClass;
out xMemory: IMemory;
InitialBuffer: Cardinal = 0;
[opt] GrowthMethod: TBufferGrowthMethod = nil
): TNtxStatus;
type
NtxSystem = class abstract
// Query fixed-size information
class function Query<T>(
InfoClass: TSystemInformationClass;
var Buffer: T
): TNtxStatus; static;
end;
// Enumerate kernel modules and drivers
function NtxEnumerateModulesSystem(
out Modules: TArray<TLdrxModuleInfo>
): TNtxStatus;
implementation
uses
Ntapi.ntrtl, NtUtils.Files, DelphiUtils.AutoObjects;
{$BOOLEVAL OFF}
{$IFOPT R+}{$DEFINE R+}{$ENDIF}
{$IFOPT Q+}{$DEFINE Q+}{$ENDIF}
function NtxQuerySystem;
var
Required: Cardinal;
begin
Result.Location := 'NtQuerySystemInformation';
Result.LastCall.UsesInfoClass(InfoClass, icQuery);
xMemory := Auto.AllocateDynamic(InitialBuffer);
repeat
Required := 0;
Result.Status := NtQuerySystemInformation(InfoClass, xMemory.Data,
xMemory.Size, @Required);
until not NtxExpandBufferEx(Result, xMemory, Required, GrowthMethod);
end;
{ NtxSystem }
class function NtxSystem.Query<T>;
begin
Result.Location := 'NtQuerySystemInformation';
Result.LastCall.UsesInfoClass(InfoClass, icQuery);
Result.Status := NtQuerySystemInformation(InfoClass, @Buffer, SizeOf(Buffer),
nil);
end;
function NtxEnumerateModulesSystem;
var
xMemory: IMemory<PRtlProcessModules>;
Module: PRtlProcessModuleInformation;
i: Integer;
begin
Result := NtxQuerySystem(SystemModuleInformation, IMemory(xMemory),
SizeOf(TRtlProcessModules));
if not Result.IsSuccess then
Exit;
SetLength(Modules, xMemory.Data.NumberOfModules);
for i := 0 to High(Modules) do
with Modules[i] do
begin
Module := @xMemory.Data.Modules{$R-}[i]{$IFDEF R+}{$R+}{$ENDIF};
DllBase := Module.ImageBase;
SizeOfImage := Module.ImageSize;
LoadCount := Module.LoadCount;
FullDllName := String(UTF8String(PAnsiChar(@Module.FullPathName)));
BaseDllName := String(UTF8String(PAnsiChar(@Module.FullPathName[
Module.OffsetToFileName])));
// Include the default drivers directory for names without a path
if Module.OffsetToFileName = 0 then
Insert('\SystemRoot\System32\drivers\', FullDllName, Low(String));
// Convert paths to the Win32 format
FullDllName := RtlxNativePathToDosPath(FullDllName);
end;
end;
end.