如何不使用WinRT获取当前HWND对应的IDCompositionDevice实例
关于非WinRT环境下获取Xaml渲染用IDCompositionDevice实例的解答
可以实现,方案完全不需要调用任何WinRT体系API,也无需操作Windows.UI.Composition.Compositor对象,但依赖Windows未公开的内部实现细节,不同版本间兼容性无法保证,不建议用于生产环境
- 方案1:线程本地存储(TLS)直接读取
Xaml运行时会将当前线程绑定的IDCompositionDevice实例指针存储在TLS的固定槽位:Windows 10 1903及以上版本槽位为0x78,Windows 11 21H2及以上版本槽位为0x82,直接通过NtCurrentTeb()访问TLS数组对应槽位即可拿到指针,全程仅需读取线程环境块内存,无需调用任何额外API。 - 方案2:特征码内存搜索
如果你不希望依赖系统版本对应的TLS槽位,可以对当前进程内的windows.ui.xaml.dll模块数据段进行内存扫描,匹配特征码48 8B 05 ? ? ? ? 48 8B 40 20,该特征码对应Xaml运行时全局存储IDCompositionDevice实例的引用位置,解算相对偏移后即可获取有效指针。 - 有效性校验
无论用哪种方案拿到的指针,都需要先做虚表合法性校验:IDCompositionDevice的虚表前三个函数固定为QueryInterface、AddRef、Release,第四个函数对应CreateSurface,匹配该特征即可确认指针有效。
所有操作均为纯Win32内存读写,完全不涉及WinRT API调用,也不需要和
Windows.UI.Composition命名空间下的任何对象交互。但该方案依赖未公开的内部实现,Windows系统版本更新可能会修改TLS槽位、特征码位置,不兼容版本下可能读取到无效指针,甚至触发进程崩溃。
内容的提问来源于stack exchange,提问作者Ahmed Walid
相关产品推荐
相关产品推荐

