PPH_MODULE_PROVIDER PhCreateModuleProvider( __in HANDLE ProcessId ) { PPH_MODULE_PROVIDER moduleProvider; if (!NT_SUCCESS(PhCreateObject( &moduleProvider, sizeof(PH_MODULE_PROVIDER), 0, PhModuleProviderType ))) return NULL; moduleProvider->ModuleHashtable = PhCreateHashtable( sizeof(PPH_MODULE_ITEM), PhpModuleHashtableCompareFunction, PhpModuleHashtableHashFunction, 20 ); PhInitializeFastLock(&moduleProvider->ModuleHashtableLock); PhInitializeCallback(&moduleProvider->ModuleAddedEvent); PhInitializeCallback(&moduleProvider->ModuleModifiedEvent); PhInitializeCallback(&moduleProvider->ModuleRemovedEvent); PhInitializeCallback(&moduleProvider->UpdatedEvent); moduleProvider->ProcessId = ProcessId; moduleProvider->ProcessHandle = NULL; // It doesn't matter if we can't get a process handle. // Try to get a handle with query information + vm read access. if (!NT_SUCCESS(PhOpenProcess( &moduleProvider->ProcessHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, ProcessId ))) { if (WINDOWS_HAS_LIMITED_ACCESS) { // Try to get a handle with query limited information + vm read access. PhOpenProcess( &moduleProvider->ProcessHandle, PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, ProcessId ); } } RtlInitializeSListHead(&moduleProvider->QueryListHead); return moduleProvider; }
PPH_THREAD_PROVIDER PhCreateThreadProvider( __in HANDLE ProcessId ) { PPH_THREAD_PROVIDER threadProvider; if (!NT_SUCCESS(PhCreateObject( &threadProvider, sizeof(PH_THREAD_PROVIDER), 0, PhThreadProviderType ))) return NULL; threadProvider->ThreadHashtable = PhCreateHashtable( sizeof(PPH_THREAD_ITEM), PhpThreadHashtableCompareFunction, PhpThreadHashtableHashFunction, 20 ); PhInitializeFastLock(&threadProvider->ThreadHashtableLock); PhInitializeCallback(&threadProvider->ThreadAddedEvent); PhInitializeCallback(&threadProvider->ThreadModifiedEvent); PhInitializeCallback(&threadProvider->ThreadRemovedEvent); PhInitializeCallback(&threadProvider->UpdatedEvent); PhInitializeCallback(&threadProvider->LoadingStateChangedEvent); threadProvider->ProcessId = ProcessId; threadProvider->SymbolProvider = PhCreateSymbolProvider(ProcessId); if (threadProvider->SymbolProvider) { if (threadProvider->SymbolProvider->IsRealHandle) threadProvider->ProcessHandle = threadProvider->SymbolProvider->ProcessHandle; } PhInitializeEvent(&threadProvider->SymbolsLoadedEvent); threadProvider->SymbolsLoading = 0; RtlInitializeSListHead(&threadProvider->QueryListHead); threadProvider->RunId = 1; // Begin loading symbols for the process' modules. PhReferenceObject(threadProvider); PhpQueueThreadWorkQueueItem(PhpThreadProviderLoadSymbols, threadProvider); return threadProvider; }
PPH_THREAD_PROVIDER PhCreateThreadProvider( _In_ HANDLE ProcessId ) { PPH_THREAD_PROVIDER threadProvider; threadProvider = PhCreateObject( PhEmGetObjectSize(EmThreadProviderType, sizeof(PH_THREAD_PROVIDER)), PhThreadProviderType ); memset(threadProvider, 0, sizeof(PH_THREAD_PROVIDER)); threadProvider->ThreadHashtable = PhCreateHashtable( sizeof(PPH_THREAD_ITEM), PhpThreadHashtableEqualFunction, PhpThreadHashtableHashFunction, 20 ); PhInitializeFastLock(&threadProvider->ThreadHashtableLock); PhInitializeCallback(&threadProvider->ThreadAddedEvent); PhInitializeCallback(&threadProvider->ThreadModifiedEvent); PhInitializeCallback(&threadProvider->ThreadRemovedEvent); PhInitializeCallback(&threadProvider->UpdatedEvent); PhInitializeCallback(&threadProvider->LoadingStateChangedEvent); threadProvider->ProcessId = ProcessId; threadProvider->SymbolProvider = PhCreateSymbolProvider(ProcessId); if (threadProvider->SymbolProvider) { if (threadProvider->SymbolProvider->IsRealHandle) threadProvider->ProcessHandle = threadProvider->SymbolProvider->ProcessHandle; } RtlInitializeSListHead(&threadProvider->QueryListHead); PhInitializeQueuedLock(&threadProvider->LoadSymbolsLock); threadProvider->RunId = 1; threadProvider->SymbolsLoadedRunId = 0; // Force symbols to be loaded the first time we try to resolve an address PhEmCallObjectOperation(EmThreadProviderType, threadProvider, EmObjectCreate); return threadProvider; }
VOID PhPluginsInitialization( VOID ) { ULONG i; for (i = 0; i < GeneralCallbackMaximum; i++) PhInitializeCallback(&GeneralCallbacks[i]); }
PPH_HANDLE_PROVIDER PhCreateHandleProvider( __in HANDLE ProcessId ) { PPH_HANDLE_PROVIDER handleProvider; if (!NT_SUCCESS(PhCreateObject( &handleProvider, sizeof(PH_HANDLE_PROVIDER), 0, PhHandleProviderType ))) return NULL; handleProvider->HandleHashSetSize = 128; handleProvider->HandleHashSet = PhCreateHashSet(handleProvider->HandleHashSetSize); handleProvider->HandleHashSetCount = 0; PhInitializeQueuedLock(&handleProvider->HandleHashSetLock); PhInitializeCallback(&handleProvider->HandleAddedEvent); PhInitializeCallback(&handleProvider->HandleModifiedEvent); PhInitializeCallback(&handleProvider->HandleRemovedEvent); PhInitializeCallback(&handleProvider->UpdatedEvent); handleProvider->ProcessId = ProcessId; handleProvider->ProcessHandle = NULL; PhOpenProcess( &handleProvider->ProcessHandle, PROCESS_DUP_HANDLE, ProcessId ); handleProvider->TempListHashtable = PhCreateSimpleHashtable(20); return handleProvider; }
/** * Registers a plugin with the host. * * \param Name A unique identifier for the plugin. The function fails * if another plugin has already been registered with the same name. The * name must only contain alphanumeric characters, spaces, dots and * underscores. * \param DllBase The base address of the plugin DLL. This is passed * to the DllMain function. * \param Information A variable which receives a pointer to the * plugin's additional information block. This should be filled in after * the function returns. * * \return A pointer to the plugin instance structure, or NULL if the * function failed. */ PPH_PLUGIN PhRegisterPlugin( _In_ PWSTR Name, _In_ PVOID DllBase, _Out_opt_ PPH_PLUGIN_INFORMATION *Information ) { PPH_PLUGIN plugin; PH_STRINGREF pluginName; PPH_AVL_LINKS existingLinks; ULONG i; PPH_STRING fileName; PhInitializeStringRefLongHint(&pluginName, Name); if (!PhpValidatePluginName(&pluginName)) return NULL; fileName = PhGetDllFileName(DllBase, NULL); if (!fileName) return NULL; plugin = PhAllocate(sizeof(PH_PLUGIN)); memset(plugin, 0, sizeof(PH_PLUGIN)); plugin->Name = pluginName; plugin->DllBase = DllBase; plugin->FileName = fileName; existingLinks = PhAddElementAvlTree(&PhPluginsByName, &plugin->Links); if (existingLinks) { // Another plugin has already been registered with the same name. PhFree(plugin); return NULL; } for (i = 0; i < PluginCallbackMaximum; i++) PhInitializeCallback(&plugin->Callbacks[i]); PhEmInitializeAppContext(&plugin->AppContext, &pluginName); if (Information) *Information = &plugin->Information; return plugin; }
PPH_HANDLE_PROVIDER PhCreateHandleProvider( _In_ HANDLE ProcessId ) { PPH_HANDLE_PROVIDER handleProvider; handleProvider = PhCreateObject( PhEmGetObjectSize(EmHandleProviderType, sizeof(PH_HANDLE_PROVIDER)), PhHandleProviderType ); handleProvider->HandleHashSetSize = 128; handleProvider->HandleHashSet = PhCreateHashSet(handleProvider->HandleHashSetSize); handleProvider->HandleHashSetCount = 0; PhInitializeQueuedLock(&handleProvider->HandleHashSetLock); PhInitializeCallback(&handleProvider->HandleAddedEvent); PhInitializeCallback(&handleProvider->HandleModifiedEvent); PhInitializeCallback(&handleProvider->HandleRemovedEvent); PhInitializeCallback(&handleProvider->UpdatedEvent); handleProvider->ProcessId = ProcessId; handleProvider->ProcessHandle = NULL; handleProvider->RunStatus = PhOpenProcess( &handleProvider->ProcessHandle, PROCESS_DUP_HANDLE, ProcessId ); handleProvider->TempListHashtable = PhCreateSimpleHashtable(20); PhEmCallObjectOperation(EmHandleProviderType, handleProvider, EmObjectCreate); return handleProvider; }
VOID PhPluginsInitialization( VOID ) { ULONG i; for (i = 0; i < GeneralCallbackMaximum; i++) PhInitializeCallback(&GeneralCallbacks[i]); if (WindowsVersion <= WINDOWS_XP) { PH_STRINGREF extendedTools = PH_STRINGREF_INIT(L"ExtendedTools.dll"); // HACK and violation of abstraction. // Always disable ExtendedTools on XP to avoid the annoying error message. PhSetPluginDisabled(&extendedTools, TRUE); } }
PPH_SYMBOL_PROVIDER PhCreateSymbolProvider( _In_opt_ HANDLE ProcessId ) { PPH_SYMBOL_PROVIDER symbolProvider; if (!NT_SUCCESS(PhCreateObject( &symbolProvider, sizeof(PH_SYMBOL_PROVIDER), 0, PhSymbolProviderType ))) return NULL; InitializeListHead(&symbolProvider->ModulesListHead); PhInitializeQueuedLock(&symbolProvider->ModulesListLock); PhInitializeAvlTree(&symbolProvider->ModulesSet, PhpSymbolModuleCompareFunction); PhInitializeCallback(&symbolProvider->EventCallback); if (ProcessId) { static ACCESS_MASK accesses[] = { STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xfff, // pre-Vista full access PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_DUP_HANDLE, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, MAXIMUM_ALLOWED }; ULONG i; symbolProvider->IsRealHandle = FALSE; // Try to open the process with many different accesses. // This handle will be re-used when walking stacks, and doing // various other things. for (i = 0; i < sizeof(accesses) / sizeof(ACCESS_MASK); i++) { if (NT_SUCCESS(PhOpenProcess(&symbolProvider->ProcessHandle, accesses[i], ProcessId))) { symbolProvider->IsRealHandle = TRUE; break; } } } else { symbolProvider->IsRealHandle = FALSE; } if (!symbolProvider->IsRealHandle) { HANDLE fakeHandle; // Just generate a fake handle. fakeHandle = (HANDLE)_InterlockedExchangeAddPointer((PLONG_PTR)&PhNextFakeHandle, 4); // Add one to make sure it isn't divisible // by 4 (so it can't be mistaken for a real // handle). fakeHandle = (HANDLE)((ULONG_PTR)fakeHandle + 1); symbolProvider->ProcessHandle = fakeHandle; } symbolProvider->IsRegistered = FALSE; #ifdef PH_SYMBOL_PROVIDER_DELAY_INIT PhInitializeInitOnce(&symbolProvider->InitOnce); #else PhpRegisterSymbolProvider(symbolProvider); #endif return symbolProvider; }
PPH_MODULE_PROVIDER PhCreateModuleProvider( _In_ HANDLE ProcessId ) { NTSTATUS status; PPH_MODULE_PROVIDER moduleProvider; moduleProvider = PhCreateObject( PhEmGetObjectSize(EmModuleProviderType, sizeof(PH_MODULE_PROVIDER)), PhModuleProviderType ); moduleProvider->ModuleHashtable = PhCreateHashtable( sizeof(PPH_MODULE_ITEM), PhpModuleHashtableEqualFunction, PhpModuleHashtableHashFunction, 20 ); PhInitializeFastLock(&moduleProvider->ModuleHashtableLock); PhInitializeCallback(&moduleProvider->ModuleAddedEvent); PhInitializeCallback(&moduleProvider->ModuleModifiedEvent); PhInitializeCallback(&moduleProvider->ModuleRemovedEvent); PhInitializeCallback(&moduleProvider->UpdatedEvent); moduleProvider->ProcessId = ProcessId; moduleProvider->ProcessHandle = NULL; moduleProvider->PackageFullName = NULL; moduleProvider->RunStatus = STATUS_SUCCESS; // It doesn't matter if we can't get a process handle. // Try to get a handle with query information + vm read access. if (!NT_SUCCESS(status = PhOpenProcess( &moduleProvider->ProcessHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, ProcessId ))) { if (WINDOWS_HAS_LIMITED_ACCESS) { // Try to get a handle with query limited information + vm read access. status = PhOpenProcess( &moduleProvider->ProcessHandle, PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, ProcessId ); } moduleProvider->RunStatus = status; } if (moduleProvider->ProcessHandle) moduleProvider->PackageFullName = PhGetProcessPackageFullName(moduleProvider->ProcessHandle); RtlInitializeSListHead(&moduleProvider->QueryListHead); PhEmCallObjectOperation(EmModuleProviderType, moduleProvider, EmObjectCreate); return moduleProvider; }