Friday 27 December 2013

Tis' The Season To Be Sharing - Sharing and Mapping Memory

This blog post is going to look at sharing memory, control areas and section objects, and how to view information about these mechanisms. Let's begin by looking at the general concept of sharing physical memory between two processes.

Process A and Process B both wish to use the same resource, this could be a library or some other kind of object. The pages used to map the shared resource, do cause any conflicts between the two processes, since the processes retain their own private virtual address space, and furthermore the pages will be marked with protection flags such as copy on write and execute only.

The sharing mechanism is mostly driven by a special object used by the Memory Manager called a Section Object. This may also be referred to as a File Mapping Object.

Sections Objects are created by calling the CreateFileMapping function, and then using a file handle to back the Section Object to, or using the INVALID_HANDLE_VALUE flag to use a page file backed region. The reasoning for the choice with the handle, is because Section Objects can be either be committed and then written to a page file on the hard disk, or a open file.

You may also notice other API function calls such as MapViewOfFile and MapViewOfFilEx. These are used when the Section Objects mapped to files much larger than the address space of the process, and therefore only a small portion of the Section Object will be mapped into the address space of a process. This is called a View of the Section Object.

Like all objects, the Section Object is manged by the Object Manager, and as a result the same techniques as discussed in my Object Manager posts can be used to gather information about a Section Object. We need to also understand the idea and concept of Control Areas.

Looking for Control Areas

Control Areas are used to store information about Section Objects and Mapped files. We can find Control Areas through several different methods, the first method is by using the !filecache WinDbg extension, which in turn displays the usage of file cache. If your why Section Objects and Control Areas can be found this way, it is because the Cache Manager uses mapped files.

The Control column lists all the Control Areas used by the Cache Manager and their addresses. The No Name for File message indicates that the Virtual Address Control Block (VACB) is not present and being cached for metadata. The VACB can be seen with the _VACB data structure in WinDbg.

 The BaseAddress field of the data structure points to the starting address of the view used by the system cache, and is used in conjuction with the MmMapViewInSystemCache. The SharedCacheMap field is a pointer to another data structure, which belongs to the VACB and uses the Section Object used to map the view of the file. The ArrayHead field is pointer to a data structure which is used to manage the array of VACBs.

You could also use the !memusage extension to view the PFN database, and then view the Control Areas for the Section Objects from using that extension.

The last method, is to use the !handle extension, which dump all the handles for the current section objects for the current process.

Using the address of the Section Object, and then applying the dt command with the _SECTION_OBJECT data structure, we can locate the _CONTROL_AREA data structure by checking the _SEGMENT_OBJECT data structure.

If your wondering about the VAD Tree related fields, then please read my VAD Tree blog post, and see this blog post too - Hidding Module from the Virtual Address Descriptor Tree

Examining Control Areas

We can then view information about a Control Area with the !ca extension or by using the _CONTROL_AREA data structure.

Personally, I prefer to use the !ca extension instead of formatting the data structure in WinDbg. Using the !ca extension with the address of the Control Area, we can see three distinct categories: Control Area, Segment and Subsection. 

 The File Object field contains the address of the File Object associated with the file mapping, we can see the !fileobj extension or the _FILE_OBJECT data structure here to gather further information. Generally, the Control Area section contains information about the state of any mapped files. The Flush Count field contains the number of times a mapped view was flushed with the FlushViewOfFile function.

The most important field is the Section Object Pointers, which contains the address of the _SECTION_OBJECT_POINTERS data structure. This data structure is used by the Memory Manager or the Cache Manager to provide information about file mapping and cache information for a file stream. 

The DataSectionObject field contains the address of the Control Area. A NULL value indicates that the file stream is not present in memory. See the WDK documentation for more information.

The Segment section contains information about the prototype PTEs used to map the pages used by the section object. This structure is allocated with paged pool.

The Subsection contains information contains information about the page protection and mapping information for each section of the file used in the mapping.

1 comment: