VOID PhShowNetworkStackDialog( __in HWND ParentWindowHandle, __in PPH_NETWORK_ITEM NetworkItem ) { NETWORK_STACK_CONTEXT networkStackContext; networkStackContext.NetworkItem = NetworkItem; networkStackContext.SymbolProvider = PhCreateSymbolProvider(NetworkItem->ProcessId); if (networkStackContext.SymbolProvider->IsRealHandle) { // Load symbols for the process. networkStackContext.LoadingProcessId = NetworkItem->ProcessId; PhEnumGenericModules( NetworkItem->ProcessId, networkStackContext.SymbolProvider->ProcessHandle, 0, LoadSymbolsEnumGenericModulesCallback, &networkStackContext ); // Load symbols for kernel-mode. networkStackContext.LoadingProcessId = SYSTEM_PROCESS_ID; PhEnumGenericModules( SYSTEM_PROCESS_ID, NULL, 0, LoadSymbolsEnumGenericModulesCallback, &networkStackContext ); } else { PhDereferenceObject(networkStackContext.SymbolProvider); PhShowError(ParentWindowHandle, L"Unable to open the process."); return; } DialogBoxParam( PhInstanceHandle, MAKEINTRESOURCE(IDD_NETSTACK), ParentWindowHandle, PhpNetworkStackDlgProc, (LPARAM)&networkStackContext ); PhDereferenceObject(networkStackContext.SymbolProvider); }
ULONG GetProcessDotNetVersions( __in HANDLE ProcessId ) { HANDLE processHandle; ULONG versions; #ifdef _M_X64 BOOLEAN isWow64; #endif versions = 0; if (NT_SUCCESS(PhOpenProcess(&processHandle, ProcessQueryAccess | PROCESS_VM_READ, ProcessId))) { #ifdef _M_X64 isWow64 = FALSE; PhGetProcessIsWow64(processHandle, &isWow64); if (isWow64) versions |= CLR_PROCESS_IS_WOW64; #endif PhEnumGenericModules(ProcessId, processHandle, 0, DotNetVersionsEnumModulesCallback, &versions); NtClose(processHandle); } return versions; }
static NTSTATUS PhpFindObjectsThreadStart( _In_ PVOID Parameter ) { NTSTATUS status = STATUS_SUCCESS; PSYSTEM_HANDLE_INFORMATION_EX handles; PPH_HASHTABLE processHandleHashtable; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; ULONG i; // Refuse to search with no filter. if (SearchString->Length == 0) goto Exit; // Try to get a search pointer from the search string. UseSearchPointer = PhStringToInteger64(&SearchString->sr, 0, &SearchPointer); _wcsupr(SearchString->Buffer); if (NT_SUCCESS(status = PhEnumHandlesEx(&handles))) { static PH_INITONCE initOnce = PH_INITONCE_INIT; static ULONG fileObjectTypeIndex = -1; BOOLEAN useWorkQueue = FALSE; PH_WORK_QUEUE workQueue; processHandleHashtable = PhCreateSimpleHashtable(8); if (!KphIsConnected() && WindowsVersion >= WINDOWS_VISTA) { useWorkQueue = TRUE; PhInitializeWorkQueue(&workQueue, 1, 20, 1000); if (PhBeginInitOnce(&initOnce)) { UNICODE_STRING fileTypeName; RtlInitUnicodeString(&fileTypeName, L"File"); fileObjectTypeIndex = PhGetObjectTypeNumber(&fileTypeName); PhEndInitOnce(&initOnce); } } for (i = 0; i < handles->NumberOfHandles; i++) { PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = &handles->Handles[i]; PVOID *processHandlePtr; HANDLE processHandle; if (SearchStop) break; // Open a handle to the process if we don't already have one. processHandlePtr = PhFindItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId ); if (processHandlePtr) { processHandle = (HANDLE)*processHandlePtr; } else { if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_DUP_HANDLE, (HANDLE)handleInfo->UniqueProcessId ))) { PhAddItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId, processHandle ); } else { continue; } } if (useWorkQueue && handleInfo->ObjectTypeIndex == (USHORT)fileObjectTypeIndex) { PSEARCH_HANDLE_CONTEXT searchHandleContext; searchHandleContext = PhAllocate(sizeof(SEARCH_HANDLE_CONTEXT)); searchHandleContext->NeedToFree = TRUE; searchHandleContext->HandleInfo = handleInfo; searchHandleContext->ProcessHandle = processHandle; PhQueueItemWorkQueue(&workQueue, SearchHandleFunction, searchHandleContext); } else { SEARCH_HANDLE_CONTEXT searchHandleContext; searchHandleContext.NeedToFree = FALSE; searchHandleContext.HandleInfo = handleInfo; searchHandleContext.ProcessHandle = processHandle; SearchHandleFunction(&searchHandleContext); } } if (useWorkQueue) { PhWaitForWorkQueue(&workQueue); PhDeleteWorkQueue(&workQueue); } { PPH_KEY_VALUE_PAIR entry; i = 0; while (PhEnumHashtable(processHandleHashtable, &entry, &i)) NtClose((HANDLE)entry->Value); } PhDereferenceObject(processHandleHashtable); PhFree(handles); } if (NT_SUCCESS(PhEnumProcesses(&processes))) { process = PH_FIRST_PROCESS(processes); do { PhEnumGenericModules( process->UniqueProcessId, NULL, PH_ENUM_GENERIC_MAPPED_FILES | PH_ENUM_GENERIC_MAPPED_IMAGES, EnumModulesCallback, (PVOID)process->UniqueProcessId ); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); } Exit: PostMessage(PhFindObjectsWindowHandle, WM_PH_SEARCH_FINISHED, status, 0); return STATUS_SUCCESS; }
VOID PhModuleProviderUpdate( __in PVOID Object ) { PPH_MODULE_PROVIDER moduleProvider = (PPH_MODULE_PROVIDER)Object; PPH_LIST modules; ULONG i; // If we didn't get a handle when we created the provider, // abort (unless this is the System process - in that case // we don't need a handle). if (!moduleProvider->ProcessHandle && moduleProvider->ProcessId != SYSTEM_PROCESS_ID) return; modules = PhCreateList(20); PhEnumGenericModules( moduleProvider->ProcessId, moduleProvider->ProcessHandle, PH_ENUM_GENERIC_MAPPED_FILES | PH_ENUM_GENERIC_MAPPED_IMAGES, EnumModulesCallback, modules ); // Look for removed modules. { PPH_LIST modulesToRemove = NULL; ULONG enumerationKey = 0; PPH_MODULE_ITEM *moduleItem; while (PhEnumHashtable(moduleProvider->ModuleHashtable, (PPVOID)&moduleItem, &enumerationKey)) { BOOLEAN found = FALSE; // Check if the module still exists. for (i = 0; i < modules->Count; i++) { PPH_MODULE_INFO module = modules->Items[i]; if ((*moduleItem)->BaseAddress == module->BaseAddress) { found = TRUE; break; } } if (!found) { // Raise the module removed event. PhInvokeCallback(&moduleProvider->ModuleRemovedEvent, *moduleItem); if (!modulesToRemove) modulesToRemove = PhCreateList(2); PhAddItemList(modulesToRemove, *moduleItem); } } if (modulesToRemove) { PhAcquireFastLockExclusive(&moduleProvider->ModuleHashtableLock); for (i = 0; i < modulesToRemove->Count; i++) { PhpRemoveModuleItem( moduleProvider, (PPH_MODULE_ITEM)modulesToRemove->Items[i] ); } PhReleaseFastLockExclusive(&moduleProvider->ModuleHashtableLock); PhDereferenceObject(modulesToRemove); } } // Go through the queued thread query data. { PSLIST_ENTRY entry; PPH_MODULE_QUERY_DATA data; entry = RtlInterlockedFlushSList(&moduleProvider->QueryListHead); while (entry) { data = CONTAINING_RECORD(entry, PH_MODULE_QUERY_DATA, ListEntry); entry = entry->Next; data->ModuleItem->VerifyResult = data->VerifyResult; data->ModuleItem->VerifySignerName = data->VerifySignerName; data->ModuleItem->JustProcessed = TRUE; PhDereferenceObject(data->ModuleItem); PhFree(data); } } // Look for new modules. for (i = 0; i < modules->Count; i++) { PPH_MODULE_INFO module = modules->Items[i]; PPH_MODULE_ITEM moduleItem; moduleItem = PhReferenceModuleItem(moduleProvider, module->BaseAddress); if (!moduleItem) { moduleItem = PhCreateModuleItem(); moduleItem->BaseAddress = module->BaseAddress; PhPrintPointer(moduleItem->BaseAddressString, moduleItem->BaseAddress); moduleItem->Size = module->Size; moduleItem->Flags = module->Flags; moduleItem->Type = module->Type; moduleItem->Reserved = 0; moduleItem->LoadCount = module->LoadCount; moduleItem->Name = module->Name; PhReferenceObject(moduleItem->Name); moduleItem->FileName = module->FileName; PhReferenceObject(moduleItem->FileName); PhInitializeImageVersionInfo( &moduleItem->VersionInfo, PhGetString(moduleItem->FileName) ); moduleItem->IsFirst = i == 0; if (moduleItem->Type == PH_MODULE_TYPE_MODULE || moduleItem->Type == PH_MODULE_TYPE_WOW64_MODULE || moduleItem->Type == PH_MODULE_TYPE_MAPPED_IMAGE) { PH_REMOTE_MAPPED_IMAGE remoteMappedImage; // Note: // On Windows 7 the LDRP_IMAGE_NOT_AT_BASE flag doesn't appear to be used // anymore. Instead we'll check ImageBase in the image headers. We read this in // from the process' memory because: // // 1. It (should be) faster than opening the file and mapping it in, and // 2. It contains the correct original image base relocated by ASLR, if present. if (NT_SUCCESS(PhLoadRemoteMappedImage(moduleProvider->ProcessHandle, moduleItem->BaseAddress, &remoteMappedImage))) { moduleItem->ImageTimeDateStamp = remoteMappedImage.NtHeaders->FileHeader.TimeDateStamp; moduleItem->ImageCharacteristics = remoteMappedImage.NtHeaders->FileHeader.Characteristics; if (remoteMappedImage.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { if ((ULONG_PTR)((PIMAGE_OPTIONAL_HEADER32)&remoteMappedImage.NtHeaders->OptionalHeader)->ImageBase != (ULONG_PTR)moduleItem->BaseAddress) moduleItem->Flags |= LDRP_IMAGE_NOT_AT_BASE; moduleItem->ImageDllCharacteristics = ((PIMAGE_OPTIONAL_HEADER32)&remoteMappedImage.NtHeaders->OptionalHeader)->DllCharacteristics; } else if (remoteMappedImage.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { if ((ULONG_PTR)((PIMAGE_OPTIONAL_HEADER64)&remoteMappedImage.NtHeaders->OptionalHeader)->ImageBase != (ULONG_PTR)moduleItem->BaseAddress) moduleItem->Flags |= LDRP_IMAGE_NOT_AT_BASE; moduleItem->ImageDllCharacteristics = ((PIMAGE_OPTIONAL_HEADER64)&remoteMappedImage.NtHeaders->OptionalHeader)->DllCharacteristics; } PhUnloadRemoteMappedImage(&remoteMappedImage); } } if (moduleItem->Type == PH_MODULE_TYPE_MODULE || moduleItem->Type == PH_MODULE_TYPE_KERNEL_MODULE || moduleItem->Type == PH_MODULE_TYPE_WOW64_MODULE || moduleItem->Type == PH_MODULE_TYPE_MAPPED_IMAGE) { // See if the file has already been verified; if not, queue for verification. moduleItem->VerifyResult = PhVerifyFileCached(moduleItem->FileName, &moduleItem->VerifySignerName, TRUE); if (moduleItem->VerifyResult == VrUnknown) PhpQueueModuleQuery(moduleProvider, moduleItem); } // Add the module item to the hashtable. PhAcquireFastLockExclusive(&moduleProvider->ModuleHashtableLock); PhAddEntryHashtable(moduleProvider->ModuleHashtable, &moduleItem); PhReleaseFastLockExclusive(&moduleProvider->ModuleHashtableLock); // Raise the module added event. PhInvokeCallback(&moduleProvider->ModuleAddedEvent, moduleItem); } else { BOOLEAN modified = FALSE; if (moduleItem->JustProcessed) modified = TRUE; moduleItem->JustProcessed = FALSE; if (modified) PhInvokeCallback(&moduleProvider->ModuleModifiedEvent, moduleItem); PhDereferenceObject(moduleItem); } } // Free the modules list. for (i = 0; i < modules->Count; i++) { PPH_MODULE_INFO module = modules->Items[i]; PhDereferenceObject(module->Name); PhDereferenceObject(module->FileName); PhFree(module); } PhDereferenceObject(modules); PhInvokeCallback(&moduleProvider->UpdatedEvent, NULL); }
static NTSTATUS PhpFindObjectsThreadStart( __in PVOID Parameter ) { PSYSTEM_HANDLE_INFORMATION_EX handles; PPH_HASHTABLE processHandleHashtable; PVOID processes; PSYSTEM_PROCESS_INFORMATION process; ULONG i; // Refuse to search with no filter. if (SearchString->Length == 0) goto Exit; // Try to get a search pointer from the search string. UseSearchPointer = PhStringToInteger64(&SearchString->sr, 0, &SearchPointer); PhUpperString(SearchString); if (NT_SUCCESS(PhEnumHandlesEx(&handles))) { processHandleHashtable = PhCreateSimpleHashtable(8); for (i = 0; i < handles->NumberOfHandles; i++) { PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = &handles->Handles[i]; PPVOID processHandlePtr; HANDLE processHandle; PPH_STRING typeName; PPH_STRING bestObjectName; if (SearchStop) break; // Open a handle to the process if we don't already have one. processHandlePtr = PhFindItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId ); if (processHandlePtr) { processHandle = (HANDLE)*processHandlePtr; } else { if (NT_SUCCESS(PhOpenProcess( &processHandle, PROCESS_DUP_HANDLE, (HANDLE)handleInfo->UniqueProcessId ))) { PhAddItemSimpleHashtable( processHandleHashtable, (PVOID)handleInfo->UniqueProcessId, processHandle ); } else { continue; } } // Get handle information. if (NT_SUCCESS(PhGetHandleInformation( processHandle, (HANDLE)handleInfo->HandleValue, handleInfo->ObjectTypeIndex, NULL, &typeName, NULL, &bestObjectName ))) { PPH_STRING upperBestObjectName; upperBestObjectName = PhDuplicateString(bestObjectName); PhUpperString(upperBestObjectName); if ( PhFindStringInString(upperBestObjectName, 0, SearchString->Buffer) != -1 || (UseSearchPointer && handleInfo->Object == (PVOID)SearchPointer) ) { PPHP_OBJECT_SEARCH_RESULT searchResult; searchResult = PhAllocate(sizeof(PHP_OBJECT_SEARCH_RESULT)); searchResult->ProcessId = (HANDLE)handleInfo->UniqueProcessId; searchResult->ResultType = HandleSearchResult; searchResult->Handle = (HANDLE)handleInfo->HandleValue; searchResult->TypeName = typeName; searchResult->Name = bestObjectName; PhPrintPointer(searchResult->HandleString, (PVOID)searchResult->Handle); searchResult->Info = *handleInfo; PhAcquireQueuedLockExclusive(&SearchResultsLock); PhAddItemList(SearchResults, searchResult); // Update the search results in batches of 40. if (SearchResults->Count % 40 == 0) PostMessage(PhFindObjectsWindowHandle, WM_PH_SEARCH_UPDATE, 0, 0); PhReleaseQueuedLockExclusive(&SearchResultsLock); } else { PhDereferenceObject(typeName); PhDereferenceObject(bestObjectName); } PhDereferenceObject(upperBestObjectName); } } { PPH_KEY_VALUE_PAIR entry; i = 0; while (PhEnumHashtable(processHandleHashtable, &entry, &i)) NtClose((HANDLE)entry->Value); } PhDereferenceObject(processHandleHashtable); PhFree(handles); } if (NT_SUCCESS(PhEnumProcesses(&processes))) { process = PH_FIRST_PROCESS(processes); do { PhEnumGenericModules( process->UniqueProcessId, NULL, PH_ENUM_GENERIC_MAPPED_FILES | PH_ENUM_GENERIC_MAPPED_IMAGES, EnumModulesCallback, (PVOID)process->UniqueProcessId ); } while (process = PH_NEXT_PROCESS(process)); PhFree(processes); } Exit: PostMessage(PhFindObjectsWindowHandle, WM_PH_SEARCH_FINISHED, 0, 0); return STATUS_SUCCESS; }
NTSTATUS PhpThreadProviderLoadSymbols( __in PVOID Parameter ) { PPH_THREAD_PROVIDER threadProvider = (PPH_THREAD_PROVIDER)Parameter; PH_THREAD_SYMBOL_LOAD_CONTEXT loadContext; loadContext.ThreadProvider = threadProvider; loadContext.SymbolProvider = threadProvider->SymbolProvider; PhLoadSymbolProviderOptions(threadProvider->SymbolProvider); if (threadProvider->ProcessId != SYSTEM_IDLE_PROCESS_ID) { if ( threadProvider->SymbolProvider->IsRealHandle || threadProvider->ProcessId == SYSTEM_PROCESS_ID ) { loadContext.ProcessId = threadProvider->ProcessId; PhEnumGenericModules( threadProvider->ProcessId, threadProvider->SymbolProvider->ProcessHandle, 0, LoadSymbolsEnumGenericModulesCallback, &loadContext ); } else { // We can't enumerate the process modules. Load // symbols for ntdll.dll and kernel32.dll. loadContext.ProcessId = NtCurrentProcessId(); PhEnumGenericModules( NtCurrentProcessId(), NtCurrentProcess(), 0, LoadBasicSymbolsEnumGenericModulesCallback, &loadContext ); } // Load kernel module symbols as well. if (threadProvider->ProcessId != SYSTEM_PROCESS_ID) { loadContext.ProcessId = SYSTEM_PROCESS_ID; PhEnumGenericModules( SYSTEM_PROCESS_ID, NULL, 0, LoadSymbolsEnumGenericModulesCallback, &loadContext ); } } else { // System Idle Process has one thread for each CPU, // each having a start address at KiIdleLoop. We // need to load symbols for the kernel. PRTL_PROCESS_MODULES kernelModules; if (NT_SUCCESS(PhEnumKernelModules(&kernelModules))) { if (kernelModules->NumberOfModules > 0) { PPH_STRING fileName; PPH_STRING newFileName; fileName = PhCreateStringFromAnsi(kernelModules->Modules[0].FullPathName); newFileName = PhGetFileName(fileName); PhDereferenceObject(fileName); PhLoadModuleSymbolProvider( threadProvider->SymbolProvider, newFileName->Buffer, (ULONG64)kernelModules->Modules[0].ImageBase, kernelModules->Modules[0].ImageSize ); PhDereferenceObject(newFileName); } PhFree(kernelModules); } } // Check if the process has services - we'll need to know before getting service tag/name // information. if (WINDOWS_HAS_SERVICE_TAGS) { PPH_PROCESS_ITEM processItem; if (processItem = PhReferenceProcessItem(threadProvider->ProcessId)) { threadProvider->HasServices = processItem->ServiceList && processItem->ServiceList->Count != 0; PhDereferenceObject(processItem); } } PhSetEvent(&threadProvider->SymbolsLoadedEvent); PhDereferenceObject(threadProvider); return STATUS_SUCCESS; }
INT_PTR CALLBACK EtpWsWatchDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { PWS_WATCH_CONTEXT context; if (uMsg == WM_INITDIALOG) { context = (PWS_WATCH_CONTEXT)lParam; SetProp(hwndDlg, L"Context", (HANDLE)context); } else { context = (PWS_WATCH_CONTEXT)GetProp(hwndDlg, L"Context"); if (uMsg == WM_DESTROY) RemoveProp(hwndDlg, L"Context"); } if (!context) return FALSE; switch (uMsg) { case WM_INITDIALOG: { HWND lvHandle; PhCenterWindow(hwndDlg, GetParent(hwndDlg)); context->WindowHandle = hwndDlg; context->ListViewHandle = lvHandle = GetDlgItem(hwndDlg, IDC_LIST); PhSetListViewStyle(lvHandle, FALSE, TRUE); PhSetControlTheme(lvHandle, L"explorer"); PhAddListViewColumn(lvHandle, 0, 0, 0, LVCFMT_LEFT, 340, L"Instruction"); PhAddListViewColumn(lvHandle, 1, 1, 1, LVCFMT_LEFT, 80, L"Count"); PhSetExtendedListView(lvHandle); ExtendedListView_SetSort(lvHandle, 1, DescendingSortOrder); context->Hashtable = PhCreateSimpleHashtable(64); context->BufferSize = 0x2000; context->Buffer = PhAllocate(context->BufferSize); PhInitializeQueuedLock(&context->ResultListLock); context->SymbolProvider = PhCreateSymbolProvider(context->ProcessItem->ProcessId); PhLoadSymbolProviderOptions(context->SymbolProvider); if (!context->SymbolProvider || !context->SymbolProvider->IsRealHandle) { PhShowError(hwndDlg, L"Unable to open the process."); EndDialog(hwndDlg, IDCANCEL); break; } context->ProcessHandle = context->SymbolProvider->ProcessHandle; // Load symbols for both process and kernel modules. context->LoadingSymbolsForProcessId = context->ProcessItem->ProcessId; PhEnumGenericModules( NULL, context->ProcessHandle, 0, EnumGenericModulesCallback, context ); context->LoadingSymbolsForProcessId = SYSTEM_PROCESS_ID; PhEnumGenericModules( SYSTEM_PROCESS_ID, NULL, 0, EnumGenericModulesCallback, context ); context->Enabled = EtpUpdateWsWatch(hwndDlg, context); if (context->Enabled) { // WS Watch is already enabled for the process. Enable updating. EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE), FALSE); ShowWindow(GetDlgItem(hwndDlg, IDC_WSWATCHENABLED), SW_SHOW); SetTimer(hwndDlg, 1, 1000, NULL); } else { // WS Watch has not yet been enabled for the process. } } break; case WM_DESTROY: { context->Destroying = TRUE; PhDereferenceObject(context->Hashtable); if (context->Buffer) { PhFree(context->Buffer); context->Buffer = NULL; } } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: case IDOK: EndDialog(hwndDlg, IDOK); break; case IDC_ENABLE: { NTSTATUS status; HANDLE processHandle; if (NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_SET_INFORMATION, context->ProcessItem->ProcessId ))) { status = NtSetInformationProcess( processHandle, ProcessWorkingSetWatchEx, NULL, 0 ); NtClose(processHandle); } if (NT_SUCCESS(status)) { EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE), FALSE); ShowWindow(GetDlgItem(hwndDlg, IDC_WSWATCHENABLED), SW_SHOW); SetTimer(hwndDlg, 1, 1000, NULL); } else { PhShowStatus(hwndDlg, L"Unable to enable WS watch", status, 0); } } break; } } break; case WM_NOTIFY: { PhHandleListViewNotifyForCopy(lParam, context->ListViewHandle); } break; case WM_TIMER: { switch (wParam) { case 1: { EtpUpdateWsWatch(hwndDlg, context); } break; } } break; } return FALSE; }
VOID PhLoadSymbolsThreadProvider( _In_ PPH_THREAD_PROVIDER ThreadProvider ) { PH_THREAD_SYMBOL_LOAD_CONTEXT loadContext; ULONG64 runId; loadContext.ThreadProvider = ThreadProvider; loadContext.SymbolProvider = ThreadProvider->SymbolProvider; PhAcquireQueuedLockExclusive(&ThreadProvider->LoadSymbolsLock); runId = ThreadProvider->RunId; PhLoadSymbolProviderOptions(ThreadProvider->SymbolProvider); if (ThreadProvider->ProcessId != SYSTEM_IDLE_PROCESS_ID) { if (ThreadProvider->SymbolProvider->IsRealHandle || ThreadProvider->ProcessId == SYSTEM_PROCESS_ID) { loadContext.ProcessId = ThreadProvider->ProcessId; PhEnumGenericModules( ThreadProvider->ProcessId, ThreadProvider->SymbolProvider->ProcessHandle, 0, LoadSymbolsEnumGenericModulesCallback, &loadContext ); } else { // We can't enumerate the process modules. Load // symbols for ntdll.dll and kernel32.dll. loadContext.ProcessId = NtCurrentProcessId(); PhEnumGenericModules( NtCurrentProcessId(), NtCurrentProcess(), 0, LoadBasicSymbolsEnumGenericModulesCallback, &loadContext ); } // Load kernel module symbols as well. if (ThreadProvider->ProcessId != SYSTEM_PROCESS_ID) { loadContext.ProcessId = SYSTEM_PROCESS_ID; PhEnumGenericModules( SYSTEM_PROCESS_ID, NULL, 0, LoadSymbolsEnumGenericModulesCallback, &loadContext ); } } else { // System Idle Process has one thread for each CPU, // each having a start address at KiIdleLoop. We // need to load symbols for the kernel. PRTL_PROCESS_MODULES kernelModules; if (NT_SUCCESS(PhEnumKernelModules(&kernelModules))) { if (kernelModules->NumberOfModules > 0) { PPH_STRING fileName; PPH_STRING newFileName; fileName = PhConvertMultiByteToUtf16(kernelModules->Modules[0].FullPathName); newFileName = PhGetFileName(fileName); PhDereferenceObject(fileName); PhLoadModuleSymbolProvider( ThreadProvider->SymbolProvider, newFileName->Buffer, (ULONG64)kernelModules->Modules[0].ImageBase, kernelModules->Modules[0].ImageSize ); PhDereferenceObject(newFileName); } PhFree(kernelModules); } } ThreadProvider->SymbolsLoadedRunId = runId; PhReleaseQueuedLockExclusive(&ThreadProvider->LoadSymbolsLock); }
INT_PTR CALLBACK EtpTpWorkerFactoryPageDlgProc( __in HWND hwndDlg, __in UINT uMsg, __in WPARAM wParam, __in LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { LPPROPSHEETPAGE propSheetPage = (LPPROPSHEETPAGE)lParam; PCOMMON_PAGE_CONTEXT context = (PCOMMON_PAGE_CONTEXT)propSheetPage->lParam; HANDLE workerFactoryHandle; if (NT_SUCCESS(EtpDuplicateHandleFromProcess(&workerFactoryHandle, WORKER_FACTORY_QUERY_INFORMATION, context))) { WORKER_FACTORY_BASIC_INFORMATION basicInfo; if (NT_SUCCESS(NtQueryInformationWorkerFactory( workerFactoryHandle, WorkerFactoryBasicInformation, &basicInfo, sizeof(WORKER_FACTORY_BASIC_INFORMATION), NULL ))) { PPH_SYMBOL_PROVIDER symbolProvider; PPH_STRING symbol = NULL; symbolProvider = PhCreateSymbolProvider(basicInfo.ProcessId); PhLoadSymbolProviderOptions(symbolProvider); if (symbolProvider->IsRealHandle) { PhEnumGenericModules(basicInfo.ProcessId, symbolProvider->ProcessHandle, 0, EnumGenericModulesCallback, symbolProvider); symbol = PhGetSymbolFromAddress(symbolProvider, (ULONG64)basicInfo.StartRoutine, NULL, NULL, NULL, NULL); } PhDereferenceObject(symbolProvider); if (symbol) { SetDlgItemText(hwndDlg, IDC_WORKERTHREADSTART, PhaFormatString(L"Worker Thread Start: %s", symbol->Buffer)->Buffer); PhDereferenceObject(symbol); } else { SetDlgItemText(hwndDlg, IDC_WORKERTHREADSTART, PhaFormatString(L"Worker Thread Start: 0x%Ix", basicInfo.StartRoutine)->Buffer); } SetDlgItemText(hwndDlg, IDC_WORKERTHREADCONTEXT, PhaFormatString(L"Worker Thread Context: 0x%Ix", basicInfo.StartParameter)->Buffer); } NtClose(workerFactoryHandle); } } break; } return FALSE; }