我试图通过WH_CALLWNDPROC
、WH_CALLWNDPROCRET
和WH_GETMESSAGE
上的钩子来获取特定窗口的指针WH_CALLWNDPROCRET
消息。
我在SetWindowsHookEx
dll中使用c++来挂接和接收消息。
unsigned long processID = 0;
unsigned long threadID = GetWindowThreadProcessId(hWnd, &processID);
g_hhkGetMsg = SetWindowsHookEx(WH_GETMESSAGE,
GetMsgProc,
g_hinstDLL,
threadID);
这适用于许多窗口,但不适用于UWP窗口的CoreWindow
。
每个UWP应用程序窗口都有如下结构:
连接到ApplicationFrameWindow是正确的,但是连接到Windows.UI.Core.CoreWindow
不起作用。(SetWindowsHookEx
显示成功,但我在回调中没有收到任何消息)
但是,Spy++能够捕获来自CoreWindow
的消息。( CoreWindow
接收WM_POINTER消息,因此我需要订阅该窗口)
考虑到问题可能在我的代码中,我还尝试了开源工具https://github.com/yinkaisheng/MyLiteSpy,看看它是否可以捕获来自CoreWindow的消息。它不能捕获任何东西,就像我的示例代码一样。(但MyLiteSpy能够从同一个UWP应用程序的ApplicationFrameWindow获得消息,我的代码和Spy++也可以)
有趣的是,这个(旧的)博客文章 about Spy++说他们使用与me和MyLiteSpy相同的三个钩子,但是它得到的消息是我的代码无法接收的。
这里有什么区别?知道为什么会这样吗?
( Spy++是否使用上述三种钩子之外的钩子?这篇博文是在2007年写的,所以事情可能已经改变了)
发布于 2018-12-22 16:24:56
Windows.UI.Core.CoreWindow类的窗口通常是沉浸式窗口。为了能够枚举这样的、顶级的、窗口的,我们需要在清单中有https://learn.microsoft.com/en-us/windows/desktop/sbscs/application-manifests。它禁用窗口过滤,以便您可以从桌面枚举(通过EnumWindows
)沉浸式窗口。但是直接打电话给FindWindowW(L"Windows.UI.Core.CoreWindow", L"Start");
--即使没有disableWindowFiltering也不会失败。但是,这部分仅与您的应用程序通过EnumWindows
的可见性沉浸窗口有关。
另一个任务设置了用于此类窗口的WH_GETMESSAGE
钩子。这里的问题是,这个窗口通常属于windows应用程序(AppContainer )进程。
Windows应用程序开发:如果dwThreadId为零,那么Windows应用程序进程和进程的进程中没有加载窗口挂钩DLL,除非它们是由UIAccess进程(可访问性工具)安装的。
因此,对于调用uiAccess
中的dwThreadId
,我们需要在dwThreadId
中将for或SetWindowsHookEx
设置为true (例如<requestedExecutionLevel level="requireAdministrator" uiAccess="true" />
),而不是0。我们可以通过GetWindowThreadProcessId
获得的GetWindowThreadProcessId
WH_GETMESSAGE
钩子总是在进程钩子中。因此,如果我们为另一个进程调用它-钩子过程必须位于dll中,这将被加载到目标进程。这里是主要的问题-如何加载dll到Windows应用程序(AppContainer )进程。
我检查这与自我简单dll -尝试设置钩子为Windows.UI.Core.CoreWindow::Calculator
窗口。对SetWindowsHookEx(WH_GETMESSAGE, ..)
的调用是正常的,在Calculator.exe中名为LoadLibraryExW
for my,但是这个调用在NtQueryAttributesFile
中失败,并带有错误STATUS_ACCESS_DENIED
。好的,Appcontainer是非常受限的进程,所以我尝试更改我的dll上的安全描述符。将其设置为"D:P(A;;FA;;;BA)(A;;FXFR;;;WD)(A;;FXFR;;;AC)S:P(ML;;NW;;;LW)"
(授予对内置(本地)管理员的完全访问权,并对在应用程序包上下文(SDDL_ALL_APP_PACKAGES
- "AC"
)和所有人("WD"
)中运行的所有应用程序进行读-执行访问)。使用此LoadLibraryExW
继续前进,但是无论如何,使用代码STATUS_SYSTEM_NEEDS_REMEDIATION
(C000047EL
-在系统二进制文件中检测到错误)调用DLL的ZwCreateSection
失败,之后是LdrAppxHandleIntegrityFailure
调用(从ntdll.dll导出函数)。
因此,要将DLL加载到Windows应用程序(应用程序容器),必须对其进行签名。下一个是从内核端调用堆栈。
CI!KappxpNotifyNonPackagedFile
CI!KappxNotifyIntegrityFailureInPackagedProcess
CI!CipReportAndReprieveUMCIFailure
CI!CiValidateImageHeader
nt!SeValidateImageHeader
nt!MiValidateSectionCreate
nt!MiCreateNewSection
nt!MiCreateImageOrDataSection
nt!MiCreateSection
有趣的是,如果检查失败,CI.DLL在KappxpNotifyNonPackagedFile
中将文件名和哈希写入HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModel\StateChange
- BinaryName
(REG_SZ
)和BinaryHash
(REG_BINARY
)下的注册表。
如果Spyxx -它使用有签名的dll - spyxxhk_amd64.dll -这个dll (如果允许所有应用程序包访问它)被加载以处理ok。因此,潜在的Spy++也可以从应用程序中收集消息。但在我的研究中,Spy++调用SetWindowsHookExW
开始时,dwThreadId
设置为零。因此,spyxxhk_amd64.dll将不会注入到Windows应用程序中。每次使用时不要使用0 dwThreadId,并在dll上有特殊的安全描述符。
https://stackoverflow.com/questions/53873390
复制相似问题