- Notifications
You must be signed in to change notification settings - Fork 8.5k
/
Copy pathntprivapi.cpp
136 lines (109 loc) · 4.32 KB
/
ntprivapi.cpp
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include"precomp.h"
#include"NtPrivApi.hpp"
namespace
{
structPROCESS_BASIC_INFORMATION_EXPANDED
{
NTSTATUS ExitStatus;
PVOID PebBaseAddress;
ULONG_PTR AffinityMask;
LONG BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
};
}
[[nodiscard]] NTSTATUS NtPrivApi::s_GetProcessParentId(_Inout_ PULONG ProcessId)
{
// TODO: Get Parent current not really available without winternl + NtQueryInformationProcess. http://osgvsowi/8394495
OBJECT_ATTRIBUTES oa;
#pragma warning(suppress : 26477) // This macro contains a bare NULL
InitializeObjectAttributes(&oa, nullptr, 0, nullptr, nullptr);
CLIENT_ID ClientId;
ClientId.UniqueProcess = UlongToHandle(*ProcessId);
ClientId.UniqueThread = nullptr;
HANDLE ProcessHandle;
auto Status = s_NtOpenProcess(&ProcessHandle, PROCESS_QUERY_LIMITED_INFORMATION, &oa, &ClientId);
PROCESS_BASIC_INFORMATION_EXPANDED BasicInfo = { 0 };
if (SUCCEEDED_NTSTATUS(Status))
{
Status = s_NtQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &BasicInfo, sizeof(BasicInfo), nullptr);
LOG_IF_FAILED(s_NtClose(ProcessHandle));
}
if (FAILED_NTSTATUS(Status))
{
*ProcessId = 0;
return Status;
}
*ProcessId = (ULONG)BasicInfo.InheritedFromUniqueProcessId;
return STATUS_SUCCESS;
}
[[nodiscard]] NTSTATUS NtPrivApi::s_NtOpenProcess(_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ CLIENT_ID* ClientId)
{
auto hNtDll = _Instance()._hNtDll;
if (hNtDll != nullptr)
{
typedefNTSTATUS (*PfnNtOpenProcess)(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, CLIENT_ID * ClientId);
staticauto pfn = (PfnNtOpenProcess)GetProcAddress(hNtDll, "NtOpenProcess");
if (pfn != nullptr)
{
returnpfn(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}
}
return STATUS_UNSUCCESSFUL;
}
[[nodiscard]] NTSTATUS NtPrivApi::s_NtQueryInformationProcess(_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_ PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength)
{
auto hNtDll = _Instance()._hNtDll;
if (hNtDll != nullptr)
{
typedefNTSTATUS (*PfnNtQueryInformationProcess)(HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
staticauto pfn = (PfnNtQueryInformationProcess)GetProcAddress(hNtDll, "NtQueryInformationProcess");
if (pfn != nullptr)
{
returnpfn(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength);
}
}
return STATUS_UNSUCCESSFUL;
}
[[nodiscard]] NTSTATUS NtPrivApi::s_NtClose(_In_ HANDLE Handle)
{
auto hNtDll = _Instance()._hNtDll;
if (hNtDll != nullptr)
{
typedefNTSTATUS (*PfnNtClose)(HANDLE Handle);
staticauto pfn = (PfnNtClose)GetProcAddress(hNtDll, "NtClose");
if (pfn != nullptr)
{
returnpfn(Handle);
}
}
return STATUS_UNSUCCESSFUL;
}
NtPrivApi::NtPrivApi()
{
// NOTE: Use LoadLibraryExW with LOAD_LIBRARY_SEARCH_SYSTEM32 flag below to avoid unneeded directory traversal.
// This has triggered CPG boot IO warnings in the past.
_hNtDll = LoadLibraryExW(L"ntdll.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
}
NtPrivApi::~NtPrivApi()
{
if (_hNtDll != nullptr)
{
FreeLibrary(_hNtDll);
_hNtDll = nullptr;
}
}
NtPrivApi& NtPrivApi::_Instance()
{
static NtPrivApi ntapi;
return ntapi;
}