使用系统api ZwOpenProcess打开句柄
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| 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; }
|
使用自定义函数打开进程句柄
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| NTSTATUS KernelOpenProcessHandle( HANDLE pid, PHANDLE pHandle ) { PEPROCESS process; NTSTATUS status = PsLookupProcessByProcessId(pid, &process); if (!NT_SUCCESS(status)) return status;
status = ObOpenObjectByPointer( process, OBJ_KERNEL_HANDLE, NULL, PROCESS_ALL_ACCESS, *PsProcessType, KernelMode, pHandle );
ObDereferenceObject(process); return status; }
|
使用系统api ZwOpenProcess打开句柄后将句柄传递给应用层
✅ 示例流程:
用户层:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| typedef struct { ULONG pid; } OPEN_PROC_INPUT;
typedef struct { HANDLE hProcess; } OPEN_PROC_OUTPUT;
OPEN_PROC_INPUT input = { .pid = 1234 }; OPEN_PROC_OUTPUT output = { 0 };
DeviceIoControl( hDevice, IOCTL_OPEN_TARGET_PROCESS, &input, sizeof(input), &output, sizeof(output), &bytesReturned, NULL );
|
⚠️ 如果你要将内核打开的句柄传回用户层使用,还要注意:这个句柄必须是 用户可访问的句柄,不能加 OBJ_KERNEL_HANDLE 标志。
内核驱动中:
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
| case IOCTL_OPEN_TARGET_PROCESS: { POPEN_PROC_INPUT in = Irp->AssociatedIrp.SystemBuffer; POPEN_PROC_OUTPUT out = Irp->AssociatedIrp.SystemBuffer;
HANDLE userHandle = NULL; OBJECT_ATTRIBUTES objAttr; CLIENT_ID clientId = { 0 }; clientId.UniqueProcess = (HANDLE)in->pid; clientId.UniqueThread = 0;
InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL);
NTSTATUS status = ZwOpenProcess( &userHandle, PROCESS_ALL_ACCESS, &objAttr, &clientId );
out->hProcess = userHandle; Irp->IoStatus.Information = sizeof(OPEN_PROC_OUTPUT); Irp->IoStatus.Status = status; break; }
|
🧠 小总结:
| 做法 |
是否可行 |
说明 |
用户层直接调用 KernelOpenProcessHandle |
❌ |
自定义函数,非系统导出 |
| 用户层通过 IOCTL 调用驱动函数 |
✅ |
推荐做法 |
用户层用系统 API(如 OpenProcess) |
✅ |
系统支持 |
| 内核打开句柄返回用户层使用 |
⚠️ 可以,但注意句柄权限和安全性 |
|