Created
March 29, 2025 12:37
-
-
Save m417z/eb4a08082f4a5efc027c5e9baf35a8e8 to your computer and use it in GitHub Desktop.
This mod logs Taskbar.View.dll load events for testing - for https://github.com/ramensoftware/windhawk-mods/issues/1724
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==WindhawkMod== | |
// @id taskbar-view-dll-load-logger | |
// @name Taskbar.View.dll load logger | |
// @description This mod logs Taskbar.View.dll load events for testing | |
// @version 0.1 | |
// @author m417z | |
// @github https://github.com/m417z | |
// @twitter https://twitter.com/m417z | |
// @homepage https://m417z.com/ | |
// @include explorer.exe | |
// @compilerOptions -ldbghelp -lshlwapi -lversion | |
// @architecture x86-64 | |
// ==/WindhawkMod== | |
// ==WindhawkModReadme== | |
/* | |
# Taskbar.View.dll load logger | |
This mod logs Taskbar.View.dll load events for testing. | |
*/ | |
// ==/WindhawkModReadme== | |
#include <windhawk_utils.h> | |
#include <dbghelp.h> | |
#include <shlwapi.h> | |
#include <algorithm> | |
#include <cctype> | |
#include <sstream> | |
#include <string> | |
#include <string_view> | |
using namespace std::string_view_literals; | |
VS_FIXEDFILEINFO* GetModuleVersionInfo(HMODULE hModule, UINT* puPtrLen) { | |
void* pFixedFileInfo = nullptr; | |
UINT uPtrLen = 0; | |
HRSRC hResource = | |
FindResource(hModule, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION); | |
if (hResource) { | |
HGLOBAL hGlobal = LoadResource(hModule, hResource); | |
if (hGlobal) { | |
void* pData = LockResource(hGlobal); | |
if (pData) { | |
if (!VerQueryValue(pData, L"\\", &pFixedFileInfo, &uPtrLen) || | |
uPtrLen == 0) { | |
pFixedFileInfo = nullptr; | |
uPtrLen = 0; | |
} | |
} | |
} | |
} | |
if (puPtrLen) { | |
*puPtrLen = uPtrLen; | |
} | |
return (VS_FIXEDFILEINFO*)pFixedFileInfo; | |
} | |
void AppendModuleNameVersion(std::wstring* string, HMODULE hModule) { | |
WCHAR buffer[1025]; | |
WCHAR szModuleName[MAX_PATH]; | |
if (!GetModuleFileName(hModule, szModuleName, _countof(szModuleName))) { | |
szModuleName[0] = L'?'; | |
szModuleName[1] = L'\0'; | |
} | |
*string += PathFindFileName(szModuleName); | |
VS_FIXEDFILEINFO* pFixedFileInfo = GetModuleVersionInfo(hModule, NULL); | |
if (pFixedFileInfo) { | |
wsprintf(buffer, L" %hu.%hu.%hu.%hu", | |
HIWORD(pFixedFileInfo->dwFileVersionMS), // Major version | |
LOWORD(pFixedFileInfo->dwFileVersionMS), // Minor version | |
HIWORD(pFixedFileInfo->dwFileVersionLS), // Build number | |
LOWORD(pFixedFileInfo->dwFileVersionLS) // QFE | |
); | |
*string += buffer; | |
} | |
} | |
#define PTR64BIT L"%016I64X" | |
std::wstring GetStackTrace() { | |
std::wstring result; | |
unsigned int i; | |
void* stack[100]; | |
unsigned short frames; | |
SYMBOL_INFOW* symbol; | |
HANDLE process; | |
HMODULE module_handle; | |
WCHAR buffer[1025]; | |
process = GetCurrentProcess(); | |
if (!SymInitialize(process, NULL, TRUE)) { | |
return result; | |
} | |
frames = CaptureStackBackTrace(0, 100, stack, NULL); | |
symbol = | |
(SYMBOL_INFOW*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, | |
sizeof(SYMBOL_INFOW) + 256 * sizeof(WCHAR)); | |
if (symbol) { | |
symbol->MaxNameLen = 255; | |
symbol->SizeOfStruct = sizeof(SYMBOL_INFOW); | |
for (i = 0; i < frames; i++) { | |
wsprintf(buffer, L"%i: %p", frames - i - 1, stack[i]); | |
result += buffer; | |
if (SymFromAddrW(process, (DWORD64)(stack[i]), 0, symbol)) { | |
wsprintf(buffer, L" (%s - " PTR64BIT L")", symbol->Name, | |
symbol->Address); | |
result += buffer; | |
} | |
if (GetModuleHandleEx( | |
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | | |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, | |
(LPCWSTR)(stack[i]), &module_handle)) { | |
result += L" ["; | |
AppendModuleNameVersion(&result, module_handle); | |
wsprintf(buffer, L" - %p]", module_handle); | |
result += buffer; | |
} | |
result += L"\n"; | |
} | |
HeapFree(GetProcessHeap(), 0, symbol); | |
} | |
SymCleanup(process); | |
return result; | |
} | |
bool EndsWithCaseInsensitive(std::wstring_view value, | |
std::wstring_view ending) { | |
if (ending.size() > value.size()) { | |
return false; | |
} | |
return std::equal(ending.crbegin(), ending.crend(), value.crbegin(), | |
[](const WCHAR a, const WCHAR b) { | |
return std::towlower(a) == std::towlower(b); | |
}); | |
} | |
using LoadLibraryExW_t = decltype(&LoadLibraryExW); | |
LoadLibraryExW_t LoadLibraryExW_Original; | |
HMODULE WINAPI LoadLibraryExW_Hook(LPCWSTR lpLibFileName, | |
HANDLE hFile, | |
DWORD dwFlags) { | |
HMODULE module = LoadLibraryExW_Original(lpLibFileName, hFile, dwFlags); | |
if (module && | |
EndsWithCaseInsensitive(lpLibFileName, L"Taskbar.View.dll"sv)) { | |
Wh_Log(L"========================================"); | |
Wh_Log(L"== Loaded %s", lpLibFileName); | |
std::wstringstream ss(GetStackTrace()); | |
std::wstring line; | |
while (std::getline(ss, line, L'\n')) { | |
Wh_Log(L"%s", line.c_str()); | |
} | |
} | |
return module; | |
} | |
BOOL Wh_ModInit() { | |
Wh_Log(L">"); | |
HMODULE kernelBaseModule = GetModuleHandle(L"kernelbase.dll"); | |
auto pKernelBaseLoadLibraryExW = (decltype(&LoadLibraryExW))GetProcAddress( | |
kernelBaseModule, "LoadLibraryExW"); | |
WindhawkUtils::Wh_SetFunctionHookT(pKernelBaseLoadLibraryExW, | |
LoadLibraryExW_Hook, | |
&LoadLibraryExW_Original); | |
return TRUE; | |
} | |
void Wh_ModUninit() { | |
Wh_Log(L">"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment