Windows Deep Dive 101 - Rings

Windows Deep Dive 101 - Rings

I know that everyone is sick and tired of hearing about COVID-19, but being stuck inside I figured it was a good idea to create some content that might be relevant in the future.  My attempt is going to be somewhat regular postings of short-smallish blog posts doing deep dives into the Windows Operating System internals.  Most of my research is going to be based off the book "Windows Internals: Part 1 System architecture, processes, threads, memory management, and more"  See the link here for Amazon's page about the book.  Since these short series posts are not meant to be long drawn out research posts, I will be skipping many of the formalities contained in our other blog posts.  No more introductions or reasoning of these posts (after this one of course). Thanks for reading, and hopefully you can use these posts as references in the future.

Intro - Chapter 1: Concepts and Tools

Kernel mode vs. user mode.  Windows operating system protects user applications from accessing and/or modifying critical OS data by using two separate modes.  The "User mode" is the where user application code runs, whereas "kernel mode" is where system services, device drivers, and high privileged code runs.  It should be noted that many processors will support more than two modes, but Windows used the reasoning that it was the lowest minimum bar allowing for more efficient and portable architecture.  So what rings does Windows operate under?  The user mode is running in privilege level 3, or ring 3.  The kernel mode is running in privilege level 0 (zero), or ring 0 (zero).  

Ring 0 (zero) allows for unfettered access to underlying hardware.  At this point there are no more safeguards, if an attacker is able to control kernel mode it can execute any CPU instructions or reference any memory address. Which is why kernel mode is so careful to only allow the most trusted functions of the operating system and drivers to access it.  On the opposite end of the privilege spectrum the user mode has no ability to directly access hardware or reference memory.  It is imperative that we say directly in this case, because user mode can access Windows system APIs to access hardware or memory.  

Whenever a Windows process starts it has its own private memory space allocated however, the kernel-mode OS and device driver code will share a single virtual address space.  Each memory page in virtual memory is tagged to indicate which ring level the processor must be in to read and/or write to that page.  Therefore, pages in system space can only be accessed from kernel mode.  Whereas, all pages in the user address space are accessible from both kernel mode and user mode.  Another tagging option is for processors that support no-execute mode Windows will mark pages containing data as non-executable.  More can be learned about this in a future blog post on Data Execution Prevention (DEP).  As mentioned above, Windows provides absolutely no protection for kernel mode.  This is why device drivers can be so dangerous.  Once that driver is in kernel mode it has complete access.  In order to help mitigate some of this risk Windows created the driver-signing mechanism.  If the user attempts to add an unsigned plug-and-play driver it will warn the user of the dangers of this.  

According to Microsoft's MSDN and the Windows Internal book all Windows 10 versions after the July Anniversary Update (1607) must be signed by only two of the accepted certification authorities, and then must be submitted to the System Device portal for attestation signing.  The release of Windows Server 2016 took an even stronger approach to device driver certification.  In order to install a driver on Windows Server 2016 that driver must first be tested with the Windows Hardware Quality Labs (WHQL) certification.  

It is possible for a user application to switch from user mode to kernel mode when they make a call to a system service.  An example would be the Windows ReadFile function.  Which will need to call the internal Windows routine that actually handles reading data from a file.  That routine accesses internal system data structures, and therefore must be run within the kernel mode.  Another example is graphics-intensive applications such as Microsoft Paint or a video game for that matter.  You can even open your Task manager and select Performance monitor.  These statistics shown can be filtered to show the amount of time between kernel mode and user mode.  Note that the switch between user mode to kernel mode is only affected when the specific Windows APIs are called that require the system services.  

Sources and Inspiration

Ryan Villarreal

About Ryan Villarreal