Mahdi Ghiasi
Mahdi Ghiasi

Reputation: 15301

Getting win32 messages from Windows.UI.Core.CoreWindow of UWP app windows

I'm trying to get Pointer Win32 messages of a specific window, by a hook on WH_CALLWNDPROC, WH_CALLWNDPROCRET and WH_GETMESSAGE.

I use SetWindowsHookEx in a c++ dll to hook and receive messages.

unsigned long processID = 0;
unsigned long threadID = GetWindowThreadProcessId(hWnd, &processID);

g_hhkGetMsg = SetWindowsHookEx(WH_GETMESSAGE,
    GetMsgProc,
    g_hinstDLL,
    threadID);

This works for many windows, but not for CoreWindow of UWP windows.

Each UWP app window has a structure like this: UWP window structure

Hooking to ApplicationFrameWindow works correctly, but hooking to Windows.UI.Core.CoreWindow does not work. (SetWindowsHookEx shows success, but I don't get any messages in the callback)

However, Spy++ is able to capture the messages from the CoreWindow. (The CoreWindow receives WM_POINTER messages, so I need to subscribe to that window)

Thinking the issue might be on my code, I also tried the open source tool MyLiteSpy to see if that can capture messages from the CoreWindow. It can't capture anything, just like my sample code. (But MyLiteSpy is able to get messages from ApplicationFrameWindow of the same UWP app, and so can my code and Spy++)

enter image description here

Interestingly, this (old) blog post about Spy++ says that they use the same three hooks as me and MyLiteSpy, but it's getting messages that my code can't receive.

What is the difference here? Any idea why this is happening?

(Is Spy++ using hooks other than the three mentioned? The blog post is written in 2007, so things might have changed)

Upvotes: 3

Views: 2575

Answers (1)

RbMm
RbMm

Reputation: 33706

windows of class Windows.UI.Core.CoreWindow is usually immersive windows. for be able enumerate such, top level, windows, we need have disableWindowFiltering in manifest. it disables window filtering so you can enumerate (via EnumWindows) immersive windows from the desktop. but say direct call to FindWindowW(L"Windows.UI.Core.CoreWindow", L"Start"); - not fail even without disableWindowFiltering in manifest. however this part is only related to visibility immersive windows, via EnumWindows, for your application.

another task set WH_GETMESSAGE hook for such windows. problem here that this windows usually belong to Windows Store app (AppContainer ) process.

Windows Store app development: If dwThreadId is zero, then window hook DLLs are not loaded in-process for the Windows Store app processes and the Windows Runtime broker process unless they are installed by either UIAccess processes (accessibility tools).

so we need have or uiAccess set to true in manifest (say <requestedExecutionLevel level="requireAdministrator" uiAccess="true" />) or not 0 for dwThreadId in call SetWindowsHookEx. the dwThreadId we can got via GetWindowThreadProcessId

the WH_GETMESSAGE hook is always in process hook. so if we call it for another process - hook procedure must be located in dll, which will be loaded to target process. and here is main problem - how load dll to Windows Store app (AppContainer ) process.

i check this with self simply dll - try set hook for Windows.UI.Core.CoreWindow::Calculator window. the call for SetWindowsHookEx(WH_GETMESSAGE, ..) is ok, and in Calculator.exe called LoadLibraryExW for my dll, but this call fail inside NtQueryAttributesFile with error STATUS_ACCESS_DENIED. ok, Appcontainer is very restricted process, so i try change security descriptor on my dll. set it to "D:P(A;;FA;;;BA)(A;;FXFR;;;WD)(A;;FXFR;;;AC)S:P(ML;;NW;;;LW)" (give full access to Builtin (local ) administrators and read-execute access to all applications running in an app package context (SDDL_ALL_APP_PACKAGES - "AC") and Everyone ("WD"). with this LoadLibraryExW go forward, but anyway fail in call ZwCreateSection for my DLL with code STATUS_SYSTEM_NEEDS_REMEDIATION (C000047EL - An error in a system binary was detected) after which is LdrAppxHandleIntegrityFailure called (exported function from ntdll.dll)

enter image description here enter image description here

so for load DLL to Windows Store app (Appcontainer) it must be signed. from kernel side call-stack is next

CI!KappxpNotifyNonPackagedFile
CI!KappxNotifyIntegrityFailureInPackagedProcess
CI!CipReportAndReprieveUMCIFailure
CI!CiValidateImageHeader
nt!SeValidateImageHeader
nt!MiValidateSectionCreate
nt!MiCreateNewSection
nt!MiCreateImageOrDataSection
nt!MiCreateSection

interesting that if check fail CI.DLL inside KappxpNotifyNonPackagedFile write file name and hash to registry under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModel\StateChange - BinaryName (REG_SZ) and BinaryHash (REG_BINARY)

enter image description here

in case Spyxx - it use signed dll - spyxxhk[_amd64].dll - this dll (if allow all app packages access to it) is loaded to process ok. so potentially Spy++ can collect messages from Appcontainer apps too. but in my research Spy++ call SetWindowsHookExW at begin with dwThreadId set to zero. as result spyxxhk[_amd64].dll will be not injected to Windows Store apps. need every time use not 0 dwThreadId and have special security descriptor on dll.

Upvotes: 6

Related Questions