diff --git a/CMakeLists.txt b/CMakeLists.txt index da522c08f..fa203d130 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -641,7 +641,7 @@ elseif(WIN32) src/detection/users/users_windows.c src/detection/wallpaper/wallpaper_windows.c src/detection/wifi/wifi_windows.c - src/detection/wm/wm_nosupport.c + src/detection/wm/wm_windows.cpp src/detection/de/de_nosupport.c src/detection/wmtheme/wmtheme_windows.c src/util/windows/getline.c diff --git a/src/detection/terminalshell/terminalshell_windows.c b/src/detection/terminalshell/terminalshell_windows.c index 746ba32a7..06ef8c573 100644 --- a/src/detection/terminalshell/terminalshell_windows.c +++ b/src/detection/terminalshell/terminalshell_windows.c @@ -130,7 +130,7 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) { ffStrbufClear(&result->shellPrettyName); - HANDLE snapshot; + FF_AUTO_CLOSE_FD HANDLE snapshot = NULL; while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid)) && GetLastError() == ERROR_BAD_LENGTH) {} if(snapshot) @@ -147,7 +147,6 @@ static uint32_t getShellInfo(FFTerminalShellResult* result, uint32_t pid) break; } } - CloseHandle(snapshot); } if(result->shellPrettyName.length == 0) ffStrbufAppendS(&result->shellPrettyName, "Command Prompt"); diff --git a/src/detection/wm/wm_windows.cpp b/src/detection/wm/wm_windows.cpp new file mode 100644 index 000000000..941052830 --- /dev/null +++ b/src/detection/wm/wm_windows.cpp @@ -0,0 +1,66 @@ +extern "C" +{ +#include "wm.h" +#include "common/io/io.h" +#include "detection/terminalshell/terminalshell.h" +} + +#include "util/windows/com.hpp" + +#include +#include +#include +#include +#include + +template +struct on_scope_exit { + on_scope_exit(Fn &&fn): _fn(std::move(fn)) {} + ~on_scope_exit() { this->_fn(); } + +private: + Fn _fn; +}; + +extern "C" +const char* ffDetectWMPlugin(FFstrbuf* pluginName) +{ + DWORD pid = ffDetectTerminalShell()->terminalPid; // Whatever GUI program + if (pid == 0) return "Unable to find a GUI program"; + + FF_AUTO_CLOSE_FD HANDLE snapshot = NULL; + while(!(snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid)) && GetLastError() == ERROR_BAD_LENGTH) {} + + if(!snapshot) + return "CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid) failed"; + + if (ffInitCom()) + return "ffInitCom() failed"; + + MODULEENTRY32W module; + module.dwSize = sizeof(module); + for(BOOL success = Module32FirstW(snapshot, &module); success; success = Module32NextW(snapshot, &module)) + { + if(wcscmp(module.szModule, L"wbhelp64.dll") == 0 || wcscmp(module.szModule, L"wbhelp.dll") == 0) + { + IShellItem2* shellItem = NULL; + if (FAILED(SHCreateItemFromParsingName(module.szExePath, NULL, IID_IShellItem2, (void**) &shellItem))) + continue; + + on_scope_exit destroyShellItem([=] { shellItem->Release(); }); + + wchar_t* desc = NULL; + if (FAILED(shellItem->GetString(PKEY_FileDescription, &desc))) + continue; + + on_scope_exit destroyDesc([=] { CoTaskMemFree(desc); }); + + if (wcscmp(desc, L"WindowBlinds Helper DLL") == 0) + { + ffStrbufSetStatic(pluginName, "WindowBlinds"); + break; + } + } + } + return NULL; +} diff --git a/src/modules/wm/wm.c b/src/modules/wm/wm.c index 460eea4f4..0e2811c96 100644 --- a/src/modules/wm/wm.c +++ b/src/modules/wm/wm.c @@ -5,7 +5,7 @@ #include "modules/wm/wm.h" #include "util/stringUtils.h" -#define FF_WM_NUM_FORMAT_ARGS 3 +#define FF_WM_NUM_FORMAT_ARGS 4 void ffPrintWM(FFWMOptions* options) { @@ -48,7 +48,8 @@ void ffPrintWM(FFWMOptions* options) ffPrintFormat(FF_WM_MODULE_NAME, 0, &options->moduleArgs, FF_WM_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProcessName}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmPrettyName}, - {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProtocolName} + {FF_FORMAT_ARG_TYPE_STRBUF, &result->wmProtocolName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &pluginName}, }); } } @@ -112,10 +113,16 @@ void ffGenerateWMJsonResult(FF_MAYBE_UNUSED FFWMOptions* options, yyjson_mut_doc yyjson_mut_obj_add_str(doc, module, "error", "No WM found"); return; } + + FF_STRBUF_AUTO_DESTROY pluginName = ffStrbufCreate(); + if(options->detectPlugin) + ffDetectWMPlugin(&pluginName); + yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result"); yyjson_mut_obj_add_strbuf(doc, obj, "processName", &result->wmProcessName); yyjson_mut_obj_add_strbuf(doc, obj, "prettyName", &result->wmPrettyName); yyjson_mut_obj_add_strbuf(doc, obj, "protocolName", &result->wmProtocolName); + yyjson_mut_obj_add_strbuf(doc, obj, "pluginName", &pluginName); } void ffPrintWMHelpFormat(void) @@ -123,7 +130,8 @@ void ffPrintWMHelpFormat(void) ffPrintModuleFormatHelp(FF_WM_MODULE_NAME, "{2} ({3})", FF_WM_NUM_FORMAT_ARGS, (const char* []) { "WM process name", "WM pretty name", - "WM protocol name" + "WM protocol name", + "WM plugin name" }); }