In the last blog post, we looked at the structure of Hive Bins and Hives, in this blog post I will looking into Cell Indexes and Cell Index Mapping.
Cells are containers for information, such as keys, thus the reason for the different type of cells explained in the last post. In order to make the logical structure of the registry clearer, it’s important for me to state how all the different parts I’ve been discussing fit together to form one complete picture of the Windows Registry.
Hives are split into Bins, and the Bins are then split into Cells. A Empty Bin will not contain any cells, whereas, a Bin with Cells will obviously contains Cells which will contain registry data. This brings around the point about Cell Indexes and Cell Mappings, and some of the data structures will can explore with WinDbg.
Cell Indexes are essentially pointers which link cells from different hives together, to make easier and more efficient for the Configuration Manager to load information which it is searching for. More specifically, the Cell Index is a offset into the cell with the subtraction of the size of the base block for the selected hive.
The tables which the Cell Indexes are used to index into, can be found within the Storage.Map member of the _DUAL data structure of the appropriate _HHIVE data structure. We can expand the _DUAL data structure and examine this member.
The _HMAP_DIRECTORY is a array of pointers to table entries, which then contain the information for a specific Block and Bin. The FreeDisplay field is used to for free cells within memory.
Since Hives are allocated from Paged Pool, they will need to be mapped since paged pool isn’t guaranteed to be contiguous. This leads to the concept of Cell Index Mapping, which is very much the same as Virtual Address Translation on x86 systems; remember that x64 had a additional table of directory pointers.
Using the diagram above, it may become more apparent what the pointers within the mentioned data structures are being used to index into. As we can see, the Directory Index pointer is being used to point to the Hive Cell Map Directory, which is then used to point to the Cell Map Table with a Table Index pointer, and then the Byte Offset is used to point to the specific Cell within the Hive Block.
There is a additional bit which is either 0 or 1, and is used to determine if the Hive is Volatile or Stable, and which table type to begin searching with. This translation is used for Hives in memory. 1 is Volatile and 0 is Stable.
Directory Index = 10 bits
Table Index = 9 bits
Byte Offset = 12 bits
Since Hives usually reside on the hard disk, and are then mapped into memory, in order to avoid excessive consumption of the Cache Manager’s address space. The number of mapped views for a hive is limited to 256 views. The LRU (Least Recently Used) views list is consulted when this has been reached, and when a new mapping is required because the Configuration Manager requires a hive to be mapped into memory. The LRU mapping will be removed from the list. This data structure is allocated with Paged Pool.
There is some interesting WinDbg extensions we can use to find additional information related to Cell Indexes such as the !reg cellindex extension.
The extension shows the virtual address associated with the Cell Index. The first address is the Hive Address and the 40 is the offset which we are looking for. I’ve used the SYSTEM hive in this example.
For additional information, I would suggest reading this thesis, which will be available on my One(Sky)Drive since I can’t find the original download link. Just ignore the random pictures and other junk in my Public folder, the Ted Mosby picture is a inside joke about me.