内核中进程与句柄互转

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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include <ntifs.h>

#define Log(X) DbgPrint("qi:"X##)
//驱动开发:内核中进程与句柄互转原创
// //https://cloud.tencent.com/developer/article/2297501
// 定义函数指针

typedef NTSTATUS(*PfnZwQueryInformationProcess)(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);

PfnZwQueryInformationProcess ZwQueryInformationProcess;
NTKERNELAPI CHAR* PsGetProcessImageFileName(PEPROCESS Process);

// 传入PID传出HANDLE句柄
HANDLE PidToHandle(ULONG PID);
// HANDLE句柄转换为PID
ULONG HandleToPid(HANDLE handle);
// 将Pid转换为Object or EProcess
PEPROCESS PidToObject(ULONG Pid);
// 将Handle转换为EProcess结构
PEPROCESS HandleToEprocess(HANDLE handle);
// EProcess转换为Handle句柄
HANDLE EprocessToHandle(PEPROCESS eprocess);
//进程名转为EPROCESS
ULONG GetProcessIdByName(char* name);
PEPROCESS GetProcessObjectByName(char* name);

NTSTATUS UnloadDriver(PDRIVER_OBJECT DriverObject)
{
Log("Unloaded Successfully!");
return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = UnloadDriver;
Log("Loaded Successfully!");
return STATUS_SUCCESS;
}
HANDLE PidToHandle(ULONG PID)
{
if (!PID)return NULL;
HANDLE hProcessHandle;
OBJECT_ATTRIBUTES obj;
CLIENT_ID clientid;

clientid.UniqueProcess = PID;
clientid.UniqueThread = 0;

// 属性初始化
InitializeObjectAttributes(&obj, 0, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0);

NTSTATUS status = ZwOpenProcess(&hProcessHandle, PROCESS_ALL_ACCESS, &obj, &clientid);
if (status == STATUS_SUCCESS)
{
// DbgPrint("[*] 已打开 \n");
ZwClose(&hProcessHandle);
return hProcessHandle;
}

return 0;
}

ULONG HandleToPid(HANDLE handle)
{
if (!handle)return 0;
PROCESS_BASIC_INFORMATION ProcessBasicInfor;

// 初始化字符串,并获取动态地址
UNICODE_STRING UtrZwQueryInformationProcessName = RTL_CONSTANT_STRING(L"ZwQueryInformationProcess");
ZwQueryInformationProcess = (PfnZwQueryInformationProcess)MmGetSystemRoutineAddress(&UtrZwQueryInformationProcessName);

// 调用查询
ZwQueryInformationProcess(
handle,
ProcessBasicInformation,
(PVOID)&ProcessBasicInfor,
sizeof(ProcessBasicInfor),
NULL);

// 返回进程PID
return ProcessBasicInfor.UniqueProcessId;
}

//#include <windef.h>
PEPROCESS PidToObject(ULONG Pid)
{
if (!Pid)return NULL;
PEPROCESS pEprocess;

NTSTATUS status = PsLookupProcessByProcessId((HANDLE)Pid, &pEprocess);

if (status == STATUS_SUCCESS)
{
ObDereferenceObject(pEprocess);
return pEprocess;
}

return NULL;
}

PEPROCESS HandleToEprocess(HANDLE handle)
{
if (!handle)return NULL;
PEPROCESS pEprocess;

NTSTATUS status = ObReferenceObjectByHandle(handle, GENERIC_ALL, *PsProcessType, KernelMode, &pEprocess, NULL);
if (status == STATUS_SUCCESS)
{
return pEprocess;
}

return 0;
}

HANDLE EprocessToHandle(PEPROCESS eprocess)
{
if (!eprocess)return NULL;
HANDLE hProcessHandle = (HANDLE)-1;

NTSTATUS status = ObOpenObjectByPointer(
eprocess,
OBJ_KERNEL_HANDLE,
0,
0,
*PsProcessType,
KernelMode,
&hProcessHandle
);

if (status == STATUS_SUCCESS)
{
return hProcessHandle;
}

return NULL;
}

PEPROCESS GetProcessObjectByName(char* name)
{
if (!name)return NULL;
SIZE_T temp;
for (temp = 100; temp < 10000; temp += 4)
{
NTSTATUS status;
PEPROCESS ep;
status = PsLookupProcessByProcessId((HANDLE)temp, &ep);
if (NT_SUCCESS(status))
{
char* pn = PsGetProcessImageFileName(ep);
if (_stricmp(pn, name) == 0)
return ep;
}
}
return NULL;
}
ULONG GetProcessIdByName(char* name)
{
if (!name)return 0;
////传入进程名字通过遍历进程得到PEPROCESS
PEPROCESS eprocess = GetProcessObjectByName(name);
if (!eprocess)
return 0;
// EProcess转换为Handle句柄
HANDLE handle = EprocessToHandle(eprocess);
if (handle == 0)return 0;
// HANDLE句柄转换为PID
ULONG pid = HandleToPid(handle);
return pid;
}