Removing Microsoft Windows Vista’s Test Mode watermark

Overview

If you're like Chris Holmes, you hate not being able to run unsigned drivers on the Microsoft Windows Vista x64 platform. I share his pain, however. Projects like ATItool and CoreTemp don't have the financial backing to afford having their drivers tested and signed.

With Atsiv's death around the corner, and pressing F8 at every reboot being ridiculously annoying, the only alternative is to test-sign the drivers yourself and boot Microsoft Windows Vista into test mode. Self-signing and the configuration of boot options is outside the scope of this hack.

Enabling test mode on Microsoft Windows Vista comes with the penalty of marking up your desktop, in all four corners, with the text "test mode".

Discovery

Having experience in reverse engineering Microsoft Windows components, I was able to quickly identify user32.dll as containing the code responsible for tarnishing my desktop. User32.dll is a core Microsoft Windows component housing API for most of the backend user interface (UI) stuff like window handling.

If you open a copy of User32.dll within IDA Disassembler Pro and suck in the debugging symbols, you will find reference to a function called LoadAndSendWatermarkStrings, responsible for displaying watermarks on your desktop (i.e. build string, eval. text)

.text:77D6439F    xor esi, esi
.text:77D643A1    push esi
.text:77D643A2    call _LoadKeyboardLayoutWorker@20
.text:77D643A7    call _LoadPreloadKeyboardLayouts@0
.text:77D643AC    cmp dword_77DCAC98, esi
.text:77D643B2    jnz short loc_77D643BF
.text:77D643B4    call _LoadAndSendWatermarkStrings@0
.text:77D643B9    mov dword_77DCAC98, edi

What's particularly interesting at 77D643AC is the comparison of some unknown global variable to zero and subsequent jump if it's not. As it makes no sense to paint watermarks on the desktop more than once, Microsoft Windows developers added a simple check we can exploit here. If we've painted the watermark, don't bother doing it again.

References to dword_77DCAC98

As our mystery variable isn't read or written to from anywhere else, it's pretty safe to assume the purpose of this variable is to keep track of whether or not the desktop was painted on. I have renamed the variable and provided some pseudo-code below, for readability.

_LoadKeyboardLayoutWorker(0,...);
_LoadPreloadKeyboardLayouts();

if(!g_bDesktopAlreadyTarnished) {
    LoadAndSendWatermarkStrings();
    g_bDesktopAlreadyTarnished = true;
}

Patching

As the newly discovered variable's value isn't assigned anywhere before its value is checked, we can bypass the painting of the desktop by simply changing the initialized value from zero to one.

You can do this by simply following this variable in IDA Pro Disassembler's hex view, jotting down the variable's file offset (in this case 69C98), and opening it up in your favorite hex editor (i.e. XVI32).

XVI32

Take note that although the starting offset is 69C98, values on the Intel architecture are stored in little-endian format, therefore to increment this DWORD (four bytes) by one, you must edit the right-most byte.

Replacing the old library with the new is left as an exercise for the reader.