..-----------------------------------------..
..    inside BSOD                          ..
..                                         ..
..              (disasming experience)     ..
.._________________________________________..


   I think, all of you have ever saw a BSOD (aka Blue Screen Of Death). If
   you had worked on win95, u saw it a very-very often. Imho,it's the best
   development of Microsoft programmers :) Blue screen pleases our eyes by
   nice-formated strings of elaborated charz (heh, matrix own u  -  editor
   notice) and you already going to press reset.  Nothing  else can't help
   now...


   If we'll take a look at a windoz-series, we'll see a bsod evolution. In
   win9x it was stupid standart text with some pseudo-graphics, but now it
   has nice design,font and cool display of memory-dump process percentes.
   Damn, it's beautifull! ))


   In system API'z on kernel level there is only one function,which called
   on some  critical system  errors and should register  them or lock  the
   kernel (BSOD). In general, there are three ways to control errorz. It's
   a status codez, SEH (Structured Exception Handling) and method,  called
   "bug checks".


   The  first type is the most  primitive.  Lotz of  functions  returns to
   us exactly this stupid codez, which gives us status of called function.
   It's well-known shit like STATUS_SUCCESS, etc.


   The second type  -  more modern and supported on kernel level.  I don't
   describe  it here,  coz there  are a good  docz  about  it.  I.e.  Matt
   Pitrek's  "A  Crash Course on the  Depths of Win32 Structured Exception
   Handling" or "Win32  Exception  handling for  assembler programmers" by
   Jeremy Gordon.


   This article is denoted to third type,aka bug checks. As i told before,
   in  kernel there  is only  one functions  to  use  this type  of  error
   handling technique,  which halts system and shows us BSOD.  We can call
   it in 2 ways, defined in DDK:

VOID KeBugCheck( IN ULONG  BugCheckCode );

VOID KeBugCheckEx(IN ULONG  BugCheckCode,IN ULONG_PTR BugCheckParameter1,\
     IN ULONG_PTR  BugCheckParameter2, IN ULONG_PTR  BugCheckParameter3, \
     IN ULONG_PTR  BugCheckParameter4 );

   In documentationz its recommended  to use second function,  coz previous
   is older and lame. The funcz are exported by system module ntoskrnl.exe,
   which is an execurtive part of kernel.


   Btw, all my researchs i done on Windoz XP  Pro 5.1.2600 SP1.  Microsoft
   like to change internal api in new releasez so much!  I.e. KeBugCheckEx
   in  XP and KeBugCheckEx in w2k  server are two different functions, but
   in fact, they do the same things.


   Well, let's look into BSOD sourcez. We need this warez:

   		- PE Tools (http://www.uinc.ru)
   		- IDA Pro (dunno where u can dl it)
   		- SoftICE  or all  DriverStudio, its not importnant


   While ida disasming ntoskrnl, we can look at api'z, which  exports this
   module and get some of them.


   The  main difference  between  KeBugCheck and  KeBugCheckEx consists in
   that, what first func just ignores last 4 argz.

    KeBugCheck:
	  		xor     eax, eax
		  	push    eax
			 	push    eax
			 	push    eax
  			push    eax
  			push    eax
  			push    [esp+14h+arg_0]
  			call    sub_420A66				;general func


    KeBugCheckEx:
  			push    ebp
  			mov     ebp, esp
  			push    0
  			push    [ebp+arg_10]
  			push    [ebp+arg_C]
  			push    [ebp+arg_8]
  			push    [ebp+arg_4]
  			push    [ebp+arg_0]
  			call    sub_420A66				;general func
  			pop     ebp


   All algorithm of BSOD work we can split on this steps:
      1) get exception code (BugCheckCode)
      2) in  some cases  do  additional  funcz (used  last  4  argz  of
         KeBugCheckEx)
      3) at last, generating BSOD and display it.


   We'll start from the beginning. Totally, in DDK  defined 0E4h  diffrent
   exception codez (look bugcodes.h). And the first, what the func does,is
   checks code of call  -  is it from system kernel,  or from some device?
   Yeah,  drivers also can crash your  winXp box,  they also have  special
   exceptionz (0E5h). The chech is easy:

				mov     ebx, [ebp+arg_0]		;BUG code
				[...]
				cmp     ebx, 0E5h
				[...]
				jnz     short loc_420AA8		;if system code
				call    sub_420778				;if  NOT  system  code  --
												;process user code
				push    3
				call    ds:HalReturnToFirmware

   Before check bug code, system also stores registers  cr0-cr4,  dr0-dr3,
   dr6, dr7, gdt, idt, tr, ldt at fs:20h + 1ch.

   Some thingz in next actionz i can't understand.Why it checks code group
   again  by   another   method?    At   first,   function   handles   7fh
   (UNEXPECTED_KERNEL_MODE_TRAP).After it, algorithm bifurcates and checks
   errors with codez more than and less than 7fh. Maybe it's used,cuz some
   bug  checks are occures in system more  often.  These most usable codez
   are:

	0Ah (IRQL_NOT_LESS_OR_EQUAL)
	1Eh (KMODE_EXCEPTION_NOT_HANDLED)
	23h (FAT_FILE_SYSTEM)
	24h (NTFS_FILE_SYSTEM)
	7Fh (UNEXPECTED_KERNEL_MODE_TRAP)

   Errors with codez less than 7fh checked by subtraction:

				mov     eax, ebx				;BUG code < 7fh
				sub     eax, ecx				;eax = BUG code - 1eh
				jz      short loc_420B34		;if BUG code == 1eh
				sub     eax, 5
				jz      loc_420C07				;if BUG code == 23h
				dec     eax
				jz      loc_420BA6				;if BUG code == 24h
				[...]

   Errors with codez, more than 7fh are hardcoded (constants) and  checked
   by cmp:

				mp     ebx, 8Eh				;BUG code > 7fh
				jz      loc_420B34				;if BUG code == 8eh
				cmp     ebx, 0A5h
				jz      short loc_420C07		;if BUG code == 0a5h
				cmp     ebx, eax				;eax == 0c5h
				jz      short loc_420C07		;if BUG code == 0c5h
				[...]


   Other codez are not checked directly, so  look attach in  ./include/ or
   disasms of ntoskrnl in your system.  And another  one  case  -  in this
   code  fragment i've  discovered,  there is  a  handling  of uknown code
   0C00002D1h, which description i can't find anywhere.  Maybe,  it's some
   debug  code and m$-coderz forget to remove it? :)


   The next step - execution special funcz in some cases and check argz of
   KeBugCheckEx (4 last ones). It stores them in this structure:

