调用未导出的函数NtCreateUserProcess创建进程

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
#include <ntifs.h>
#include <wdm.h>
#include <ntstrsafe.h>
#include <minwindef.h>

#define Log(X) DbgPrint("qi:"X##)
// 手动声明必要的未公开结构
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PS_CREATE_INFO {
ULONG Size;
ULONG Flags;
} PS_CREATE_INFO, * PPS_CREATE_INFO;

// 定义内存标签
#define TAG_PROCESS_PARAMS 'PrPs'

// 声明函数指针类型
typedef NTSTATUS(NTAPI* PNT_CREATE_USER_PROCESS)(
PHANDLE ProcessHandle,
PHANDLE ThreadHandle,
ACCESS_MASK ProcessDesiredAccess,
ACCESS_MASK ThreadDesiredAccess,
POBJECT_ATTRIBUTES ProcessObjectAttributes,
POBJECT_ATTRIBUTES ThreadObjectAttributes,
ULONG ProcessFlags,
ULONG ThreadFlags,
PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
PPS_CREATE_INFO CreateInfo,
PVOID AttributeList
);

// 创建 cmd.exe 进程
NTSTATUS CreateCmdProcess() {
NTSTATUS status;
HANDLE hProcess = NULL, hThread = NULL;
UNICODE_STRING cmdPath;
PRTL_USER_PROCESS_PARAMETERS params = NULL;
PS_CREATE_INFO createInfo = { 0 };
PNT_CREATE_USER_PROCESS pNtCreateUserProcess = NULL;

// 初始化 cmd.exe 路径
RtlInitUnicodeString(&cmdPath, L"\\??\\C:\\Windows\\System32\\cmd.exe");

// 动态解析 NtCreateUserProcess 地址
UNICODE_STRING funcName;
RtlInitUnicodeString(&funcName, L"NtCreateUserProcess");
pNtCreateUserProcess = (PNT_CREATE_USER_PROCESS)MmGetSystemRoutineAddress(&funcName);
if (!pNtCreateUserProcess) {
return STATUS_ENTRYPOINT_NOT_FOUND;
}

// 分配并初始化进程参数
params = (PRTL_USER_PROCESS_PARAMETERS)ExAllocatePoolWithTag(
NonPagedPool,
sizeof(RTL_USER_PROCESS_PARAMETERS),
TAG_PROCESS_PARAMS
);
if (!params) {
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(params, sizeof(RTL_USER_PROCESS_PARAMETERS));

params->ImagePathName = cmdPath;
params->CommandLine = cmdPath;

createInfo.Size = sizeof(PS_CREATE_INFO);
createInfo.Flags = 0;

// 调用 NtCreateUserProcess
status = pNtCreateUserProcess(
&hProcess,
&hThread,
PROCESS_ALL_ACCESS,
THREAD_ALL_ACCESS,
NULL,
NULL,
0,
0,
params,
&createInfo,
NULL
);

// 清理资源
if (params) {
ExFreePoolWithTag(params, TAG_PROCESS_PARAMS);
}
if (hProcess) {
ZwClose(hProcess);
}
if (hThread) {
ZwClose(hThread);
}

return status;
}

NTSTATUS UnloadDriver(PDRIVER_OBJECT DriverObject)
{
Log("Unloaded Successfully!");
return STATUS_SUCCESS;
}
// 驱动程序入口
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
NTSTATUS status = CreateCmdProcess();
DriverObject->DriverUnload = UnloadDriver;
if (!NT_SUCCESS(status)) {
Log("Failed to create process: 0x%X\n", status);
}
return STATUS_SUCCESS;
}

调用未导出的函数ZwCreateProcessEx,复制system的Token来创建进程

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
#include <ntifs.h>
#include <ntddk.h>
#include <minwindef.h>

#define Log(X) DbgPrint("qi:"X##)

// 手动声明必要的未公开结构
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;

typedef NTSTATUS(NTAPI* PNT_CREATE_USER_PROCESS)(
PHANDLE, PHANDLE, ACCESS_MASK, ACCESS_MASK,
POBJECT_ATTRIBUTES, POBJECT_ATTRIBUTES, ULONG, ULONG,
PRTL_USER_PROCESS_PARAMETERS, PVOID, PVOID
);
HANDLE GetTargetToken() {
HANDLE hToken = NULL;
PEPROCESS targetProcess;

// 示例:获取 System 进程的 Token
PsLookupProcessByProcessId((HANDLE)4, &targetProcess); // PID 4 是 System
ObOpenObjectByPointer(
targetProcess,
OBJ_KERNEL_HANDLE,
NULL,
TOKEN_ALL_ACCESS,
*SeTokenObjectType,
KernelMode,
&hToken
);
ObDereferenceObject(targetProcess);
return hToken;
}
NTSTATUS CreateProcessWithTokenAndParams() {
HANDLE hProcess, hThread, hToken;
UNICODE_STRING cmdPath;
PRTL_USER_PROCESS_PARAMETERS params = NULL;
PNT_CREATE_USER_PROCESS pNtCreateUserProcess;

// 动态获取 NtCreateUserProcess
UNICODE_STRING funcName;
RtlInitUnicodeString(&funcName, L"NtCreateUserProcess");
pNtCreateUserProcess = (PNT_CREATE_USER_PROCESS)MmGetSystemRoutineAddress(&funcName);
if (!pNtCreateUserProcess) return STATUS_NOT_FOUND;

// 初始化进程参数
RtlInitUnicodeString(&cmdPath, L"\\??\\C:\\Windows\\System32\\cmd.exe");
params = (PRTL_USER_PROCESS_PARAMETERS)ExAllocatePoolZero(
NonPagedPool,
sizeof(RTL_USER_PROCESS_PARAMETERS),
'TokP'
);
params->ImagePathName = cmdPath;
params->CommandLine = cmdPath;

// 获取目标 Token(例如 System Token)
hToken = GetTargetToken();

// 创建进程
NTSTATUS status = pNtCreateUserProcess(
&hProcess,
&hThread,
PROCESS_ALL_ACCESS,
THREAD_ALL_ACCESS,
NULL,
NULL,
0,
0,
params,
NULL,
hToken // 通过 AttributeList 传递 Token
);

// 清理资源
if (params) ExFreePool(params);
if (hToken) ZwClose(hToken);
return status;
}



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

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
CreateProcessWithTokenAndParams();
DriverObject->DriverUnload = UnloadDriver;
Log("Loaded Successfully!");
return STATUS_SUCCESS;
}