我的问题:
当win32k.sys加载到会话空间时,它是否在每个会话中获得相同的基址?
详细说明:
我正在为Windows(32位)编写内核模式设备驱动程序。它在系统引导期间作为标准WDM驱动程序加载到系统空间(全局内核模式内存)中。
但在某些情况下,我需要访问win32k.sys导出的函数。确切地说,我正在编写一种有时需要伪装成显示驱动程序的驱动程序。
我可能不会静态导入这些功能(意味着,通过可执行的导入表导入它们)。这是因为在创建会话的后期阶段加载了win32k.sys。此外,它已加载到会话空间。
尽管如此,我找到了解决方法。在会话创建期间,我动态导入所需的函数。我使用ZwQuerySystemInformation
和SystemModuleInformation
来查找当前会话中win32k.sys 的基地址。然后使用这个基地址我分析它以找到win32k.sys的导出目录并获得所需的函数指针。
目前,对于每个会话,我都会保留一个单独的导入函数数组。然而,实际上这些功能在所有会话中始终是相同的。均值 - win32k.sys映射到每个会话中属于会话空间的同一地址。
因此,我的问题是,是否保证win32k.sys将在所有会话中映射到同一地址?
除了节省一些记忆外,这对我来说更容易。目前为了调用这样的函数,我需要一个特定于会话的上下文来存储函数指针。
答案 0 :(得分:2)
我的经验是 win32k.sys 基地址在驱动程序映射的所有进程的上下文中是相同的。在初始化期间, win32k.sys 调用ntoskrnl.exe
为桌面,窗口站以及驱动程序使用的其他对象创建对象类型内核对象。这些内核对象必须位于所有进程的上下文中的相同地址,以保持内核数据结构的一致性(例如,有一个指向ntoskrnl.exe
模块内所有对象类型对象的指针数组)。
此外, win32k.sys 包含系统调用表(win32k!W32pServiceTable
)。该表的地址再次存储在ntoskrnl.exe
(nt!KeServiceDescriptorTableshadow
)中的固定位置。
因此,如果 win32k.sys 驱动程序映射到不同会话中的不同地址,ntoskrnl.exe
必须表现相同。这不是真的(这种行为会导致其他问题,例如SYSENTER/SYSCALL
)。但我没有在任何官方文件中看到这个事实。
答案 1 :(得分:0)
我不太确定,但我猜答案是肯定的。 Win32k.sys只是另一个(特殊)dll文件,Windows上的每个dll文件都在其PE头中有一个基地址。对于由Windows提供的win32k.sys(我认为),基地址不应该与其他系统dll(.sys)文件冲突。
为了安全起见,您可以使您的程序更灵活一些。一开始,您假设地址相同。但是,在实际调用之前,请检查地址。这样,系统不会因为地址不好而挂起,至少。