Skip to content

Commit 64db3d1

Browse files
🤖
1 parent 6a49605 commit 64db3d1

File tree

1 file changed

+66
-27
lines changed

1 file changed

+66
-27
lines changed

‎main.cpp‎

Lines changed: 66 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1604,6 +1604,59 @@ _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+
}
16071660

16081661
void ListProcHandles(HANDLE hproc, DWORD pid) {
16091662
// this is so that we can get the handles of a process
@@ -1708,33 +1761,19 @@ _NtQueryObject pfnNtQueryObject =
17081761
continue;
17091762
}
17101763

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-
}
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+
17381777

17391778

17401779
objectNameInfo = malloc(0x1000);

0 commit comments

Comments
 (0)