有人可以解释Windows ZwMapViewOfSection系统调用,以便菜鸟(我)可以理解吗?

时间:2018-10-03 07:00:15

标签: windows winapi paging malware malware-detection

我正在调查由沙箱中运行的一部分恶意软件发出的一组Windows API系统调用,以便我可以了解其恶意意图。不幸的是,我在努力理解文档https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-zwmapviewofsection

中描述的ZwMapViewOfSection函数。

现在,我确实知道此功能与页表中物理内存到虚拟内存的映射有关。除此之外,我发现文档奥秘并且对初学者不友好。我也感到困惑,为什么他们将物理内存块称为“节”而不是“框架”(如果这确实是他们所指的,这对我来说还不清楚)。谁能提供有关此系统调用及其一般功能的更直观的解释?这是程序的常见系统调用,还是仅限于恶意软件?谢谢。

2 个答案:

答案 0 :(得分:0)

普通程序进行此调用非常普遍(当然不是直接进行此调用),每个程序至少要在初始化期间多次调用它(执行用于实现可执行文件的内存备份时使用ZwMapViewOfSection部分代码本身)。在普通程序代码中不是很常见,但也很常见。如果程序执行动态DLL加载,但是合法程序也可以出于自身原因执行内存映射的IO,则这种情况尤为常见。

它对内存部分对象(我从未真正理解过这个名称)进行操作,这些对象是磁盘文件和内存映射区域之间链接的一部分,该部分是通过ZwCreateSection创建的,或者是通过ZwOpenSection打开的,然后是另一个ZwMapViewOfSection发挥作用。

这到底让您感到困惑?知道这一点将使提供信息丰富的响应变得容易得多。

答案 1 :(得分:0)

据我所知,您必须打开文件并获取一个文件句柄,然后将其映射到 CreateFileMapping,后者将调用 NtCreateSection,后者调用 MmCreateSection。如果第一次映射文件,则首先创建新的段对象和控制区域,然后取决于是为支持 MiCreateDataFileMapMiCreateImageFileMap 或 { 的数据、图像或页面文件创建的部分{1}} 被调用。

MiCreatePagingFileMap 设置子节对象和节对象。在正常情况下只创建一个小节,但在某些特殊情况下multiple subsections are used,例如如果文件很大。对于数据文件,子节对象字段 MiCreateDataFileMap 留空。相反,段对象的 SubsectionBase 字段已正确设置,可在必要时用于创建 PPTE。这会推迟 PPTE 的创建,直到第一次映射视图,从而避免在映射非常大的数据文件时浪费内存。请注意,PPTE 是用作原型 PTE 的 PTE,而 SegmentPteTemplate 是指向原型的 PTE。

_MMPTE_PROTOTYPE 创建节对象并加载指定文件的 PE 标头并对其进行验证,然后为 PE 标头创建一个子节,为每个 PE 节创建一个子节。如果映射了一个非常小的图像文件,则只为整个文件创建一个子部分。除了小节之外,还为每个小节创建了相关的 PPTE,并根据相关 PE 节的保护设置设置了它们的页面保护标志。当视图被映射和访问时,这些 PPTE 将用作构建真实 PTE 的模板。

创建一个部分后,可以通过从它创建一个视图来将它映射到地址空间。传递给 MiCreateImageFileMapflProtect 指定了节对象的保护。对象的所有映射视图必须与此保护兼容。您将 CreateFileMappingdwMaximumSizeLow 指定为 0,以便将 dwMaximumSizeHigh 自动设置为文件的长度。

然后将返回的部分对象句柄传递给 dwMaximumSizeHigh,后者将对其调用 MapViewOfFile,后者调用 NtMapViewOfSection,后者调用 MmMapViewOfSegment,即视图所在的位置映射到进程的 VAD 中,保护 MmCreateMemoryArea 提供给 dwDesiredAccess,用作 VAD 条目涵盖的所有 PTE 的保护类型。 MapViewOfFile 中的 dwNumberOfBytesToMap = 0dwFileOffsetLow = 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 条目后立即指向。