Recently we have noticed some Win32/Rovnix samples (detected as TrojanDropper:Win32/Rovnix.K) causing the BSOD on Windows 7 machines. We spent some time investigating this situation and discovered an interesting story behind the BSOD.

Analyzing the crash dump

We first saw TrojanDropper:Win32/Rovnix.K in October 2013. During a normal Windows Boot the malware will cause the BSOD.

The BSOD 

Figure 1: Rovix BSOD screenshot

To start, let’s analyze the crash dump using windbg: 


kd> !analyze -v

*******************************************************************************
*                                                                             *
*                        Bugcheck Analysis                                    *
*                                                                             *
*******************************************************************************

ATTEMPTED_WRITE_TO_READONLY_MEMORY (be)
An attempt was made to write to read only memory.  The guilty driver is on the
stack trace (and is typically the current instruction pointer).
When possible, the guilty driver's name (Unicode string) is printed on
the bugcheck screen and saved in KiBugCheckDriver.
Arguments:
Arg1: 867bf4b1, Virtual address for the attempted write.
Arg2: 02f72121, PTE contents.
Arg3: 8a733c44, (reserved)
Arg4: 0000000b, (reserved)

As shown above, the BSOD is caused by writing to a read-only memory address (0x867bf4b1).

We can then use the  .trap command to get further information.

kd> .trap 0xffffffff8a733c44
ErrCode = 00000003
eax=00000000 ebx=00000000 ecx=867bf4b1 edx=80ba6848 esi=80ba5a2e edi=80ba6876
eip=80b9be24 esp=8a733cb8 ebp=8a733cd4 iopl=0         nv up ei pl zr na pe nc
cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00210246
80b9be24 c601cc          mov     byte ptr [ecx],0CCh        ds:0023:867bf4b1=8b


According to the above information, the BSOD is raised when Rovnix is trying to write to address 0x867bf4b1 (ecx).

Let’s have a look at that address:

kd> u 867bf4b1
storport!RaDriverScsiIrp
867bf4b1 8bff            mov     edi,edi
867bf4b3 55              push    ebp
867bf4b4 8bec            mov     ebp,esp
867bf4b6 53              push    ebx
867bf4b7 56              push    esi
867bf4b8 57              push    edi
867bf4b9 a100d07c86      mov     eax,dword ptr [storport!WPP_GLOBAL_Control (867cd000)]
867bf4be 8b7d0c          mov     edi,dword ptr [ebp+0Ch]


We know Rovnix is trying to write a byte 0xcc at address storport!RaDriverScsiIrp.
However, it didn’t make the address writable, so it’s causing a write to read-only memory BSOD.

The trick behind this BSOD

Why is Rovnix trying to put a 0xcc byte at a driver dispatch function? Isn’t that going to cause an exception? We recall having seen this trick before (used by Win32/Alureon) – it’s a tricky hooking mechanism. In short, it works like this:

  1. The malware modifies KiDebugRoutine to point to its own debug routine.
  2. When the 0xcc is executed, an exception is raised, and the control is  transferred to Rovnix’s own debug routine.
  3. In Rovnix’s own debug routine, it modifies the EIP register in the saved context to its own function (hook).

Is that the end of the story? No, not yet.

Windows XP v.s. Windows 7

Did the malware author test the sample before releasing it? Probably yes, but perhaps only on Windows XP. We tried this sample on a Windows XP machine, and it doesn’t crash - the KiDebugRoutine trick works as expected.  This means that on Windows XP, the memory address should be writable. However, the section characteristics are read-only for both cases. So why is the address writable on Windows XP but not Windows 7?

The answer is a bit surprising – it lies in the value of SectionAlignment in PE header.  On Windows XP, the SectionAlignment for the disk driver is less than 0x1000 - whereas on Windows 7 it is 0x1000.  For the SectionAlignment < 0x1000 case, Windows loads the whole PE file as a single subsection, and the whole subsection is writable regardless of the section characteristic in the section table. For the SectionAlignment >= 0x1000 case, it is loaded section by section and each section has its own section characteristic (specified in the section table).

Win XP 

Figure 2: SectionAlignment < 0x1000 on Windows XP

Win 7 

Figure 3: SectionAlignment =0x1000 on Windows 7

That’s the whole story of this BSOD – “Rovnix’s fault- so core dumped”.

Our TrojanDropper:Win32/Rovnix.K description has full remediation steps to fix this issue.

As always, the best protection from this and other threats is to run up-to-date real-time security software such as Microsoft Security Essentials and the Enhanced Mitigation Experience Toolkit.

Chun Feng and Jim Wang