/** * 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; }
BOOLEAN PhLoadModuleSymbolProvider( _In_ PPH_SYMBOL_PROVIDER SymbolProvider, _In_ PWSTR FileName, _In_ ULONG64 BaseAddress, _In_ ULONG Size ) { PPH_ANSI_STRING fileName; ULONG64 baseAddress; if (!SymLoadModule64_I) return FALSE; #ifdef PH_SYMBOL_PROVIDER_DELAY_INIT PhpRegisterSymbolProvider(SymbolProvider); #endif fileName = PhCreateAnsiStringFromUnicode(FileName); if (!fileName) return FALSE; PH_LOCK_SYMBOLS(); baseAddress = SymLoadModule64_I( SymbolProvider->ProcessHandle, NULL, fileName->Buffer, NULL, BaseAddress, Size ); PH_UNLOCK_SYMBOLS(); PhDereferenceObject(fileName); // Add the module to the list, even if we couldn't load // symbols for the module. { PPH_SYMBOL_MODULE symbolModule = NULL; PPH_AVL_LINKS existingLinks; PH_SYMBOL_MODULE lookupSymbolModule; lookupSymbolModule.BaseAddress = BaseAddress; PhAcquireQueuedLockExclusive(&SymbolProvider->ModulesListLock); // Check for duplicates. existingLinks = PhFindElementAvlTree(&SymbolProvider->ModulesSet, &lookupSymbolModule.Links); if (!existingLinks) { symbolModule = PhAllocate(sizeof(PH_SYMBOL_MODULE)); symbolModule->BaseAddress = BaseAddress; symbolModule->Size = Size; symbolModule->FileName = PhGetFullPath(FileName, &symbolModule->BaseNameIndex); existingLinks = PhAddElementAvlTree(&SymbolProvider->ModulesSet, &symbolModule->Links); assert(!existingLinks); InsertTailList(&SymbolProvider->ModulesListHead, &symbolModule->ListEntry); } PhReleaseQueuedLockExclusive(&SymbolProvider->ModulesListLock); } if (!baseAddress) { if (GetLastError() != ERROR_SUCCESS) return FALSE; else return TRUE; } return TRUE; }
VOID PhShowMemoryEditorDialog( _In_ HANDLE ProcessId, _In_ PVOID BaseAddress, _In_ SIZE_T RegionSize, _In_ ULONG SelectOffset, _In_ ULONG SelectLength, _In_opt_ PPH_STRING Title, _In_ ULONG Flags ) { PMEMORY_EDITOR_CONTEXT context; MEMORY_EDITOR_CONTEXT lookupContext; PPH_AVL_LINKS links; lookupContext.ProcessId = ProcessId; lookupContext.BaseAddress = BaseAddress; lookupContext.RegionSize = RegionSize; links = PhFindElementAvlTree(&PhMemoryEditorSet, &lookupContext.Links); if (!links) { context = PhAllocate(sizeof(MEMORY_EDITOR_CONTEXT)); memset(context, 0, sizeof(MEMORY_EDITOR_CONTEXT)); context->ProcessId = ProcessId; context->BaseAddress = BaseAddress; context->RegionSize = RegionSize; context->SelectOffset = SelectOffset; PhSwapReference(&context->Title, Title); context->Flags = Flags; context->WindowHandle = CreateDialogParam( PhInstanceHandle, MAKEINTRESOURCE(IDD_MEMEDIT), NULL, PhpMemoryEditorDlgProc, (LPARAM)context ); if (!context->LoadCompleted) { DestroyWindow(context->WindowHandle); return; } if (SelectOffset != -1) PostMessage(context->WindowHandle, WM_PH_SELECT_OFFSET, SelectOffset, SelectLength); PhRegisterDialog(context->WindowHandle); PhAddElementAvlTree(&PhMemoryEditorSet, &context->Links); ShowWindow(context->WindowHandle, SW_SHOW); } else { context = CONTAINING_RECORD(links, MEMORY_EDITOR_CONTEXT, Links); if (IsIconic(context->WindowHandle)) ShowWindow(context->WindowHandle, SW_RESTORE); else SetForegroundWindow(context->WindowHandle); if (SelectOffset != -1) PostMessage(context->WindowHandle, WM_PH_SELECT_OFFSET, SelectOffset, SelectLength); // Just in case. if ((Flags & PH_MEMORY_EDITOR_UNMAP_VIEW_OF_SECTION) && ProcessId == NtCurrentProcessId()) NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress); } }