There are many processes running on a typical Windows system – here are some of the “well known” ones (based on their executable names), very briefly summarized:
- Explorer.exe – the default Window shell
- SvcHost.exe – generic host for services, used mostly for hosting built-in Windows services
- Lsass.exe – in charge of authentication
- Csrss.exe – the Windows Subsystem process, helps in managing processes that belong to the Windows Subsystem.
- Smss.exe – the session manager, tasked with creating new sessions as needed
- WmiPrvSe.exe – worker process(es) for the Windows Management Instrumentation (WMI) service
On the surface, these all look roughly the same – just user mode processes. Taking a deeper look, we can see which APIs these executables are using. All processes need access to the kernel for operations like accessing files, allocating memory, creating threads, and others. Some may require more specialized services, like a Graphical User Interface (GUI).
Gain Insider Knowledge
The “normal”, documented, Windows APIs are provided through a set of subsystem DLLs. Here are the most important ones:
- Kernel32.Dll, KernelBase.Dll – the most fundamentals APIs, used for working with processes, threads, DLLs and virtual memory, etc.
- User32.Dll – provides the classic window management APIs, like creating and managing windows, working with UI messages, and more.
- Advapi32.Dll – provides functions for working with security and the Registry.
- Gdi32.Dll – supports the classic Windows graphics API (Graphics Device Interface), used by many applications for (mostly) 2D drawings.
Explorer.exe, for example, has a GUI, so needs to call functions from User32.Dll, but also Kernel32.Dll/KernelBase.Dll. Applications that do not have a GUI do not need to use User32.Dll or Gdi32.Dll.
What do the aforementioned DLLs call? How do they reach the kernel? The answer lies in another two DLLs, NtDll.dll and Win32u.Dll. These are the ones making the actual system calls that power the higher level APIs. For example, the CreateFile API from kernel32.dll calls NtCreateFile in NtDll.dll (the system call). The implementation of NtCreateFile transitions to kernel mode by issuing a machine instruction (syscall on x64), placing a system call number in a register (EAX on x86/x64) before making the call. Win32u.dll provides the system calls for User32.Dll and Gdi32.dll, while NtDll.dll provides the system calls for Kernel32.Dll, KernelBase.Dll, and AdvApi32.Dll.
Some executables, however, don’t link with the subsystem DLLs at all. Rather, they use NtDll.Dll directly. These applications are called native applications. Examples include Smss.exe and Csrss.Exe. The following figure summarizes the three application types.
As can be seen in the diagram, GUI applications use Kernel32.Dll, KernelBase.Dll (always), as well as User32.Dll and Gdi32.Dll. Console based applications do not need User32.Dll and Gdi32.Dll. While native applications only use NtDll.Dll.
The API implemented by NtDll.dll is called the Windows Native API. It’s mostly undocumented, and that is intentional. Microsoft would like developers to use the documented Windows API only.
You can find much more information on the native API in my book “Windows Native API programming”.