我正在调查由沙箱中运行的一部分恶意软件发出的一组Windows API系统调用,以便我可以了解其恶意意图。不幸的是,我在努力理解文档https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-zwmapviewofsection
中描述的ZwMapViewOfSection函数。现在,我确实知道此功能与页表中物理内存到虚拟内存的映射有关。除此之外,我发现文档奥秘并且对初学者不友好。我也感到困惑,为什么他们将物理内存块称为“节”而不是“框架”(如果这确实是他们所指的,这对我来说还不清楚)。谁能提供有关此系统调用及其一般功能的更直观的解释?这是程序的常见系统调用,还是仅限于恶意软件?谢谢。
答案 0 :(得分:0)
普通程序进行此调用非常普遍(当然不是直接进行此调用),每个程序至少要在初始化期间多次调用它(执行用于实现可执行文件的内存备份时使用ZwMapViewOfSection部分代码本身)。在普通程序代码中不是很常见,但也很常见。如果程序执行动态DLL加载,但是合法程序也可以出于自身原因执行内存映射的IO,则这种情况尤为常见。
它对内存部分对象(我从未真正理解过这个名称)进行操作,这些对象是磁盘文件和内存映射区域之间链接的一部分,该部分是通过ZwCreateSection创建的,或者是通过ZwOpenSection打开的,然后是另一个ZwMapViewOfSection发挥作用。
这到底让您感到困惑?知道这一点将使提供信息丰富的响应变得容易得多。
答案 1 :(得分:0)
据我所知,您必须打开文件并获取一个文件句柄,然后将其映射到 CreateFileMapping
,后者将调用 NtCreateSection
,后者调用 MmCreateSection
。如果第一次映射文件,则首先创建新的段对象和控制区域,然后取决于是为支持 MiCreateDataFileMap
、MiCreateImageFileMap
或 { 的数据、图像或页面文件创建的部分{1}} 被调用。
MiCreatePagingFileMap
设置子节对象和节对象。在正常情况下只创建一个小节,但在某些特殊情况下multiple subsections are used,例如如果文件很大。对于数据文件,子节对象字段 MiCreateDataFileMap
留空。相反,段对象的 SubsectionBase
字段已正确设置,可在必要时用于创建 PPTE。这会推迟 PPTE 的创建,直到第一次映射视图,从而避免在映射非常大的数据文件时浪费内存。请注意,PPTE 是用作原型 PTE 的 PTE,而 SegmentPteTemplate
是指向原型的 PTE。
_MMPTE_PROTOTYPE
创建节对象并加载指定文件的 PE 标头并对其进行验证,然后为 PE 标头创建一个子节,为每个 PE 节创建一个子节。如果映射了一个非常小的图像文件,则只为整个文件创建一个子部分。除了小节之外,还为每个小节创建了相关的 PPTE,并根据相关 PE 节的保护设置设置了它们的页面保护标志。当视图被映射和访问时,这些 PPTE 将用作构建真实 PTE 的模板。
创建一个部分后,可以通过从它创建一个视图来将它映射到地址空间。传递给 MiCreateImageFileMap
的 flProtect
指定了节对象的保护。对象的所有映射视图必须与此保护兼容。您将 CreateFileMapping
和 dwMaximumSizeLow
指定为 0,以便将 dwMaximumSizeHigh
自动设置为文件的长度。
然后将返回的部分对象句柄传递给 dwMaximumSizeHigh
,后者将对其调用 MapViewOfFile
,后者调用 NtMapViewOfSection
,后者调用 MmMapViewOfSegment
,即视图所在的位置映射到进程的 VAD 中,保护 MmCreateMemoryArea
提供给 dwDesiredAccess
,用作 VAD 条目涵盖的所有 PTE 的保护类型。 MapViewOfFile
中的 dwNumberOfBytesToMap = 0
和 dwFileOffsetLow = 0
映射整个文件。
当一个视图被映射时,我相信所有的 PTE 都指向原型 PTE 并得到 PPTE 的保护。对于图像文件,PPTEs 已经被初始化为 subsection PTEs。对于数据文件,视图的 PPTE 需要初始化为小节 PTE。现在已创建视图的 VAD 条目。 VAD 条目保护并不总是反映它所涵盖的 PTE 的保护,因为它可以涵盖多个小节和这些小节中的多个块。
第一次实际访问映射中的地址时,子节原型 PTE 按需填充,分配的物理页填充该范围的 I/O 写入,进程 PTE 填充相同的地址.对于图片,在创建子部分时就已经填写了 PPTE 以及从图片中的部分标题特征派生的保护信息,它只是用该地址和其中的保护信息填充 PTE。
当PTE从进程工作集中剪裁出来时,工作集管理器访问PFN定位PPTE地址,减少共享计数,并将PPTE地址插入PTE。
我不确定 VAD PTE(原型位和原型地址为 MapViewOfFile
并且无效)何时发生。我原以为 PPTE 总是在它们的虚拟地址中,并且可以在创建 VAD 条目后立即指向。