A Windows system tray API observer built in C/C++ (Win32, x64). Monitors and correlates Shell_NotifyIcon calls from any process against Explorer's internal tray list, logging the relationship between API calls and the actual notification area state.
Work in progress — core hook infrastructure is in place but event resolution and icon respawning have known issues.
Component A — Explorer watcher
- Installs a
WH_CALLWNDPROCglobal hook into Explorer's message pump - Intercepts
WM_COPYDATAonShell_TrayWndand decodesSHELLTRAYDATApayloads (NIM_ADD, NIM_MODIFY, NIM_DELETE, NIM_SETFOCUS, NIM_SETVERSION) - Enumerates the live tray toolbar (
SysPager→ToolbarWindow32) viaTB_GETBUTTON+ReadProcessMemoryfor on-demand snapshots
Component B — API observer
- IAT-patches
Shell_NotifyIconWin target processes - Intercepts calls before they reach Explorer, capturing the full
NOTIFYICONDATApayload - Reports via named pipe (
\\.\pipe\TrayObserver) back to the controller
GUI
- Dark theme, owner-drawn Win32 controls
- Per-process event detail windows
- Persistent event history
- Toolbar controls for snapshot, clear, and filter
- Correlation view matching API call events to Explorer's internal tray state
IPC
- Named pipe (
\\.\pipe\TrayObserver) between injected DLLs and the controller - Local-only — routes through NPFS, not affected by UNC hardening policies
TrayObserver.exe — main application (GUI + controller + pipe server)
TrayHook.dll — WH_CALLWNDPROC hook, injected into Explorer
ComponentA.dll — snapshot enumerator + hook installer
ComponentB.dll — IAT patcher + process injector
PayloadHook.dll — IAT patch DLL injected into target processes
- System tray icons do not respawn correctly after the hook is installed — Explorer's internal icon list gets out of sync
- Event log produces verbose or nonsensical entries during icon resolution due to timing between NIM_ADD/MODIFY/DELETE events and the snapshot enumerator
- These are active areas of investigation
- Windows 10 x64
- Must be run as administrator (required for
SetWindowsHookExinto Explorer and process injection) - MSVC x64 build environment
Open in Visual Studio and build the solution. Component DLLs must be built before the main executable. All binaries must be co-located for the hook installer to find them.
This tool uses process injection and global hooks. It will be flagged by antivirus — add the build directory to your AV exclusions. Designed for use on your own machine for development and research purposes.
PPL-protected processes and processes running at higher integrity are automatically skipped.