1

I'm investigating a set of Windows API system calls made by a piece of malware running in a sandbox so that I can understand its malicious intent. Unfortunately, I'm struggling to understand the ZwMapViewOfSection function described in documentation: https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-zwmapviewofsection

Now, I do understand that this function is related to the mapping of physical memory to virtual memory in a page table. Apart from that, I find the documentation arcane and not friendly to beginners. I am also confused why they are calling blocks of physical memory "sections" rather than "frames" (if that is what they are indeed referring to -- its not clear to me). Can anyone provide a more intuitive explanation about this system call and what it does in general? Is this a common system call for programs or is it limited to malware? Thank You.

H3G3moKnight
  • 123
  • 1
  • 9
  • *section* object this is *file mapping* object on win32 language. corresponded win32 calls is [`MapViewOfFileEx`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366763(v=vs.85).aspx) and new api [`MapViewOfFile2`](https://msdn.microsoft.com/en-us/library/windows/desktop/mt492557(v=vs.85).aspx). both this win32 api shell over `ZwMapViewOfSection`. how easy view nt-api have more parameters, so more power – RbMm Oct 03 '18 at 07:57

2 Answers2

0

It is extremely common for normal programs to make this call (not directly of course), every program is going to invoke it multiple times during initialization at the very least (ZwMapViewOfSection is used when performing the memory backing used to implement the executable sections of code itself). Not so common during normal program code but not uncommon either. Particularly common if the program performs dynamic DLL loads but legitimate programs can also do memory-mapped IO for their own reasons.

It operates on memory section objects (I've never really understood that name either) which are one part of the link between disc files and memory-mapped regions, the section is created via ZwCreateSection or opened with ZwOpenSection and then the other part comes into play with ZwMapViewOfSection.

What part of this, exactly, is confusing you? Knowing that would make it far easier to provide an informative response.

SoronelHaetir
  • 14,104
  • 1
  • 12
  • 23
  • 1
    *"Section"* is the organizational unit of the [PE Format](https://learn.microsoft.com/en-us/windows/desktop/debug/pe-format). Since the primary use for `ZwMapViewOfSection` is to establish a mapping between sections of an executable image and chunks of virtual address space, the term *"section"* made it into the function name. – IInspectable Oct 03 '18 at 09:32
  • @IInspectable - this api absolute unrelated to pe format and "section" in sense pe section. section here the same as "file mapping". use of `ZwMapViewOfSection` the same as `MapViewOfFile[Ex|2]` – RbMm Oct 03 '18 at 10:15
  • 2
    @rbm: I'm talking about history here, and mapping a PE file section into memory was the initial use case of the file mapping API. That's where the term *"section"* comes from. In essence: There *is* a relation between this API and PE files, but that relation is historic and does not impose a limitation. – IInspectable Oct 03 '18 at 12:01
  • 1
    @IInspectable, to clarify, the connection here is, and has always been, between PE sections and the *subsections* of a Section object. Only one Section object is created when a file is mapped as `SEC_IMAGE`. A Section object references a Segment Control Area, which has a singly linked list of subsections (for an image map, it's one for the header and one for each PE section). A subsection incudes the number of prototype page table entries (PTEs), base PTE address, starting logical sector number (LSN) in the file, and number of sectors. – Eryk Sun Oct 03 '18 at 23:52
0

As far as I understand it, you have to open the file and acquire a file handle which you then map with CreateFileMapping, which will call NtCreateSection, which calls MmCreateSection. If the file is mapped for the first time a new segment object and control area are created first then depending on whether the section is created for a data, image or page-file backed MiCreateDataFileMap, MiCreateImageFileMap or MiCreatePagingFileMap is called.

MiCreateDataFileMap sets up the subsection object and section object. In the normal case only one subsection is created, but under some special conditions multiple subsections are used, e.g. if the file is very large. For data files, the subsection object field SubsectionBase is left blank. Instead the SegmentPteTemplate field of the segment object is setup properly which can be used to create the PPTEs when necessary. This defers the creation of PPTEs until a view is mapped for the first time which avoids wasting memory when very large data files are mapped. Note a PPTE is a PTE that is serving as a prototype PTE, but an _MMPTE_PROTOTYPE is a PTE that is pointing to a prototype.

MiCreateImageFileMap creates the section object and loads the PE header of the specified file and verifies it then one subsection is created for the PE header and one for each PE section. If a very small image file is mapped then only one subsection is created for the complete file. Besides the subsections also the related PPTEs for each of them are created and their page protection flags are set according to the protection settings of the related PE section. These PPTEs will be used as a template for building the real PTEs when a view is mapped and accessed.

After a section is created it can be mapped into the address space by creating a view from it. The flProtect passed to CreateFileMapping specifies the protection of the section object. All mapped views of the object must be compatible with this protection. You specify dwMaximumSizeLow and dwMaximumSizeHigh to be 0 in order for dwMaximumSizeHigh to be set to the length of the file automatically.

You then pass the returned section object handle to MapViewOfFile, which will calls NtMapViewOfSection on it, which calls MmMapViewOfSegment, which calls MmCreateMemoryArea, which is where the view is mapped into the VAD of the process with the protection dwDesiredAccess supplied to MapViewOfFile, which serves as the protection type for all PTEs that the VAD entry covers. dwNumberOfBytesToMap = 0 and dwFileOffsetLow = 0 in MapViewOfFile maps the whole file.

When a view is mapped, I believe that all of the PTEs are made to point to the prototype PTEs and are given the protection of the PPTE. For an image file, the PPTEs have already been initialised to subsection PTEs. For a data file, the PPTEs for the view need to be initialised to subsection PTEs. The VAD entry for the view is now created. The VAD entry protection isn't always reflective of the protection of the PTEs it covers, because it can cover multiple subsections and multiple blocks within those subsections.

The first time an address in the mapping is actually accessed, the subsection prototype PTE is filled in on demand with the allocated physical page filled with the I/O write for that range and the process PTE is filled in with that same address. For an image, the PPTE was already filled in when the subsections were created along with protection information derived from the section header characteristics in the image, and it just fills in the PTE with that address and the protection information in it.

When the PTE is trimmed from the process working set, the working set manager accesses the PFN to locate the PPTE address, decreases the share count, and it inserts the PPTE address into the PTE.

I'm not sure when a VAD PTE (which have a prototype bit and prototype address of 0xFFFFFFFF0000 and is not valid) occurs. I would have thought the PPTEs are always there at their virtual address and can be pointed to as soon as the VAD entry is created.

Lewis Kelsey
  • 4,129
  • 1
  • 32
  • 42