
Have you ever wondered what happens to the operating system at the moment when it draws its logo and says “Starting Windows”? And in general, why does it take a long time to load? After all, when starting the system, no tasks that are difficult from a computational point of view are solved at all!
What then implies the boot of the operating system? For the most part, this is the projection into memory of executable modules and the initialization of service data structures. The data structures live in memory, so operations with them should be fast in theory. Everything suggests the idea that time is eaten up precisely by the process of loading executable modules into memory.
Let's see for the sake of interest, which modules, in what quantity and in what order are loaded when the OS starts. To find out, you can, for example, get a system boot log. The experimental OS in my case is Windows 7 Enterprise x64. Log the boot process using the kernel debugger. There are several options for kernel debuggers, I personally prefer WinDbg. We will also need some tools to magically transform the log into something more pleasing to the eye.
Mining and crafting
Debugging setup is good for Google, so I will not describe this process in detail. Since we are interested in everything that happens since the start of the system, we need to check the “Cycle Initial Break” item, with which the debugger will stop as soon as the kernel debugging subsystem is loaded into the debugged system. Duplication of output to a file can be accomplished using the ".logopen" and ".logclose" commands, it is simple. Another useful command is ".cls". It clears the command screen, and yes, only the command screen.
')
The function of interest is MiCreateImageFileMap. This is an internal memory manager function that projects the executable file into memory. Projecting into memory occurs when creating a section, for example, when running an executable file. However, note that if an executable file is projected into memory, this is not a guarantee that its code will be executed! This function simply creates a projection, most often “in reserve”, so that if someone decides to launch the module for execution, it can save its loading time. Put a logging breakpoint on this function.
If you have enough mana, enter the following command:
bu nt!MiCreateImageFileMap "dt nt!_EPROCESS -d ImageFileName @$proc; dt nt!_FILE_OBJECT -d FileName @rcx; g"
The magic line literally means the following:
- bu (Set Unresolved Breakpoint) - set an unresolved breakpoint. Not that someone or something is not allowed, just to install it, you need to decide what address to put it on. The fact is that it is not known in advance what address it should be located at. When any module is loaded, the presence of the necessary function in it is checked, and if such a function is found, a breakpoint is set automatically. This method of installation is indispensable when the ASLR is enabled — randomization of the address space, since the modules will be loaded at different addresses each time, and a breakpoint set at a fixed address is likely to be out of business.
- nt! MiCreateImageFileMap is a symbol to stop at. In WinDbg, an entry in the form 'module_name! Function_name' is accepted. In this case, nt is a predefined alias for ntoskrnl.exe.
- This is followed by part of the WinDbg script that will be executed each time you stop on this function. “Dt nt! _EPROCESS -d ImageFileName @ $ proc” in Russian means “display the ImageFileName field of the _EPROCESS structure from the nt module, provided it is mapped to the address specified in the“ current process ”pseudo register.” Next after the delimiter ";" the command means approximately the same thing, only the structure address is taken from the rcx register, in which the first parameter of the function is passed to the Microsoft x64 ABI. “G” means “go”, i.e. continue execution.
A small recommendation on the use of logging breakpoints: try not to use debugger extensions (commands starting with "!"), Since in this case logging will be performed an order of magnitude slower.
Go! Press the breakpoint brake and wait. I waited until the desktop was loaded, i.e. I logged in The resulting "crop" is slightly edited, all unnecessary trimmed for ease of further processing and fed buddy to the python. Let's not focus on parsing the log. We only note that the graph fit into the shape of the Archimedes spiral with further correction manually, since the overlapping of nodes occurred on each other. The resulting graph takes into account the order of loading libraries. Unfortunately, we had to sacrifice considering the order of loading executable files relative to libraries for the sake of readability of the graph.
Star chart

Conditionally select several download groups.
OC starts working in the ntoskrnl.exe module, which is the OS kernel. And more specifically, with the KiSystemStartup () function. Together with the loaded system components, it forms the foundation of the OS: separation of operating modes, basic services for user applications, etc. This group also includes drivers marked for boot during system startup. In a nutshell, in this shell is born OS Windows.

The next node is the session manager. It is represented by the smss.exe, the first after the system process starting in Windows. The process is notable for the fact that it is a native (native) process of Windows, that is, it does not use the Win32 subsystem, which in general is not yet loaded. This process uses only native operating system services via ntdll.dll, which is a user mode interface for OS services. Also, this process is a trusted component of the operating system and has exclusive rights, for example, it can create security tokens. But its main purpose is to create sessions and initialize subsystems, both graphic and various executables (Windows, POSIX). This shell is rewarded to each according to his needs.

A logon group consists of several processes. In general, they are responsible for initializing sessions. This includes displaying the welcome screen, creating desktops, starting autoload processes and initializing the security subsystem, etc. This broom sweeps away all outsiders.

The most massive was the group of services. In many respects, it owes its volume to the SuperFetch service. This is the same one, about which they say that on weekends it preloads the office package, and at the beginning of the working week - Steam with toys. Superfetch loads a huge number of modules at system startup, so that “everything will work faster”. And besides him, the system lacks service applications and autorun drivers. I think everyone saw the “Services and Applications” snap-in. This star of life gets everything in the system that is needed and not very.

Last I will note favorite all explorer.exe. It is noteworthy that by the time of its launch all the modules used by it are already loaded into memory. The screenshot also got a certain vcredist_x64.exe - the poor fellow was lying on the desktop of the experimental virtual machine and was loaded into memory by the conductor.

In general, there are many ways to be loaded into the memory of the module. For example, it is enough to request information from the resources of the executable file, including its icon. Specifically, in this example, the explorer checked whether this program requires elevated privileges, i.e. is it worth drawing a corresponding picture with a yellow and blue shield to the icon? Once again, I note that loading a module into memory does not mean the execution of its code!
Personally, I keep the resulting picture at hand. On it dependences, for example, drivers are well traced. Also paired with the utility Sysinternals Autoruns, you can see at what stage of loading these or those modules are tightened.
Boot graph was built for Windows 7 Enterprise x64, installed on a VMware virtual machine. Below are the vector image of the graph and directly the file in gml format, with which you can play in any graph editor.
GML GraphVector image of a graphAttention! Bonus!
Download graph for clean Windows 8 Enterprise x64 on a live machine;)
GML GraphVector image of a graphIngredients:
WinDbg @
msdn.microsoft.com/en-us/windows/hardware/gg463009.aspxPython @
www.python.orgNetworkX @
networkx.lanl.govyEd Graph Editor @
www.yworks.com/en/products_yed_about.htmlHands @ Shoulders