PyObject* psutil_get_open_files(long pid, HANDLE processHandle) { _NtQuerySystemInformation NtQuerySystemInformation = GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation"); _NtDuplicateObject NtDuplicateObject = GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject"); _NtQueryObject NtQueryObject = GetLibraryProcAddress("ntdll.dll", "NtQueryObject"); NTSTATUS status; PSYSTEM_HANDLE_INFORMATION handleInfo; ULONG handleInfoSize = 0x10000; ULONG i; ULONG fileNameLength; PyObject *filesList = Py_BuildValue("[]"); PyObject *arg = NULL; PyObject *fileFromWchar = NULL; if (filesList == NULL) return NULL; handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); if (handleInfo == NULL) { Py_DECREF(filesList); PyErr_NoMemory(); return NULL; } /* NtQuerySystemInformation won't give us the correct buffer size, so we guess by doubling the buffer size. */ while ((status = NtQuerySystemInformation( SystemHandleInformation, handleInfo, handleInfoSize, NULL )) == STATUS_INFO_LENGTH_MISMATCH) { handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2); } /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */ if (!NT_SUCCESS(status)) { //printf("NtQuerySystemInformation failed!\n"); Py_DECREF(filesList); free(handleInfo); return NULL; } for (i = 0; i < handleInfo->HandleCount; i++) { SYSTEM_HANDLE handle = handleInfo->Handles[i]; HANDLE dupHandle = NULL; POBJECT_TYPE_INFORMATION objectTypeInfo = NULL; PVOID objectNameInfo; UNICODE_STRING objectName; ULONG returnLength; fileFromWchar = NULL; arg = NULL; /* Check if this handle belongs to the PID the user specified. */ if (handle.ProcessId != pid) continue; /* Skip handles with the following access codes as the next call to NtDuplicateObject() or NtQueryObject() might hang forever. */ if((handle.GrantedAccess == 0x0012019f) || (handle.GrantedAccess == 0x001a019f) || (handle.GrantedAccess == 0x00120189) || (handle.GrantedAccess == 0x00100000)) { continue; } /* Duplicate the handle so we can query it. */ if (!NT_SUCCESS(NtDuplicateObject( processHandle, handle.Handle, GetCurrentProcess(), &dupHandle, 0, 0, 0 ))) { //printf("[%#x] Error!\n", handle.Handle); continue; } /* Query the object type. */ objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000); if (!NT_SUCCESS(NtQueryObject( dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL ))) { //printf("[%#x] Error!\n", handle.Handle); free(objectTypeInfo); CloseHandle(dupHandle); continue; } objectNameInfo = malloc(0x1000); if (!NT_SUCCESS(NtQueryObject( dupHandle, ObjectNameInformation, objectNameInfo, 0x1000, &returnLength ))) { /* Reallocate the buffer and try again. */ objectNameInfo = realloc(objectNameInfo, returnLength); if (!NT_SUCCESS(NtQueryObject( dupHandle, ObjectNameInformation, objectNameInfo, returnLength, NULL ))) { /* We have the type name, so just display that.*/ /* printf( "[%#x] %.*S: (could not get name)\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer ); */ free(objectTypeInfo); free(objectNameInfo); CloseHandle(dupHandle); continue; } } /* Cast our buffer into an UNICODE_STRING. */ objectName = *(PUNICODE_STRING)objectNameInfo; /* Print the information! */ if (objectName.Length) { /* The object has a name. Make sure it is a file otherwise ignore it */ fileNameLength = objectName.Length / 2; if (wcscmp(objectTypeInfo->Name.Buffer, L"File") == 0) { //printf("%.*S\n", objectName.Length / 2, objectName.Buffer); fileFromWchar = PyUnicode_FromWideChar(objectName.Buffer, fileNameLength); if (fileFromWchar == NULL) goto error_py_fun; #if PY_MAJOR_VERSION >= 3 arg = Py_BuildValue("N", PyUnicode_AsUTF8String(fileFromWchar)); #else arg = Py_BuildValue("N", PyUnicode_FromObject(fileFromWchar)); #endif if (!arg) goto error_py_fun; Py_XDECREF(fileFromWchar); fileFromWchar = NULL; if (PyList_Append(filesList, arg)) goto error_py_fun; Py_XDECREF(arg); } /* printf( "[%#x] %.*S: %.*S\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer, objectName.Length / 2, objectName.Buffer ); */ } else { /* Print something else. */ /* printf( "[%#x] %.*S: (unnamed)\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer ); */ ;; } free(objectTypeInfo); free(objectNameInfo); CloseHandle(dupHandle); } free(handleInfo); CloseHandle(processHandle); return filesList; error_py_fun: Py_XDECREF(arg); Py_XDECREF(fileFromWchar); Py_DECREF(filesList); return NULL; }
int wmain(int argc, WCHAR *argv[]) { _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation"); _NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject"); _NtQueryObject NtQueryObject = (_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject"); NTSTATUS status; PSYSTEM_HANDLE_INFORMATION handleInfo; ULONG handleInfoSize = 0x10000; ULONG pid = 0; HANDLE processHandle; ULONG i; if (argc < 2) { printf("Usage: handles filepath [pid]\n"); return 1; } if (argc > 2) { pid = _wtoi(argv[2]); } // convert C:\Windows\System32 to \Device\HarddiskVolume1\Windows\System32 const WCHAR* filePath = argv[1]; if (wcslen(filePath) < 2 || filePath[1] != L':') { printf("Can't process input path which is tool short or not contain local driver!\n"); return 1; } PWSTR pDosDriveName = new TCHAR[MAX_PATH]; TCHAR szDrive[3] = TEXT(" :"); szDrive[0] = filePath[0]; DWORD uiLen = QueryDosDeviceW(szDrive, pDosDriveName, MAX_PATH); if (0 == uiLen) { if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) { printf("QueryDosDeviceW failed: %d\n", GetLastError()); return 1; } delete[]pDosDriveName; pDosDriveName = new TCHAR[uiLen + 1]; uiLen = QueryDosDevice(szDrive, pDosDriveName, uiLen + 1); if (0 == uiLen) { printf("QueryDosDeviceW failed: %d\n", GetLastError()); return 1; } } wcscat(pDosDriveName, &filePath[2]); handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); /* NtQuerySystemInformation won't give us the correct buffer size, so we guess by doubling the buffer size. */ while ((status = NtQuerySystemInformation( SystemHandleInformation, handleInfo, handleInfoSize, NULL )) == STATUS_INFO_LENGTH_MISMATCH) handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2); /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */ if (!NT_SUCCESS(status)) { printf("NtQuerySystemInformation failed!\n"); return 1; } for (i = 0; i < handleInfo->HandleCount; i++) { SYSTEM_HANDLE handle = handleInfo->Handles[i]; HANDLE dupHandle = NULL; POBJECT_TYPE_INFORMATION objectTypeInfo; PVOID objectNameInfo; UNICODE_STRING objectName; ULONG returnLength; // Jump of no file /*if (handle.ObjectTypeNumber != 31) { continue; }*/ /* Check if this handle belongs to the PID the user specified. */ if (pid != 0 && handle.ProcessId != pid) continue; if (!(processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, handle.ProcessId))) { //printf("Could not open PID %d! (Don't try to open a system process.)\n", handle.ProcessId); continue; } /* Duplicate the handle so we can query it. */ DWORD re = NtDuplicateObject( processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, 0, 0, 0 ); if (ERROR_SUCCESS != re) { printf("[%#x] Error!\n", handle.Handle); continue; } /* Query the object type. */ objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000); if (!NT_SUCCESS(NtQueryObject( dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL ))) { printf("[%#x] Error!\n", handle.Handle); CloseHandle(dupHandle); continue; } /* Query the object name (unless it has an access of 0x0012019f, on which NtQueryObject could hang. */ if (handle.GrantedAccess == 0x0012019f) { /* We have the type, so display that. */ printf( "[%#x] %.*S: (did not get name)\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer ); free(objectTypeInfo); CloseHandle(dupHandle); continue; } objectNameInfo = malloc(0x1000); if (!NT_SUCCESS(MyNtQueryObject( NtQueryObject, dupHandle, ObjectNameInformation, objectNameInfo, 0x1000, &returnLength ))) { /* Reallocate the buffer and try again. */ objectNameInfo = realloc(objectNameInfo, returnLength); if (!NT_SUCCESS(MyNtQueryObject( NtQueryObject, dupHandle, ObjectNameInformation, objectNameInfo, returnLength, NULL ))) { /* We have the type name, so just display that. */ printf( "[%#x] %.*S: (could not get name)\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer ); free(objectTypeInfo); free(objectNameInfo); CloseHandle(dupHandle); continue; } } /* Cast our buffer into an UNICODE_STRING. */ objectName = *(PUNICODE_STRING)objectNameInfo; /* Print the information! */ if (objectName.Length) { /* The object has a name. */ printf( "[%#x] %.*S: %.*S\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer, objectName.Length / 2, objectName.Buffer ); if (wcscmp(objectName.Buffer, pDosDriveName) == 0) { printf("opend by process: %d", handle.ProcessId); break; } } else { /* Print something else. */ printf( "[%#x] %.*S: (unnamed)\n", handle.Handle, objectTypeInfo->Name.Length / 2, objectTypeInfo->Name.Buffer ); } free(objectTypeInfo); free(objectNameInfo); CloseHandle(dupHandle); } free(handleInfo); CloseHandle(processHandle); return 0; }
BOOL GetProcessIdByMutantName(LPCWSTR mutant_name, std::vector<ULONG> &pids) { _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetLibraryProcAddress(TEXT("ntdll.dll"), "NtQuerySystemInformation"); _NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)GetLibraryProcAddress(TEXT("ntdll.dll"), "NtDuplicateObject"); _NtQueryObject NtQueryObject = (_NtQueryObject)GetLibraryProcAddress(TEXT("ntdll.dll"), "NtQueryObject"); if (NtQuerySystemInformation == NULL || NtDuplicateObject == NULL || NtQueryObject == NULL) { return FALSE; } PSYSTEM_HANDLE_INFORMATION handle_info; ULONG handle_info_size = 0x10000; CHeapPtr<UCHAR> handle_info_buffer; handle_info_buffer.Allocate(handle_info_size); NTSTATUS ns; while ((ns = NtQuerySystemInformation( SystemHandleInformation, handle_info_buffer.m_pData, handle_info_size, NULL )) == STATUS_INFO_LENGTH_MISMATCH) { handle_info_buffer.Reallocate(handle_info_size *= 2); } if (!NT_SUCCESS(ns)) { return FALSE; } handle_info = (PSYSTEM_HANDLE_INFORMATION)handle_info_buffer.m_pData; ULONG process_id = 0; HANDLE cur_handle = NULL; for (ULONG i = 0; i < handle_info->HandleCount; i++) { SYSTEM_HANDLE handle = handle_info->Handles[i]; ULONG info_size = 0x1000; if (handle.GrantedAccess == 0x0012019f) { continue; } if (process_id != handle.ProcessId) { process_id = handle.ProcessId; if (cur_handle != NULL) { CloseHandle(cur_handle); cur_handle = NULL; } if (cur_handle == NULL) { cur_handle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, process_id); } if (cur_handle == NULL) { continue; } } HANDLE dup_handle = NULL; if (!NT_SUCCESS(NtDuplicateObject( cur_handle, (HANDLE)handle.Handle, GetCurrentProcess(), &dup_handle, 0, 0, 0 ))) { continue; } CHandle auto_handle(dup_handle); CHeapPtr<UCHAR> obj_type_buffer; obj_type_buffer.Allocate(info_size); POBJECT_TYPE_INFORMATION obj_type_info = (POBJECT_TYPE_INFORMATION)obj_type_buffer.m_pData; if (!NT_SUCCESS(NtQueryObject( dup_handle, ObjectTypeInformation, obj_type_info, info_size, NULL ))) { continue; } if (memcmp(obj_type_info->Name.Buffer, L"Mutant", 12) != 0) { continue; } CHeapPtr<UCHAR> obj_name_buffer; obj_name_buffer.Allocate(info_size); PVOID obj_name_info = obj_name_buffer.m_pData; ULONG return_length; if (!NT_SUCCESS(NtQueryObject( dup_handle, ObjectNameInformation, obj_name_info, info_size, &return_length ))) { continue; } UNICODE_STRING object_name = *(PUNICODE_STRING)obj_name_info; if (object_name.Length) { CStringW object_name(object_name.Buffer, object_name.Length / 2); if (object_name == mutant_name) { pids.push_back(process_id); } //wprintf(L"%u %s\n", process_id, object_name.GetString()); } } if (cur_handle != NULL) { CloseHandle(cur_handle); cur_handle = NULL; } return TRUE; }
bool search::generate_pbo_list() { NTSTATUS status; PSYSTEM_HANDLE_INFORMATION handleInfo; ULONG handleInfoSize = 0x10000; ULONG pid; HANDLE processHandle; ULONG i; _NtQuerySystemInformation NtQuerySystemInformation = (_NtQuerySystemInformation)GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation"); _NtDuplicateObject NtDuplicateObject = (_NtDuplicateObject)GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject"); _NtQueryObject NtQueryObject = (_NtQueryObject)GetLibraryProcAddress("ntdll.dll", "NtQueryObject"); if (!NtQuerySystemInformation || !NtDuplicateObject || !NtQueryObject) return false; pid = GetCurrentProcessId(); processHandle = GetCurrentProcess(); handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize); while ((status = NtQuerySystemInformation( SystemHandleInformation, handleInfo, handleInfoSize, NULL )) == STATUS_INFO_LENGTH_MISMATCH) handleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(handleInfo, handleInfoSize *= 2); /* NtQuerySystemInformation stopped giving us STATUS_INFO_LENGTH_MISMATCH. */ if (!NT_SUCCESS(status)) { LOG(ERROR) << "Error opening object for pbo search"; free(handleInfo); return false; } for (i = 0; i < handleInfo->HandleCount; i++) { SYSTEM_HANDLE handle = handleInfo->Handles[i]; HANDLE dupHandle = NULL; POBJECT_TYPE_INFORMATION objectTypeInfo; PVOID objectNameInfo; UNICODE_STRING objectName; ULONG returnLength; /* Check if this handle belongs to the PID the user specified. */ if (handle.ProcessId != pid) continue; /* Duplicate the handle so we can query it. */ if (!NT_SUCCESS(NtDuplicateObject( processHandle, (HANDLE)handle.Handle, GetCurrentProcess(), &dupHandle, 0, 0, 0 ))) { continue; } /* Query the object type. */ objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(0x1000); if (!NT_SUCCESS(NtQueryObject( dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL ))) { CloseHandle(dupHandle); continue; } /* Query the object name (unless it has an access of 0x0012019f, on which NtQueryObject could hang. */ if (handle.GrantedAccess == 0x0012019f) { free(objectTypeInfo); CloseHandle(dupHandle); continue; } objectNameInfo = malloc(0x1000); if (!NT_SUCCESS(NtQueryObject( dupHandle, ObjectNameInformation, objectNameInfo, 0x1000, &returnLength ))) { /* Reallocate the buffer and try again. */ objectNameInfo = realloc(objectNameInfo, returnLength); if (!NT_SUCCESS(NtQueryObject( dupHandle, ObjectNameInformation, objectNameInfo, returnLength, NULL ))) { free(objectTypeInfo); free(objectNameInfo); CloseHandle(dupHandle); continue; } } /* Cast our buffer into an UNICODE_STRING. */ objectName = *(PUNICODE_STRING)objectNameInfo; /* Print the information! */ if (objectName.Length) { std::wstring tmp_type(objectTypeInfo->Name.Buffer); std::wstring tmp_name(objectName.Buffer); std::string object_type(tmp_type.begin(), tmp_type.end()); std::string object_name(tmp_name.begin(), tmp_name.end()); if (object_type == "File" && object_name.find(".pbo") != object_name.npos) { char buffer[MAX_PATH]; GetFinalPathNameByHandle(dupHandle, buffer, sizeof(buffer), VOLUME_NAME_DOS); LOG(DEBUG) << "Pbo: " << buffer; _active_pbo_list.push_back(std::string(buffer)); } } free(objectTypeInfo); free(objectNameInfo); CloseHandle(dupHandle); } free(handleInfo); return true; }