26 #define PH_QUERY_HACK_MAX_THREADS 20
28 typedef struct _PHP_CALL_WITH_TIMEOUT_THREAD_CONTEXT
30 SLIST_ENTRY ListEntry;
35 HANDLE StartEventHandle;
36 HANDLE CompletedEventHandle;
48 typedef struct _PHP_QUERY_OBJECT_COMMON_CONTEXT
58 OBJECT_INFORMATION_CLASS ObjectInformationClass;
59 PVOID ObjectInformation;
60 ULONG ObjectInformationLength;
66 SECURITY_INFORMATION SecurityInformation;
67 PSECURITY_DESCRIPTOR SecurityDescriptor;
70 } NtQuerySecurityObject;
74 SECURITY_INFORMATION SecurityInformation;
75 PSECURITY_DESCRIPTOR SecurityDescriptor;
76 } NtSetSecurityObject;
79 HANDLE SourceProcessHandle;
81 HANDLE TargetProcessHandle;
83 ACCESS_MASK DesiredAccess;
84 ULONG HandleAttributes;
91 _In_opt_ PLARGE_INTEGER Timeout
101 _In_opt_ PVOID Context,
102 _In_ PLARGE_INTEGER Timeout
112 static SLIST_HEADER PhpCallWithTimeoutThreadListHead;
120 (PVOID *)&PhHandleGetClientIdName,
126 _In_ HANDLE ProcessHandle,
148 BasicInformation->PointerCount -= 1;
153 status = NtQueryObject(
155 ObjectBasicInformation,
167 BasicInformation->HandleCount -= 1;
168 BasicInformation->PointerCount -= 2;
176 _In_ HANDLE ProcessHandle,
178 _In_ ULONG ObjectTypeNumber,
182 NTSTATUS status = STATUS_SUCCESS;
189 typeName = PhObjectTypeNames[ObjectTypeNumber];
198 ULONG returnLength = 0;
215 status = NtQueryObject(
217 ObjectTypeInformation,
224 if (returnLength == 0)
227 buffer = PhAllocate(returnLength);
242 status = NtQueryObject(
244 ObjectTypeInformation,
264 &PhObjectTypeNames[ObjectTypeNumber],
281 *TypeName = typeName;
287 _In_ HANDLE ProcessHandle,
289 _In_ BOOLEAN WithTimeout,
294 POBJECT_NAME_INFORMATION buffer;
299 buffer = PhAllocate(bufferSize);
329 status = NtQueryObject(
339 if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_INFO_LENGTH_MISMATCH ||
340 status == STATUS_BUFFER_TOO_SMALL)
343 buffer = PhAllocate(bufferSize);
349 }
while (--attempts);
384 PTOKEN_USER tokenUser;
454 _In_ HANDLE SectionHandle,
492 static PVOID processes = NULL;
493 static ULONG lastProcessesTickCount = 0;
502 tickCount = GetTickCount();
504 if (tickCount - lastProcessesTickCount >= 2000)
509 if (tickCount - lastProcessesTickCount >= 2000)
523 lastProcessesTickCount = tickCount;
541 if (ClientId->UniqueThread)
549 (ULONG)ClientId->UniqueProcess,
550 (ULONG)ClientId->UniqueThread
556 (ULONG)ClientId->UniqueProcess, (ULONG)ClientId->UniqueThread);
567 (ULONG)ClientId->UniqueProcess
572 name =
PhFormatString(L
"Non-existent process (%u)", (ULONG)ClientId->UniqueProcess);
582 _In_ HANDLE ProcessHandle,
633 if (publisherName && publisherName->
Length == 0)
636 publisherName = NULL;
646 bestObjectName = publisherName;
651 bestObjectName = guidString;
698 PJOBOBJECT_BASIC_PROCESS_ID_LIST processIdList;
700 status = NtDuplicateObject(
723 for (i = 0; i < processIdList->NumberOfProcessIdsInList; i++)
725 clientId.
UniqueProcess = (HANDLE)processIdList->ProcessIdList[i];
726 name = handleGetClientIdName(&clientId);
761 PROCESS_BASIC_INFORMATION basicInfo;
768 sizeof(PROCESS_BASIC_INFORMATION),
780 PROCESS_BASIC_INFORMATION basicInfo;
782 status = NtDuplicateObject(
804 if (handleGetClientIdName)
805 bestObjectName = handleGetClientIdName(&clientId);
815 status = NtDuplicateObject(
820 SECTION_QUERY | SECTION_MAP_READ,
842 PWSTR sectionType = L
"Unknown";
845 sectionType = L
"Commit";
847 sectionType = L
"File";
849 sectionType = L
"Image";
851 sectionType = L
"Reserve";
857 bestObjectName =
PhFormat(format, 4, 20);
890 status = NtDuplicateObject(
912 if (handleGetClientIdName)
913 bestObjectName = handleGetClientIdName(&clientId);
918 ENLISTMENT_BASIC_INFORMATION basicInfo;
920 status = NtDuplicateObject(
925 ENLISTMENT_QUERY_INFORMATION,
947 status = NtDuplicateObject(
952 RESOURCEMANAGER_QUERY_INFORMATION,
971 bestObjectName = description;
986 TRANSACTIONMANAGER_BASIC_INFORMATION basicInfo;
988 status = NtDuplicateObject(
993 TRANSACTIONMANAGER_QUERY_INFORMATION,
1033 TRANSACTION_BASIC_INFORMATION basicInfo;
1035 status = NtDuplicateObject(
1040 TRANSACTION_QUERY_INFORMATION,
1057 bestObjectName = description;
1071 bestObjectName =
PhFormatGuid(&basicInfo.TransactionId);
1080 PTOKEN_USER tokenUser = NULL;
1081 TOKEN_STATISTICS statistics = { 0 };
1083 status = NtDuplicateObject(
1111 PhInitFormatX(&format[2], statistics.AuthenticationId.LowPart);
1112 PhInitFormatS(&format[3], statistics.TokenType == TokenPrimary ? L
" (Primary)" : L
" (Impersonation)");
1114 bestObjectName =
PhFormat(format, 4, fullName->
Length + 8 + 16 + 16);
1126 if (!bestObjectName)
1129 *BestObjectName = bestObjectName;
1131 return STATUS_SUCCESS;
1156 _In_ HANDLE ProcessHandle,
1158 _In_ ULONG ObjectTypeNumber,
1233 _In_ HANDLE ProcessHandle,
1235 _In_ ULONG ObjectTypeNumber,
1236 _Reserved_ ULONG Flags,
1242 _Reserved_ PVOID *ExtraInformation
1245 NTSTATUS status = STATUS_SUCCESS;
1246 NTSTATUS subStatus = STATUS_SUCCESS;
1247 HANDLE dupHandle = NULL;
1252 if (Handle == NULL || Handle == NtCurrentProcess() || Handle == NtCurrentThread())
1253 return STATUS_INVALID_HANDLE;
1255 return STATUS_INVALID_PARAMETER_3;
1262 if (ProcessHandle != NtCurrentProcess())
1264 status = NtDuplicateObject(
1284 if (BasicInformation)
1297 if (!TypeName && !ObjectName && !BestObjectName)
1312 if (!ObjectName && !BestObjectName)
1319 #define QUERY_NORMALLY 0
1320 #define QUERY_WITH_TIMEOUT 1
1321 #define QUERY_FAIL 2
1342 status = STATUS_SUCCESS;
1362 status = STATUS_SUCCESS;
1367 status = STATUS_SUCCESS;
1373 if (!BestObjectName)
1387 status = STATUS_SUCCESS;
1396 *SubStatus = subStatus;
1405 if (dupHandle && ProcessHandle != NtCurrentProcess())
1423 bufferSize = 0x1000;
1424 buffer = PhAllocate(bufferSize);
1426 while ((status = NtQueryObject(
1432 )) == STATUS_INFO_LENGTH_MISMATCH)
1439 return STATUS_INSUFFICIENT_RESOURCES;
1441 buffer = PhAllocate(bufferSize);
1489 _In_opt_ PLARGE_INTEGER Timeout
1495 PSLIST_ENTRY listEntry;
1506 RtlInterlockedPushEntrySList(&PhpCallWithTimeoutThreadListHead, &threadContext->ListEntry);
1514 if (listEntry = RtlInterlockedPopEntrySList(&PhpCallWithTimeoutThreadListHead))
1517 if (!Timeout || Timeout->QuadPart != 0)
1521 if (listEntry = RtlInterlockedPopEntrySList(&PhpCallWithTimeoutThreadListHead))
1524 PhSetWakeEvent(&PhpCallWithTimeoutThreadReleaseEvent, &waitBlock);
1545 RtlInterlockedPushEntrySList(&PhpCallWithTimeoutThreadListHead, &ThreadContext->ListEntry);
1552 _In_opt_ PVOID Context,
1553 _In_ PLARGE_INTEGER Timeout
1560 if (!ThreadContext->StartEventHandle)
1566 if (!ThreadContext->CompletedEventHandle)
1573 if (!ThreadContext->ThreadHandle)
1577 NtClearEvent(ThreadContext->StartEventHandle);
1578 NtClearEvent(ThreadContext->CompletedEventHandle);
1589 &ThreadContext->ThreadHandle,
1596 NtWaitForSingleObject(ThreadContext->CompletedEventHandle,
FALSE, NULL);
1599 ThreadContext->Routine = Routine;
1600 ThreadContext->Context = Context;
1602 NtSetEvent(ThreadContext->StartEventHandle, NULL);
1603 status = NtWaitForSingleObject(ThreadContext->CompletedEventHandle,
FALSE, Timeout);
1605 ThreadContext->Routine = NULL;
1607 ThreadContext->Context = NULL;
1609 if (status != STATUS_WAIT_0)
1613 NtTerminateThread(ThreadContext->ThreadHandle, STATUS_UNSUCCESSFUL);
1614 status = NtWaitForSingleObject(ThreadContext->ThreadHandle,
FALSE, NULL);
1615 NtClose(ThreadContext->ThreadHandle);
1616 ThreadContext->ThreadHandle = NULL;
1618 status = STATUS_UNSUCCESSFUL;
1625 _In_ PVOID Parameter
1630 NtSetEvent(threadContext->CompletedEventHandle, NULL);
1634 if (NtWaitForSingleObject(threadContext->StartEventHandle,
FALSE, NULL) != STATUS_WAIT_0)
1637 if (threadContext->Routine)
1638 threadContext->Routine(threadContext->Context);
1640 NtSetEvent(threadContext->CompletedEventHandle, NULL);
1643 return STATUS_SUCCESS;
1648 _In_opt_ PVOID Context,
1649 _In_opt_ PLARGE_INTEGER AcquireTimeout,
1650 _In_ PLARGE_INTEGER CallTimeout
1663 status = STATUS_UNSUCCESSFUL;
1670 _In_ PVOID Parameter
1675 switch (context->Work)
1678 context->Status = NtQueryObject(
1679 context->u.NtQueryObject.Handle,
1680 context->u.NtQueryObject.ObjectInformationClass,
1681 context->u.NtQueryObject.ObjectInformation,
1682 context->u.NtQueryObject.ObjectInformationLength,
1683 context->u.NtQueryObject.ReturnLength
1687 context->Status = NtQuerySecurityObject(
1688 context->u.NtQuerySecurityObject.Handle,
1689 context->u.NtQuerySecurityObject.SecurityInformation,
1690 context->u.NtQuerySecurityObject.SecurityDescriptor,
1691 context->u.NtQuerySecurityObject.Length,
1692 context->u.NtQuerySecurityObject.LengthNeeded
1696 context->Status = NtSetSecurityObject(
1697 context->u.NtSetSecurityObject.Handle,
1698 context->u.NtSetSecurityObject.SecurityInformation,
1699 context->u.NtSetSecurityObject.SecurityDescriptor
1704 context->u.KphDuplicateObject.SourceProcessHandle,
1705 context->u.KphDuplicateObject.SourceHandle,
1706 context->u.KphDuplicateObject.TargetProcessHandle,
1707 context->u.KphDuplicateObject.TargetHandle,
1708 context->u.KphDuplicateObject.DesiredAccess,
1709 context->u.KphDuplicateObject.HandleAttributes,
1710 context->u.KphDuplicateObject.Options
1714 context->Status = STATUS_INVALID_PARAMETER;
1718 return STATUS_SUCCESS;
1726 LARGE_INTEGER timeout;
1732 status = Context->Status;
1741 _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
1742 _Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation,
1743 _In_ ULONG ObjectInformationLength,
1744 _Out_opt_ PULONG ReturnLength
1751 context->Status = STATUS_UNSUCCESSFUL;
1752 context->u.NtQueryObject.Handle = Handle;
1753 context->u.NtQueryObject.ObjectInformationClass = ObjectInformationClass;
1754 context->u.NtQueryObject.ObjectInformation = ObjectInformation;
1755 context->u.NtQueryObject.ObjectInformationLength = ObjectInformationLength;
1756 context->u.NtQueryObject.ReturnLength = ReturnLength;
1763 _In_ SECURITY_INFORMATION SecurityInformation,
1764 _Out_writes_bytes_opt_(Length) PSECURITY_DESCRIPTOR SecurityDescriptor,
1766 _Out_ PULONG LengthNeeded
1773 context->Status = STATUS_UNSUCCESSFUL;
1774 context->u.NtQuerySecurityObject.Handle = Handle;
1775 context->u.NtQuerySecurityObject.SecurityInformation = SecurityInformation;
1776 context->u.NtQuerySecurityObject.SecurityDescriptor = SecurityDescriptor;
1777 context->u.NtQuerySecurityObject.Length = Length;
1778 context->u.NtQuerySecurityObject.LengthNeeded = LengthNeeded;
1785 _In_ SECURITY_INFORMATION SecurityInformation,
1786 _In_ PSECURITY_DESCRIPTOR SecurityDescriptor
1793 context->Status = STATUS_UNSUCCESSFUL;
1794 context->u.NtSetSecurityObject.Handle = Handle;
1795 context->u.NtSetSecurityObject.SecurityInformation = SecurityInformation;
1796 context->u.NtSetSecurityObject.SecurityDescriptor = SecurityDescriptor;
1802 _In_ HANDLE SourceProcessHandle,
1803 _In_ HANDLE SourceHandle,
1804 _In_opt_ HANDLE TargetProcessHandle,
1805 _Out_opt_ PHANDLE TargetHandle,
1806 _In_ ACCESS_MASK DesiredAccess,
1807 _In_ ULONG HandleAttributes,
1815 context->Status = STATUS_UNSUCCESSFUL;
1816 context->u.KphDuplicateObject.SourceProcessHandle = SourceProcessHandle;
1817 context->u.KphDuplicateObject.SourceHandle = SourceHandle;
1818 context->u.KphDuplicateObject.TargetProcessHandle = TargetProcessHandle;
1819 context->u.KphDuplicateObject.TargetHandle = TargetHandle;
1820 context->u.KphDuplicateObject.DesiredAccess = DesiredAccess;
1821 context->u.KphDuplicateObject.HandleAttributes = HandleAttributes;
1822 context->u.KphDuplicateObject.Options = Options;