@@ -1604,59 +1604,6 @@ _NtQueryObject pfnNtQueryObject =
16041604 (_NtQueryObject)GetLibraryProcAddress(" ntdll.dll" , " NtQueryObject" );
16051605
16061606
1607- // Structure to pass data to the worker thread
1608- struct QueryObjectThreadData {
1609- _NtQueryObject pfnNtQueryObject;
1610- HANDLE handle;
1611- PVOID buffer;
1612- ULONG bufferSize;
1613- NTSTATUS status;
1614- volatile BOOL completed;
1615- };
1616-
1617- // Worker thread function
1618- DWORD WINAPI QueryObjectThreadProc (LPVOID param) {
1619- QueryObjectThreadData* data = (QueryObjectThreadData*)param;
1620-
1621- data->status = data->pfnNtQueryObject (
1622- data->handle ,
1623- (OBJECT_INFORMATION_CLASS )ObjectNameInformation,
1624- data->buffer ,
1625- data->bufferSize ,
1626- NULL
1627- );
1628-
1629- data->completed = TRUE ;
1630- return 0 ;
1631- }
1632-
1633- // Safe query with 1ms timeout
1634- bool QueryObjectNameSafe (_NtQueryObject pfnNtQueryObject, HANDLE handle,
1635- PVOID buffer, ULONG bufferSize, NTSTATUS * outStatus) {
1636- QueryObjectThreadData threadData = {0 };
1637- threadData.pfnNtQueryObject = pfnNtQueryObject;
1638- threadData.handle = handle;
1639- threadData.buffer = buffer;
1640- threadData.bufferSize = bufferSize;
1641- threadData.completed = FALSE ;
1642-
1643- HANDLE hThread = CreateThread (NULL , 0 , QueryObjectThreadProc, &threadData, 0 , NULL );
1644- if (!hThread) return false ;
1645-
1646- // Wait for 1ms
1647- DWORD waitResult = WaitForSingleObject (hThread, 1 );
1648-
1649- if (waitResult == WAIT_TIMEOUT ) {
1650- // Hung! Kill the thread (leaks the thread but keeps us fast)
1651- TerminateThread (hThread, 1 );
1652- CloseHandle (hThread);
1653- return false ; // Timed out
1654- }
1655-
1656- *outStatus = threadData.status ;
1657- CloseHandle (hThread);
1658- return true ; // Success
1659- }
16601607
16611608void ListProcHandles (HANDLE hproc, DWORD pid) {
16621609 // this is so that we can get the handles of a process
@@ -1761,19 +1708,33 @@ _NtQueryObject pfnNtQueryObject =
17611708 continue ;
17621709 }
17631710
1764- NTSTATUS status;
1765- if (!QueryObjectNameSafe (pfnNtQueryObject, dupHandle, objectNameInfo, 0x1000 , &status)) {
1766- // Timed out after 1ms - likely a blocking handle
1767- printf (" [%#x] %.*S: (query timed out)\n " ,
1768- handle.Handle ,
1769- objectTypeInfo->Name .Length / 2 ,
1770- objectTypeInfo->Name .Buffer );
1771- free (objectTypeInfo);
1772- CloseHandle (dupHandle);
1773- continue ;
1774- }
1775-
1776-
1711+ /* Check if this type is known to hang on name queries */
1712+ WCHAR typeName[64 ];
1713+ wcsncpy_s (typeName, 64 , objectTypeInfo->Name .Buffer , objectTypeInfo->Name .Length / 2 );
1714+ typeName[objectTypeInfo->Name .Length / 2 ] = L' \0 ' ;
1715+
1716+ if (wcscmp (typeName, L" File" ) == 0 || wcscmp (typeName, L" ALPC Port" ) == 0 ) {
1717+ printf (" [%#x] %.*S: (name query skipped)\n " , handle.Handle ,
1718+ objectTypeInfo->Name .Length / 2 , objectTypeInfo->Name .Buffer );
1719+ free (objectTypeInfo);
1720+ CloseHandle (dupHandle);
1721+ continue ;
1722+ }
1723+ /* Query the object name (unless it has an access of
1724+ 0x0012019f, on which NtQueryObject could hang. */
1725+ if (handle.GrantedAccess == 0x0012019f )
1726+ {
1727+ /* We have the type, so display that. */
1728+ printf (
1729+ " [%#x] %.*S: (did not get name)\n " ,
1730+ handle.Handle ,
1731+ objectTypeInfo->Name .Length / 2 ,
1732+ objectTypeInfo->Name .Buffer
1733+ );
1734+ free (objectTypeInfo);
1735+ CloseHandle (dupHandle);
1736+ continue ;
1737+ }
17771738
17781739
17791740 objectNameInfo = malloc (0x1000 );
0 commit comments