类为
Windows.UI.Core.CoreWindow的窗口通常是沉浸式窗口。要枚举这样的顶级窗口,我们需要在清单中添加
disableWindowFiltering。它禁用了窗口过滤,因此您可以通过
EnumWindows
从桌面上枚举沉浸式窗口。但是,即使在清单中没有添加
disableWindowFiltering,直接调用
FindWindowW(L"Windows.UI.Core.CoreWindow", L"Start");
也不会失败。但是,这部分仅与可见性沉浸式窗口有关,对于您的应用程序,可以通过
EnumWindows
进行枚举。
另一个任务是为这些窗口设置
WH_GETMESSAGE
钩子。问题在于,这些窗口通常属于Windows Store应用(AppContainer)进程。
Windows Store应用开发:如果dwThreadId为零,则窗口钩子DLL不会在Windows Store应用程序进程和Windows Runtime代理进程中加载,除非它们被UIAccess进程(辅助工具)安装。
因此,我们需要在清单中设置
uiAccess
为true(例如
<requestedExecutionLevel level="requireAdministrator" uiAccess="true" />
),或者在调用
SetWindowsHookEx
时将
dwThreadId
设为非0。我们可以通过
GetWindowThreadProcessId
获取
dwThreadId
。
WH_GETMESSAGE
钩子始终是进程钩子。因此,如果我们为另一个进程调用它,钩子过程必须位于dll中,并将其加载到目标进程中。这里的主要问题是如何将dll加载到Windows Store应用(AppContainer)进程中。
我用简单的dll检查了一下——尝试为
Windows.UI.Core.CoreWindow::Calculator
窗口设置钩子。调用
SetWindowsHookEx(WH_GETMESSAGE, ...)
是可以的,在
Calculator.exe中调用了
LoadLibraryExW
来加载我的dll,但是在
NtQueryAttributesFile
中以
STATUS_ACCESS_DENIED
的错误失败。好的,Appcontainer是非常受限制的进程,所以我尝试更改我的dll的安全描述符。将其设置为
"D:P(A;;FA;;;BA)(A;;FXFR;;;WD)(A;;FXFR;;;AC)S:P(ML;;NW;;;LW)"
(向Builtin(local)管理员提供完全访问权限,并为在应用程序包上下文中运行的所有应用程序(
SDDL_ALL_APP_PACKAGES
-
"AC"
)和“Everyone”(
"WD"
)提供读取-执行访问权限)。使用这个,
LoadLibraryExW
可以继续进行,但仍然无法在
ZwCreateSection
的调用中为我的DLL分配代码
STATUS_SYSTEM_NEEDS_REMEDIATION
(
C000047EL
——检测到系统二进制文件中的错误),之后调用了
LdrAppxHandleIntegrityFailure
(从
ntdll.dll导出的函数)。
![enter image description here](https://istack.dev59.com/qYpuz.webp)
因此,要将DLL加载到Windows Store应用程序(Appcontainer)中,必须进行签名。从内核方面来看,调用栈如下:
CI!KappxpNotifyNonPackagedFile
CI!KappxNotifyIntegrityFailureInPackagedProcess
CI!CipReportAndReprieveUMCIFailure
CI!CiValidateImageHeader
nt!SeValidateImageHeader
nt!MiValidateSectionCreate
nt!MiCreateNewSection
nt!MiCreateImageOrDataSection
nt!MiCreateSection
有趣的是,如果检查失败,则在
KappxpNotifyNonPackagedFile
中的
CI.DLL会将文件名和哈希写入注册表
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModel\StateChange
-
BinaryName
(
REG_SZ
)和
BinaryHash
(
REG_BINARY
)。
![enter image description here](https://istack.dev59.com/9Dp19.webp)
对于Spyxx,它使用签名的dll-
spyxxhk[_amd64].dll,如果允许所有应用程序包访问它,则该dll将被加载到进程中。因此,
Spy++也可以从Appcontainer应用中收集消息。但是在我的研究中,
Spy++会以0为
dwThreadId
开始调用
SetWindowsHookExW
。因此,
spyxxhk[_amd64].dll不会注入到Windows商店应用程序中。需要每次使用非0的
dwThreadId并在dll上具有特殊的安全描述符。
disableWindowFiltering
属性,参考链接:https://learn.microsoft.com/en-us/windows/desktop/sbscs/application-manifests。 - RbMm<disableWindowFiltering>true</disableWindowFiltering>
,则进程根本无法查看uwp窗口(例如EnumWindows
跳过此窗口),因此我猜想,在钩子测试时,disableWindowFiltering
在这里扮演关键角色。 - RbMm