Sometimes session context is important too

I go on and on about thread and process context in this blog and in my courses, but every once in a rare while session context becomes an important topic.

Historically we’ve thought of sessions as being a Terminal Services only concept, where each user logged on to the Terminal Server is provided their own session. This allows the user to have their own desktop, mapped drive letters, processes, etc. Windows XP brought the idea of sessions to the desktop with the introduction of Fast User Switching, which provides each logged on user their own session. Windows Vista took advantage of the built in support of sessions to provide isolation from background services with interactive user tasks. This so called, “Session Zero Isolation” means that every Vista and later Windows installation is always running at least two sessions, session 0 containing critical Windows processes and services and session 1 providing the default user desktop.

In order to maintain global state for each session, Windows carves out a portion of the kernel virtual address space and stores and global data there. In order to scale appropriately across hundreds or even thousands of sessions, Windows cannot simply use an array of global session data with an entry for each session. Instead, Windows will use a single portion of the address space and simply map it differently based on the session that the current process runs in.

Why this is interesting is that we typically believe that all kernel virtual addresses are the same across all processes. However, we may find that different kernel virtual addresses are mapped differently depending on which session our process context maps to, just  like user space virtual addresses. An example of this was recently discovered on NTDEV and had to do with the tsddd.dll module. The OP couldn’t seem to figure out why he couldn’t read the image from either the debugger or his kernel driver. As it turns out, this image is only mapped in session zero on the target platform, which was Windows 7 (haven’t bothered to look anywhere else personally).

Let’s check it out with LiveKD. First, we can try to dump out the beginning of the image:

tsddds1

Nada. We can use the !pte command to determine what exactly is wrong with this address and we’ll see that there is simply no mapping for this address (as evidenced by the contents of the PTE being zero):

emptypte

Let’s use the !session command to look into which session we are in and what sessions are available:

session

According to this, we’re running in session one and there is another valid session, session zero. This matches what we understand about Vista and later where there are always at least two sessions running on the system. Let’s try switching to the other session and seeing if we can dump out the module header:

tsddds0

Jackpot! Thus, what we can determine from this is that this kernel module is currently only mapped into session zero on this machine.

Leave a Reply