Home > Technology > Change Windows 8 BSOD color and emoticon

Change Windows 8 BSOD color and emoticon

I still remember that during Win7 era, I found how to change the background color of BSOD. Unfortunately, I was just one step later than Mark.
http://blogs.technet.com/b/markrussinovich/archive/2010/12/14/3374820.aspx
Now it’s good chance to take one step ahead.

First, let’s take a look how BSOD screen is shown.

NT kernel call nt!BgpFwDisplayBugCheckScreen to display the BSOD screen. Go through this function, we can see some key calls:

1. Fill the background:

867 8116a1a0 8b0da00f1e81 mov ecx,dword ptr [nt!BgpCriticalState+0x50 (811e0fa0)]
867 8116a1a6 8b4914 mov ecx,dword ptr [ecx+14h]
867 8116a1a9 ff711c push dword ptr [ecx+1Ch]
867 8116a1ac 8bf8 mov edi,eax
867 8116a1ae 8bf7 mov esi,edi
867 8116a1b0 6bf638 imul esi,esi,38h
867 8116a1b3 81c6e8781d81 add esi,offset nt!DisplayStateList (811d78e8)
867 8116a1b9 e88df2ffff call nt!BgpClearScreen (8116944b)

nt!BgpClearScreen has one input parameter which specify the color to fill. From above assembly code, we know that the color now saved at address ecx+1Ch. The color is 0xff2067b2 (ARGB), it looks like blue, which is exactly the color of Windows 8 BSOD background. If we change the value to other color, such as pure red, after nt!BgpClearScreen is called, you can observe that the whole screen is filled with red color.

Where does the color come from?

nt!BgpCriticalState is a global structure which is initialized at a very early stage during NT kernel initialization. It defines some string which will be displayed on BSOD screen, including “Your PC ran into a problem and needs to restart.”. At offset 0x50, it defines the character context of the critical state. At offset 0x14 of character context is the region handle, it’s a pointer to a text region. At offset 0x1c of the text region is the text attribute. The text attribute defines some environment parameters, such as background color, foreground color, etc. Background color is at offset 0 of text attribute, ecx+1Ch. It’s pushed to the stack as the input parameter of nt!BgpClearScreen.

2. Draw the text:

892 8116a1d8 57 push edi
892 8116a1d9 ff7608 push dword ptr [esi+8]
892 8116a1dc 68187a1d81 push offset nt!BcpEmoticon (811d7a18)
892 8116a1e1 e868f8ffff call nt!BcpDisplayCriticalString (81169a4e)

nt!BcpDisplayCriticalString has three input parameters: the unicode string to display, font size, display type. The above call will display emoticon “:(” with font size = 0x6f, and display type = 2. If we change the unicode string to “:)”, BSOD will display a smile face instead of a sad one. nt!BcpEmoticon is defined as unicode string “:(“.

Within function nt!BcpDisplayCriticalString, it will fill also fill each character image with the same background color as nt!BgpClearScreen. So in order to let the text on BSOD screen has the same color as nt!BgpClearScreen, you should change the global definition in nt!BgpCriticalState.

With this runtime patch, you cannot simply change the displayed information to any text you like. The reason is, NT kernel create the image cache according to font size for each character in these critical strings. If dynamically change the string, the font image will not always match with the cached one, then the patched string will not be displayed. However, change from 😦 to 🙂 should always work.
See the modified BSOD screen:

Categories: Technology
  1. January 15, 2015 at 11:23

    wheres the run-time patch or a how to change you’re information is great but you left out the steps on doing it ourselves, like how are you editing these calls and how does the average user do it? did you make a script or a program for download I feel like you did provide a tool because you said “with this runtime patch” but the link is missing

  2. April 3, 2016 at 12:13

    I could imagine replacing the sad face emoticon with “Oh shit!”

    It must happen.

  1. No trackbacks yet.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.