.data:00475C60	KiBugCheckData  dd ?			;BUG code
				dword_475C64    dd ?			;[ebp+arg_4]
				dword_475C68    dd ?			;[ebp+arg_8]
				dword_475C6C    dd ?			;[ebp+arg_C]
				dword_475C70    dd ?			;[ebp+arg_10]

   It handles not all codes here, only this:

	0Ah (IRQL_NOT_LESS_OR_EQUAL)
	4Ch (FATAL_UNHANDLED_HARD_ERROR)
	50h (PAGE_FAULT_IN_NONPAGED_AREA)
	0BEh (ATTEMPTED_WRITE_TO_READONLY_MEMORY)
	0D8h (DRIVER_USED_EXCESSIVE_PTES)

   Others are not handled directly or just ignored.

   And the last step  -  genereating text and displaying BSOD.  But  right
   before it,  there are some lame hacks with  debugger (if  it turned on,
   sure). It's strange, but in code we can see what  microsoft programmers
   used Kd. I can't belive it,  what  they never  heard about  SoftICE and
   using their own lame shity tool, which  also works  only  with *remote*
   computer. But they do:

				cmp     KdDebuggerEnabled, 0
				jz      short loc_420ED3		;If no debuggers enabled
				push    dword_475C70
				push    dword_475C6C
				push    dword_475C68
				push    dword_475C64
				push    KiBugCheckData
				push    offset aFatalSystemErr 	;"\n*** Fatal System " ...
				call    DbgPrint

   Then, it calls KfRaiseIrql. Formating BSOD-strings on screen  organized
   with  fucntions  like  Inbv* (InbvSetTextColor,InbvEnableDisplayString,
   InbvDisplayString,...), which are also consists in ntoskrnl.exe.


   The last code strings - system halt, or debuger call (if it turned on).

   So, what is how BSOD works... It's tangled a bit, but in general,  code
   is easy. And its the most important part of wind0z kernel =) In archive
   u'll find listing from ida (without included procedures).  But  for the
   better understanding it's a usefull to disasm it by yourself :)


   p.s. thx to groups MoskovSKAya, Ska-P, SKA ChartBusters collection cdz,
   SKA  attack and to  whole disk "SKA Punk" (Mad Sound Collection)  for a
   nice background, created while i wrote this article.
