void *FindTokenObject(HANDLE Handle) { ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation; LONG Status; DWORD *p; DWORD n = 0x1000; HMODULE hNtdll; PSYSTEM_HANDLE_INFORMATION hinfo; BYTE *Object; DWORD cpid; cpid = GetCurrentProcessId(); hNtdll = GetModuleHandle("ntdll.dll"); ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll, "ZwQuerySystemInformation"); if (!ZwQuerySystemInformation) return NULL; if ( !(p = (DWORD *)malloc(n)) ) return NULL; while ( (Status=ZwQuerySystemInformation(SystemHandleInformation, p, n, 0)) == STATUS_INFO_LENGTH_MISMATCH ) { free(p); n*=2; if (!(p = (DWORD *)malloc(n))) return NULL; } if (Status != STATUS_SUCCESS) { free(p); return NULL; } hinfo = PSYSTEM_HANDLE_INFORMATION(p + 2); for (DWORD i = 0; i < *p; i++) { if (hinfo[i].ProcessId == cpid && hinfo[i].Handle == (USHORT)Handle) { Object = (BYTE *)hinfo[i].Object; free(p); return Object; } } free(p); return NULL; }
int __stdcall EnumMutex2(_CollectionPtr *pColl, void* doEventsCallback){ int cnt=0; char buf[600]; NTSTATUS rv; vbCallback doEvents = (vbCallback)doEventsCallback; if(pColl==0 || *pColl == 0) return -4; EnablePrivilege(SE_DEBUG_NAME); HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll")); if (!hNtDll) return -1; PZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (PZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll, "ZwQuerySystemInformation"); PZWDUPLICATEOBJECT ZwDuplicateObject = (PZWDUPLICATEOBJECT)GetProcAddress(hNtDll, "ZwDuplicateObject"); PZWQUERYOBJECT ZwQueryObject = (PZWQUERYOBJECT)GetProcAddress(hNtDll, "ZwQueryObject"); if( (int)ZwQuerySystemInformation == 0 || (int)ZwDuplicateObject == 0 || (int)ZwQueryObject == 0) return -2; ULONG n = 0x1000; PULONG p = new ULONG[n]; while (ZwQuerySystemInformation(SystemHandleInformation, p, n * sizeof *p, 0) == STATUS_INFO_LENGTH_MISMATCH){ delete [] p; p = new ULONG[n *= 2]; } PSYSTEM_HANDLE_INFORMATION h = PSYSTEM_HANDLE_INFORMATION(p + 1); for (ULONG i = 0; i < *p; i++){ HANDLE hObject = 0; OBJECT_BASIC_INFORMATION obi; HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, h[i].ProcessId); if(hProcess == 0) continue; //kept getting NtClose was called on a handle that was protected from close via NtSetInformationObject. //also this is much faster by eliminating the DUPLICATE_SAME_ATTRIBUTES flag..no need to use the doevents callback? if (ZwDuplicateObject(hProcess, HANDLE(h[i].Handle), NtCurrentProcess(), &hObject, 0, 0, /*DUPLICATE_SAME_ATTRIBUTES*/ NULL)!= STATUS_SUCCESS) continue; rv = ZwQueryObject(hObject, ObjectBasicInformation, &obi, sizeof obi, &n); if(!NT_SUCCESS(rv)) continue; n = obi.TypeInformationLength + 2; POBJECT_TYPE_INFORMATION oti = POBJECT_TYPE_INFORMATION(new CHAR[n]); rv = ZwQueryObject(hObject, ObjectTypeInformation, oti, n, &n); if(!NT_SUCCESS(rv)) continue; if(oti[0].Name.Length > 0 && wcscmp(oti[0].Name.Buffer,L"Mutant")==0){ n = obi.NameInformationLength == 0 ? MAX_PATH * sizeof (WCHAR) : obi.NameInformationLength; POBJECT_NAME_INFORMATION oni = POBJECT_NAME_INFORMATION(new CHAR[n]); rv = ZwQueryObject(hObject, ObjectNameInformation, oni, n, &n); if (NT_SUCCESS(rv)){ if(oni[0].Name.Length > 0){ _snprintf(buf, sizeof(buf)-1, "%ld %ls", h[i].ProcessId, oni[0].Name.Buffer); addStr(*pColl,buf); cnt++; } } } //_snprintf(buf, sizeof(buf), "i=%d hObject=%x hProcess=%x\r\n",i,hObject,hProcess); //OutputDebugString(buf); if( (int)doEvents != 0 && i > 0 && i%5 == 0 ) doEvents(""); if(hObject !=0) CloseHandle(hObject); if(hProcess!=0) CloseHandle(hProcess); } delete [] p; return cnt; }
//todo: grab the bug fixes from v2 to speed up and prevent can not close error in debug mode. ignore callback int __stdcall EnumMutex(char* outPath){ int cnt=0; EnablePrivilege(SE_DEBUG_NAME); HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll")); if (!hNtDll) return -1; PZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = (PZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtDll, "ZwQuerySystemInformation"); PZWDUPLICATEOBJECT ZwDuplicateObject = (PZWDUPLICATEOBJECT)GetProcAddress(hNtDll, "ZwDuplicateObject"); PZWQUERYOBJECT ZwQueryObject = (PZWQUERYOBJECT)GetProcAddress(hNtDll, "ZwQueryObject"); if( (int)ZwQuerySystemInformation == 0 || (int)ZwDuplicateObject == 0 || (int)ZwQueryObject == 0) return -2; ULONG n = 0x1000; PULONG p = new ULONG[n]; FILE *f = fopen(outPath,"w"); if(f == NULL) return -3; while (ZwQuerySystemInformation(SystemHandleInformation, p, n * sizeof *p, 0) == STATUS_INFO_LENGTH_MISMATCH){ delete [] p; p = new ULONG[n *= 2]; } PSYSTEM_HANDLE_INFORMATION h = PSYSTEM_HANDLE_INFORMATION(p + 1); for (ULONG i = 0; i < *p; i++){ HANDLE hObject; OBJECT_BASIC_INFORMATION obi; HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, h[i].ProcessId); if (ZwDuplicateObject(hProcess, HANDLE(h[i].Handle), NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ATTRIBUTES)!= STATUS_SUCCESS){ continue; } ZwQueryObject(hObject, ObjectBasicInformation, &obi, sizeof obi, &n); n = obi.TypeInformationLength + 2; POBJECT_TYPE_INFORMATION oti = POBJECT_TYPE_INFORMATION(new CHAR[n]); ZwQueryObject(hObject, ObjectTypeInformation, oti, n, &n); if(oti[0].Name.Length > 0 && wcscmp(oti[0].Name.Buffer,L"Mutant")==0){ n = obi.NameInformationLength == 0 ? MAX_PATH * sizeof (WCHAR) : obi.NameInformationLength; POBJECT_NAME_INFORMATION oni = POBJECT_NAME_INFORMATION(new CHAR[n]); NTSTATUS rv = ZwQueryObject(hObject, ObjectNameInformation, oni, n, &n); if (NT_SUCCESS(rv)){ if(oni[0].Name.Length > 0){ fprintf(f,"%ld ", h[i].ProcessId); fprintf(f,"%.*ws\r\n", oni[0].Name.Length / 2, oni[0].Name.Buffer); cnt++; } } } CloseHandle(hObject); CloseHandle(hProcess); } delete [] p; fclose(f); return cnt; }