26 #define KERNEL_HANDLE_BIT (0x80000000)
28 #define KERNEL_HANDLE_BIT (0xffffffff80000000)
31 #define IsKernelHandle(Handle) ((LONG_PTR)(Handle) < 0)
32 #define MakeKernelHandle(Handle) ((HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_BIT))
34 typedef struct _KPHP_ENUMERATE_PROCESS_HANDLES_CONTEXT
57 #pragma alloc_text(PAGE, KphGetObjectType)
58 #pragma alloc_text(PAGE, KphReferenceProcessHandleTable)
59 #pragma alloc_text(PAGE, KphDereferenceProcessHandleTable)
60 #pragma alloc_text(PAGE, KphUnlockHandleTableEntry)
61 #pragma alloc_text(PAGE, KphpEnumerateProcessHandlesEnumCallback61)
62 #pragma alloc_text(PAGE, KphpEnumerateProcessHandlesEnumCallback)
63 #pragma alloc_text(PAGE, KpiEnumerateProcessHandles)
64 #pragma alloc_text(PAGE, KphQueryNameObject)
65 #pragma alloc_text(PAGE, KphQueryNameFileObject)
66 #pragma alloc_text(PAGE, KpiQueryInformationObject)
67 #pragma alloc_text(PAGE, KpiSetInformationObject)
68 #pragma alloc_text(PAGE, KphDuplicateObject)
69 #pragma alloc_text(PAGE, KpiDuplicateObject)
70 #pragma alloc_text(PAGE, KphOpenNamedObject)
124 __in PEPROCESS Process
132 if (KphDynEpObjectTable == -1)
138 handleTable = *(
PHANDLE_TABLE *)((ULONG_PTR)Process + KphDynEpObjectTable);
153 __in PEPROCESS Process
166 PEX_PUSH_LOCK handleContentionEvent;
173 InterlockedExchangeAdd64(&HandleTableEntry->Value, 1);
175 InterlockedExchangeAdd(&HandleTableEntry->Value, 1);
180 handleContentionEvent = (PEX_PUSH_LOCK)((ULONG_PTR)HandleTable + KphDynHtHandleContentionEvent);
182 if (*(PULONG_PTR)handleContentionEvent != 0)
195 POBJECT_TYPE objectType;
201 handleInfo.
Handle = Handle;
202 handleInfo.
Object = objectHeader ? &objectHeader->
Body : NULL;
213 if (objectType && KphDynOtIndex != -1)
216 handleInfo.
ObjectTypeIndex = (USHORT)*(PUCHAR)((ULONG_PTR)objectType + KphDynOtIndex);
218 handleInfo.
ObjectTypeIndex = (USHORT)*(PULONG)((ULONG_PTR)objectType + KphDynOtIndex);
224 entryInBuffer = context->CurrentEntry;
225 context->CurrentEntry = (PVOID)((ULONG_PTR)context->CurrentEntry +
sizeof(
KPH_PROCESS_HANDLE));
232 (ULONG_PTR)entryInBuffer >= (ULONG_PTR)context->Buffer &&
233 (ULONG_PTR)entryInBuffer +
sizeof(
KPH_PROCESS_HANDLE) <= (ULONG_PTR)context->BufferLimit
238 *entryInBuffer = handleInfo;
240 __except (EXCEPTION_EXECUTE_HANDLER)
243 if (context->Status == STATUS_SUCCESS)
244 context->Status = GetExceptionCode();
250 if (context->Status == STATUS_SUCCESS)
251 context->Status = STATUS_BUFFER_TOO_SMALL;
286 __in HANDLE ProcessHandle,
287 __out_bcount(BufferLength) PVOID Buffer,
288 __in_opt ULONG BufferLength,
289 __out_opt PULONG ReturnLength,
290 __in KPROCESSOR_MODE AccessMode
304 return STATUS_NOT_SUPPORTED;
307 if (AccessMode != KernelMode)
311 ProbeForWrite(Buffer, BufferLength,
sizeof(ULONG));
314 ProbeForWrite(ReturnLength,
sizeof(ULONG),
sizeof(ULONG));
316 __except (EXCEPTION_EXECUTE_HANDLER)
318 return GetExceptionCode();
323 status = ObReferenceObjectByHandle(
340 ObDereferenceObject(process);
341 return STATUS_UNSUCCESSFUL;
345 context.Buffer = Buffer;
346 context.BufferLimit = (PVOID)((ULONG_PTR)Buffer + BufferLength);
349 context.Status = STATUS_SUCCESS;
373 ObDereferenceObject(process);
378 if (AccessMode != KernelMode)
384 __except (EXCEPTION_EXECUTE_HANDLER)
386 return GetExceptionCode();
402 returnLength = (ULONG)((ULONG_PTR)context.CurrentEntry - (ULONG_PTR)Buffer);
404 if (AccessMode != KernelMode)
408 *ReturnLength = returnLength;
410 __except (EXCEPTION_EXECUTE_HANDLER)
412 return GetExceptionCode();
417 *ReturnLength = returnLength;
421 return context.Status;
435 __out_bcount(BufferLength) POBJECT_NAME_INFORMATION Buffer,
436 __in ULONG BufferLength,
437 __out PULONG ReturnLength
441 POBJECT_TYPE objectType;
449 if (objectType == *IoFileObjectType &&
450 (((PFILE_OBJECT)Object)->Busy || ((PFILE_OBJECT)Object)->Waiters))
453 dprintf(
"KphQueryNameFileObject: status 0x%x\n", status);
457 status = ObQueryNameString(Object, Buffer, BufferLength, ReturnLength);
458 dprintf(
"ObQueryNameString: status 0x%x\n", status);
462 if (status == STATUS_BUFFER_OVERFLOW)
463 status = STATUS_BUFFER_TOO_SMALL;
464 if (status == STATUS_INFO_LENGTH_MISMATCH)
465 status = STATUS_BUFFER_TOO_SMALL;
468 dprintf(
"KphQueryNameObject: %.*S\n", Buffer->Name.Length /
sizeof(WCHAR), Buffer->Name.Buffer);
470 dprintf(
"KphQueryNameObject: status 0x%x\n", status);
485 __in PFILE_OBJECT FileObject,
486 __out_bcount(BufferLength) POBJECT_NAME_INFORMATION Buffer,
487 __in ULONG BufferLength,
488 __out PULONG ReturnLength
491 NTSTATUS status = STATUS_SUCCESS;
496 PFILE_OBJECT relatedFileObject;
502 if (BufferLength <
sizeof(OBJECT_NAME_INFORMATION))
504 *ReturnLength =
sizeof(OBJECT_NAME_INFORMATION);
506 return STATUS_BUFFER_TOO_SMALL;
510 Buffer->Name.Length = 0;
513 Buffer->Name.Buffer = (PWSTR)((ULONG_PTR)Buffer +
sizeof(OBJECT_NAME_INFORMATION));
516 objectName = (PCHAR)Buffer->Name.Buffer;
519 usedLength =
sizeof(OBJECT_NAME_INFORMATION);
526 if (FileObject->DeviceObject)
528 status = ObQueryNameString(
529 FileObject->DeviceObject,
537 if (status == STATUS_INFO_LENGTH_MISMATCH)
538 status = STATUS_BUFFER_TOO_SMALL;
540 *ReturnLength = returnLength;
550 objectName += Buffer->Name.Length;
551 usedLength += Buffer->Name.Length;
557 if (!FileObject->FileName.Buffer)
559 *ReturnLength = usedLength;
561 return STATUS_SUCCESS;
569 relatedFileObject = FileObject;
574 subNameLength += relatedFileObject->FileName.Length;
577 if (relatedFileObject == relatedFileObject->RelatedFileObject)
580 relatedFileObject = relatedFileObject->RelatedFileObject;
582 while (relatedFileObject);
584 usedLength += subNameLength;
587 if (usedLength > BufferLength)
589 *ReturnLength = usedLength;
591 return STATUS_BUFFER_TOO_SMALL;
597 objectName += subNameLength;
599 relatedFileObject = FileObject;
603 objectName -= relatedFileObject->FileName.Length;
604 memcpy(objectName, relatedFileObject->FileName.Buffer, relatedFileObject->FileName.Length);
607 if (relatedFileObject == relatedFileObject->RelatedFileObject)
610 relatedFileObject = relatedFileObject->RelatedFileObject;
612 while (relatedFileObject);
615 Buffer->Name.Length += (USHORT)subNameLength;
618 *ReturnLength = usedLength;
620 return STATUS_SUCCESS;
638 __in HANDLE ProcessHandle,
641 __out_bcount(ObjectInformationLength) PVOID ObjectInformation,
642 __in ULONG ObjectInformationLength,
643 __out_opt PULONG ReturnLength,
644 __in KPROCESSOR_MODE AccessMode
649 KPROCESSOR_MODE referenceMode;
655 if (AccessMode != KernelMode)
659 ProbeForWrite(ObjectInformation, ObjectInformationLength,
sizeof(ULONG));
662 ProbeForWrite(ReturnLength,
sizeof(ULONG),
sizeof(ULONG));
664 __except (EXCEPTION_EXECUTE_HANDLER)
666 return GetExceptionCode();
670 status = ObReferenceObjectByHandle(
682 if (process == PsInitialSystemProcess)
687 referenceMode = KernelMode;
696 ObDereferenceObject(process);
697 return STATUS_INVALID_HANDLE;
700 referenceMode = AccessMode;
703 switch (ObjectInformationClass)
709 KeStackAttachProcess(process, &apcState);
712 ObjectBasicInformation,
717 KeUnstackDetachProcess(&apcState);
727 __except (EXCEPTION_EXECUTE_HANDLER)
729 status = GetExceptionCode();
734 status = STATUS_INFO_LENGTH_MISMATCH;
745 POBJECT_NAME_INFORMATION nameInfo;
747 returnLength =
sizeof(OBJECT_NAME_INFORMATION);
750 KeStackAttachProcess(process, &apcState);
751 status = ObReferenceObjectByHandle(
759 KeUnstackDetachProcess(&apcState);
763 allocateSize = ObjectInformationLength;
765 if (allocateSize <
sizeof(OBJECT_NAME_INFORMATION))
766 allocateSize =
sizeof(OBJECT_NAME_INFORMATION);
768 nameInfo = ExAllocatePoolWithQuotaTag(PagedPool, allocateSize,
'QhpK');
773 memset(nameInfo, 0, ObjectInformationLength);
778 ObjectInformationLength,
781 dprintf(
"KpiQueryInformationObject: called KphQueryNameObject: Handle: 0x%Ix, ObjectInformationLength: %u, returnLength: %u\n",
782 Handle, ObjectInformationLength, returnLength);
787 if (nameInfo->Name.Buffer)
788 nameInfo->Name.Buffer = (PVOID)((ULONG_PTR)nameInfo->Name.Buffer - (ULONG_PTR)nameInfo + (ULONG_PTR)ObjectInformation);
792 memcpy(ObjectInformation, nameInfo, ObjectInformationLength);
794 __except (EXCEPTION_EXECUTE_HANDLER)
796 status = GetExceptionCode();
800 ExFreePoolWithTag(nameInfo,
'QhpK');
804 status = STATUS_INSUFFICIENT_RESOURCES;
807 ObDereferenceObject(
object);
817 allocateSize = ObjectInformationLength;
826 allocateSize +=
sizeof(ULONGLONG);
828 typeInfo = ExAllocatePoolWithQuotaTag(PagedPool, allocateSize,
'QhpK');
832 memset(typeInfo, 0, ObjectInformationLength);
834 KeStackAttachProcess(process, &apcState);
837 ObjectTypeInformation,
839 ObjectInformationLength,
842 KeUnstackDetachProcess(&apcState);
848 typeInfo->
TypeName.Buffer = (PVOID)((ULONG_PTR)typeInfo->
TypeName.Buffer - (ULONG_PTR)typeInfo + (ULONG_PTR)ObjectInformation);
852 memcpy(ObjectInformation, typeInfo, ObjectInformationLength);
854 __except (EXCEPTION_EXECUTE_HANDLER)
856 status = GetExceptionCode();
860 ExFreePoolWithTag(typeInfo,
'QhpK');
864 status = STATUS_INSUFFICIENT_RESOURCES;
872 KeStackAttachProcess(process, &apcState);
880 KeUnstackDetachProcess(&apcState);
890 __except (EXCEPTION_EXECUTE_HANDLER)
892 status = GetExceptionCode();
897 status = STATUS_INFO_LENGTH_MISMATCH;
906 PROCESS_BASIC_INFORMATION basicInfo;
908 KeStackAttachProcess(process, &apcState);
911 ProcessBasicInformation,
913 sizeof(PROCESS_BASIC_INFORMATION),
916 KeUnstackDetachProcess(&apcState);
920 if (ObjectInformationLength ==
sizeof(PROCESS_BASIC_INFORMATION))
924 *(PPROCESS_BASIC_INFORMATION)ObjectInformation = basicInfo;
926 __except (EXCEPTION_EXECUTE_HANDLER)
928 status = GetExceptionCode();
933 status = STATUS_INFO_LENGTH_MISMATCH;
937 returnLength =
sizeof(PROCESS_BASIC_INFORMATION);
944 KeStackAttachProcess(process, &apcState);
947 ThreadBasicInformation,
952 KeUnstackDetachProcess(&apcState);
962 __except (EXCEPTION_EXECUTE_HANDLER)
964 status = GetExceptionCode();
969 status = STATUS_INFO_LENGTH_MISMATCH;
987 KphDynEgeGuid != -1 &&
988 KphDynEreGuidEntry != -1 &&
996 KeStackAttachProcess(process, &apcState);
997 status = ObReferenceObjectByHandle(
1005 KeUnstackDetachProcess(&apcState);
1015 objectTypeName = (
PUNICODE_STRING)((ULONG_PTR)objectType + KphDynOtName);
1020 status = STATUS_OBJECT_TYPE_MISMATCH;
1025 status = STATUS_NOT_SUPPORTED;
1030 guidEntry = *(PVOID *)((ULONG_PTR)etwReg + KphDynEreGuidEntry);
1033 basicInfo.
Guid = *(GUID *)((ULONG_PTR)guidEntry + KphDynEgeGuid);
1035 memset(&basicInfo.
Guid, 0,
sizeof(GUID));
1045 __except (EXCEPTION_EXECUTE_HANDLER)
1047 status = GetExceptionCode();
1052 status = STATUS_INFO_LENGTH_MISMATCH;
1056 ObDereferenceObject(etwReg);
1061 status = STATUS_NOT_SUPPORTED;
1069 PFILE_OBJECT fileObject;
1072 KeStackAttachProcess(process, &apcState);
1073 status = ObReferenceObjectByHandle(
1081 KeUnstackDetachProcess(&apcState);
1087 objectInfo.
ReadAccess = fileObject->ReadAccess;
1090 objectInfo.
SharedRead = fileObject->SharedRead;
1094 objectInfo.
Flags = fileObject->Flags;
1102 __except (EXCEPTION_EXECUTE_HANDLER)
1104 status = GetExceptionCode();
1109 status = STATUS_INFO_LENGTH_MISMATCH;
1112 ObDereferenceObject(fileObject);
1120 PFILE_OBJECT fileObject;
1121 HANDLE driverHandle;
1125 KeStackAttachProcess(process, &apcState);
1126 status = ObReferenceObjectByHandle(
1134 KeUnstackDetachProcess(&apcState);
1138 if (fileObject->DeviceObject && fileObject->DeviceObject->DriverObject)
1140 status = ObOpenObjectByPointer(
1141 fileObject->DeviceObject->DriverObject,
1152 driverHandle = NULL;
1161 __except (EXCEPTION_EXECUTE_HANDLER)
1163 status = GetExceptionCode();
1167 ObDereferenceObject(fileObject);
1172 status = STATUS_INFO_LENGTH_MISMATCH;
1177 status = STATUS_INVALID_INFO_CLASS;
1182 ObDereferenceObject(process);
1186 if (AccessMode != KernelMode)
1190 *ReturnLength = returnLength;
1192 __except (EXCEPTION_EXECUTE_HANDLER)
1199 *ReturnLength = returnLength;
1219 __in HANDLE ProcessHandle,
1222 __in_bcount(ObjectInformationLength) PVOID ObjectInformation,
1223 __in ULONG ObjectInformationLength,
1224 __in KPROCESSOR_MODE AccessMode
1229 KAPC_STATE apcState;
1233 if (AccessMode != KernelMode)
1237 switch (ObjectInformationClass)
1240 alignment =
sizeof(BOOLEAN);
1243 alignment =
sizeof(ULONG);
1249 ProbeForRead(ObjectInformation, ObjectInformationLength, alignment);
1251 __except (EXCEPTION_EXECUTE_HANDLER)
1253 return GetExceptionCode();
1257 status = ObReferenceObjectByHandle(
1269 if (process == PsInitialSystemProcess)
1277 ObDereferenceObject(process);
1278 return STATUS_INVALID_HANDLE;
1282 switch (ObjectInformationClass)
1294 __except (EXCEPTION_EXECUTE_HANDLER)
1296 status = GetExceptionCode();
1301 status = STATUS_INFO_LENGTH_MISMATCH;
1306 KeStackAttachProcess(process, &apcState);
1308 KeUnstackDetachProcess(&apcState);
1313 status = STATUS_INVALID_INFO_CLASS;
1317 ObDereferenceObject(process);
1344 __in PEPROCESS SourceProcess,
1345 __in_opt PEPROCESS TargetProcess,
1346 __in HANDLE SourceHandle,
1347 __out_opt PHANDLE TargetHandle,
1348 __in ACCESS_MASK DesiredAccess,
1349 __in ULONG HandleAttributes,
1351 __in KPROCESSOR_MODE AccessMode
1354 NTSTATUS status = STATUS_SUCCESS;
1355 KPROCESSOR_MODE referenceMode;
1356 BOOLEAN sourceAttached =
FALSE;
1357 BOOLEAN targetAttached =
FALSE;
1358 KAPC_STATE apcState;
1360 HANDLE objectHandle;
1366 if (!TargetProcess || !TargetHandle)
1368 if (!(Options & DUPLICATE_CLOSE_SOURCE))
1369 return STATUS_INVALID_PARAMETER_MIX;
1374 return STATUS_INVALID_PARAMETER_6;
1378 if (SourceProcess == PsInitialSystemProcess)
1381 referenceMode = KernelMode;
1385 referenceMode = AccessMode;
1396 if (SourceProcess == PsGetCurrentProcess())
1398 if (Options & DUPLICATE_CLOSE_SOURCE)
1399 return STATUS_CANT_TERMINATE_SELF;
1403 if (SourceProcess != PsGetCurrentProcess())
1405 KeStackAttachProcess(SourceProcess, &apcState);
1406 sourceAttached =
TRUE;
1410 if (Options & DUPLICATE_CLOSE_SOURCE)
1415 KeUnstackDetachProcess(&apcState);
1421 status = ObReferenceObjectByHandle(
1430 KeUnstackDetachProcess(&apcState);
1436 if (TargetProcess != PsGetCurrentProcess())
1438 KeStackAttachProcess(TargetProcess, &apcState);
1439 targetAttached =
TRUE;
1444 status = ObOpenObjectByPointer(
1453 ObDereferenceObject(
object);
1456 KeUnstackDetachProcess(&apcState);
1459 *TargetHandle = objectHandle;
1461 *TargetHandle = NULL;
1488 __in HANDLE SourceProcessHandle,
1489 __in HANDLE SourceHandle,
1490 __in_opt HANDLE TargetProcessHandle,
1491 __out_opt PHANDLE TargetHandle,
1492 __in ACCESS_MASK DesiredAccess,
1493 __in ULONG HandleAttributes,
1495 __in KPROCESSOR_MODE AccessMode
1498 NTSTATUS status = STATUS_SUCCESS;
1499 PEPROCESS sourceProcess = NULL;
1500 PEPROCESS targetProcess = NULL;
1501 HANDLE targetHandle;
1505 if (AccessMode != KernelMode)
1510 ProbeForWrite(TargetHandle,
sizeof(HANDLE), 1);
1512 __except (EXCEPTION_EXECUTE_HANDLER)
1514 return GetExceptionCode();
1518 status = ObReferenceObjectByHandle(
1519 SourceProcessHandle,
1531 if (TargetProcessHandle)
1533 status = ObReferenceObjectByHandle(
1534 TargetProcessHandle,
1544 ObDereferenceObject(sourceProcess);
1562 if (AccessMode != KernelMode)
1566 *TargetHandle = targetHandle;
1568 __except (EXCEPTION_EXECUTE_HANDLER)
1570 status = STATUS_ACCESS_VIOLATION;
1575 *TargetHandle = targetHandle;
1580 ObDereferenceObject(targetProcess);
1582 ObDereferenceObject(sourceProcess);
1588 __out PHANDLE ObjectHandle,
1589 __in ACCESS_MASK DesiredAccess,
1591 __in POBJECT_TYPE ObjectType,
1592 __in KPROCESSOR_MODE AccessMode
1595 NTSTATUS status = STATUS_SUCCESS;
1596 HANDLE objectHandle;
1602 if (AccessMode != KernelMode)
1606 ProbeForWrite(ObjectHandle,
sizeof(HANDLE),
sizeof(HANDLE));
1610 __except (EXCEPTION_EXECUTE_HANDLER)
1612 return GetExceptionCode();
1622 return STATUS_INVALID_PARAMETER;
1626 return STATUS_INVALID_PARAMETER;
1631 return STATUS_INVALID_PARAMETER;
1640 objectAttributes.
ObjectName = &capturedObjectName;
1662 if (AccessMode != KernelMode)
1666 *ObjectHandle = objectHandle;
1668 __except (EXCEPTION_EXECUTE_HANDLER)
1670 status = GetExceptionCode();
1675 *ObjectHandle = objectHandle;