首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >谁能解释一下Windows ZwMapViewOfSection系统调用,好让新手(我)能理解?

谁能解释一下Windows ZwMapViewOfSection系统调用,好让新手(我)能理解?
EN

Stack Overflow用户
提问于 2018-10-03 15:00:15
回答 2查看 1.2K关注 0票数 1

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

现在,我确实理解了这个函数与页表中物理内存到虚拟内存的映射有关。除此之外,我发现文档晦涩难懂,对初学者也不友好。我也不明白为什么他们把物理内存块称为“段”而不是“帧”(如果这就是他们所指的--我不清楚)。有没有人能更直观地解释一下这个系统调用,以及它一般做了什么?这是对程序的常见系统调用,还是仅限于恶意软件?谢谢。

EN

回答 2

Stack Overflow用户

发布于 2018-10-03 15:39:41

对于普通程序来说,进行这种调用(当然不是直接调用)是非常常见的,每个程序至少会在初始化期间多次调用它(ZwMapViewOfSection是在执行用于实现代码本身的可执行部分的内存回退时使用的)。在正常的程序代码中不是很常见,但也不是不常见。当程序执行动态DLL加载时尤其常见,但合法程序也可以出于自己的原因执行内存映射IO。

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

到底是哪一部分让你感到困惑呢?了解这一点将使提供信息性回复变得容易得多。

票数 0
EN

Stack Overflow用户

发布于 2021-02-10 20:13:47

据我所知,您必须打开文件并获取一个文件句柄,然后将其映射到CreateFileMapping,后者将调用NtCreateSection,后者将调用MmCreateSection。如果文件是第一次映射,则首先创建新的段对象和控制区,然后根据是为数据、图像还是页面文件支持的MiCreateDataFileMap创建节,调用MiCreateImageFileMapMiCreatePagingFileMap

MiCreateDataFileMap设置子对象和截面对象。在正常情况下,只创建一个子部分,但在某些特殊情况下会创建multiple subsections are used,例如,如果文件非常大。对于数据文件,子对象字段SubsectionBase留空。取而代之的是,片段对象的SegmentPteTemplate字段被正确设置,必要时可以使用它来创建PPTE。这将PPTE的创建推迟到第一次映射视图,从而避免了在映射非常大的数据文件时浪费内存。注意: PTE是充当原型PTE的PTE,而_MMPTE_PROTOTYPE是指向原型的PTE。

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

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

然后将返回的节对象句柄传递给MapViewOfFile,它将在其上调用NtMapViewOfSection,后者调用MmMapViewOfSegment,后者调用MmCreateMemoryArea,这是将视图映射到进程的VAD的位置,并将保护dwDesiredAccess提供给MapViewOfFile,作为VAD条目涵盖的所有PTE的保护类型。MapViewOfFile中的dwNumberOfBytesToMap = 0dwFileOffsetLow = 0映射整个文件。

当映射一个视图时,我相信所有的PPTE都指向原型PPTE,并受到PPTE的保护。对于图像文件,PPTE已经初始化为子PTE。对于数据文件,视图的PPTE需要初始化为子PTE。现在创建了视图的VAD条目。VAD条目保护并不总是反映它所覆盖的PTE的保护,因为它可以覆盖多个子部分和这些子部分中的多个块。

当映射中的地址第一次被实际访问时,子部分原型PTE被按需填充,分配的物理页被该范围的I/O写填充,并且进程PTE被填充该相同的地址。对于图像,在创建子部分以及从图像中的节头特征导出的保护信息时,PPTE已经填充,它只是使用该地址和其中的保护信息填充PTE。

当PTE从进程工作集被修整时,工作集管理器访问PFN以定位PPTE地址,减少共享计数,并将PPTE地址插入PTE中。

我不确定何时发生VAD PTE (其原型位和原型地址为0xFFFFFFFF0000,并且无效)。我认为PPTE总是在它们的虚拟地址上,只要创建了VAD条目就可以指向它们。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52621403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档