Adjust a custom blue screen of death
It turned blue, is something wrong with it?
BSOD is the kernel response to an unsolvable particular situation. If you see it, it means that something has happened and it is definitely wrong.
The kernel environment imposes many restrictions on the programmer's free hand: you consider IRQL, sync access to shared variables, and you do not stay too long in ISR, you should verify any data from the userland… Breaking at least one of the rules, you will receive a bunch of phrases in a standard VGA video with the poor palette.
In fact, this makes sense. If in the user mode the application simply closes without even removing a trail after itself (that the kernel will do that), so it will not break the integrity of the entire system.
In kernel mode everything is different. First, kernel mode modules are thin and fragile. The kernel and its components like a giant clock with a huge number of components. Here is the point, if one screw is damaged, the whole system stops. Of course, there are modules, which failures logically have no effect on the OS. It would be possible to isolate the faulting module. However, the logic is that the kernel component actively cooperates with other components and the OS kernel, therefore, the failure in one component can lead to a chain of failures in the other components, eventually destroying all kernel structure, or even worse to damage the user's data. In addition, debugging these bugs is extremely difficult.
However, let's say you are the entry level user. What would you do if you see a blue screen?
Now let’s suppose that you are the system administrator. What would you do if you see a blue screen? Well, before you start reading the error code and so on.
Let’s say you are the kernel coder, and you had a bunch of times to see this sophisticated debugging output. What do you think when you see it again?
I think most people are familiar with this name. Russinovich is cool, though he is cunning. NotMyFault is an interesting one among useful utilities from Sysinternals. It can generate various errors in the kernel mode that BSOD displays. In addition, it has an interesting feature to change the background color and font screen of death. This utility is so cool that even comes with source! However, as I said earlier, Russinovich is very cool ...
I could not understand for some time what is happening: the header file ioctlcmd.h has the following code:
#define IOCTL_BSOD_COLOR (ULONG) CTL_CODE(FILE_DEVICE_MYFAULT, 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS)
But this is the only place where is a trace of code that is responsible for changing the screen color of death. Myfault.c driver file contains a kernel book!
Before you plan to splice something in the kernel, do not be too lazy to look at MDSN, since there are plenty of the callback-functions in the kernel. So the same is with the blue screen: there is a callback-function, a call that occurs immediately after displaying the blue screen. It is registered by the following function:
__out PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord,
__in PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine,
__in KBUGCHECK_CALLBACK_REASON Reason,
__in PUCHAR Component
This callback-function indicates the reason for its registration, either it needs to finish something in a dump or keep track when the dump is written, or specify as a reason KbCallbackReserved1. This parameter is private and called before any other callback-functions in the event of critical errors.
In addition to this callback-function, there is another one that is similar to that and it is recorded by the following function:
BOOLEAN KeRegisterBugCheckCallback(It notifies the registered module about the critical error, after the worst has already happened, and you can restart the computer.
__out PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
__in PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine,
__in_opt PVOID Buffer,
__in ULONG Length,
__in PUCHAR Component
When I saw automatically assigned function name CallbackRoutine in the disassembled listing, I did not even know where else to go in order to find this magic code. And here it is! Wait ... what is it? “Mov - out, mov – out”. I do not know about you, but I had a feeling that I was deceived. I was waiting for the miracles and fairy tales. And then Mark takes the VGA ports and through them, he changes the palette. That's palette! Namely, he changes the blue color to the green, so the background becomes green:
mov edx, 3C8h ; port, where is recorded the color index in the palette DAC
mov al, 4 ; was blue
out dx, al
mov al, 0x00003F00 ; will become green (6 bits per color)
lea ecx, [edx +1] ; edx = 0x3C9 - port for recording the color components
mov edx, ecx
out dx, al ; set Red component
mov eax, 0x00003F00
shr eax, 8
out dx, al ; Green
mov eax, 0x00003F00
shr eax, 10h
out dx, al ; Blue
Well, that is going to be fine.
Enjoy the little things
An animated boot screen of OS gives a good idea of what you can squeeze out of the VGA video mode. You can even guess that there is the code for rendering graphics already in the kernel. I will not keep you waiting, we are interested in a function family Inbv*. Please note that some of them even are exported from the kernel. Here is an example of reverse KiDisplayBlueScreen that can help us to figure out how to use these functions:
InbvAcquireDisplayOwnership(); // Now we give a command
InbvResetDisplay(); // we clear the screen and reinitialize the palette
InbvSolidColorFill(0, 0, 639, 479, 4); // we fill with all the blue paint
InbvSetTextColor(15); // we use white
InbvInstallDisplayStringFilter(0); // reset the callback-function to display a text string
InbvEnableDisplayString(TRUE); // we allow writing lines
InbvSetScrollRegion(0, 0, 639, 475); // we narrow the scope of the screen
InbvDisplayString(«Hello world!»); // we display the text
These functions can be safely used in the code of its driver. But do not forget as soon as you switch to this mode, you cannot easily get out of it.
Here is the most remarkable function – InbvBitBlt:
VOID NTAPI InbvBitBlt(IN PUCHAR Buffer, IN ULONG X, IN ULONG Y)
Guess what? It directly renders BMP image (read, BMP file with 256 colors without the file header)! The only problem is that it is non-exportable. Fortunately, it is just a cover similar to VidBitBlt function. The role of the cover is only in sync rendering, but we were not interested in it for now. VidBitBlt is exported from bootvid.dll module. So we seek the loaded modules and parse an export table, and then we get a pointer to this magical function. Next, you're limited only by your imagination.
Enjoy this video!
|Vote for this post
Bring it to the Main Page