Up until a few years ago, I was a huge OS optimization junkie, but thankfully the level of obsession has gone down in recent years. I still remember the time when a friend had come over to exchange some data and we spent almost an hour trying to get the bloody network sharing to work in XP. As it happened I was in my 'no open ports' OCD stage and I had "fixed" Windows so that no TCP/IP ports were left open. Apparently that involved neutering netbt/netbios and other networking components to the point where getting them back was a chore. I can't remember but I think we ended up setting up an FTP server.

So, the new me, doesn't care too much about crap that runs on system startup or the terrible service-bloat that the popular malware iTunes forces on you just to copy a mp3 file to a fucking flash drive. Ofcource, I also do realize that many of the Windows optimization tips are just snake-oil and there won't be a perceptible difference in OS performance (or at least, one that justifies all the time wasted troubleshooting problems caused by your b0rked system state). Anyway, I recently moved up to Win7 from Vista and as I was installing my mouse (Razer Diamondback 3G) driver, my dormant OCD stirred from its deep slumber and messed with my head.

I realized I wasn't really using the config tool for any purpose other than to set my mouse's CPI to 800 instead of the native 1800 and that I ought to get rid of it. Ofcource as it turned out the mouse doesn't even have any internal memory to save this setting and that the mouse config tool, on system startup, sets the dpi to 800.

After poking around it seemed like the tool was functionally separated into 4 main binaries : razerhid.exe, razertra.exe, razercfg.exe, razerofa.exe. Just by looking at the naming I guessed that the razercfg.exe was the config tool itself, the razertra.exe was the system taskbar (tray) tool and the razerofa.exe was the on-the-fly sensitivity tool. I didn't quite know whatrazerhid.exe was but I just guessed it was something to do with USB HID class devices. The process hierarchy had razerhid.exe as the parent process, with razertra.exe and razerofa.exe as child processes. And razercfg.exe was the child process of razertra.exe

Now, I just had to find out where the settings were stored, and how specific commands were sent to the mouse to change the CPI. The registry was the first guess so I ran a registry monitor to get the location of the settings. So, now I knew that the settings were stored at HKCU\Control Panel\Mouse\razer\* and the one I was primarily interested in was called Dpi1600Enable. I now needed to find out which of these binaries was actually sending the command to the device driver. I fired up IDA and went rummaging through the imports table and possible LoadLibrary/GetProcAdress calls in razercfg.exe and razerhid.exe to see if I could find anything of interest. For some reason trying to debug and trace through razerhid.exe caused random bluescreens with the mouse driver. I didn't want to spend time tracking that down, so I slapped on KD and hooked up my laptop through 1394 and used a mixture of static analysis with IDA and live debugging with KD to get an idea of what was happening.

After some more poking around, one thing seemed fairly certain. razercfg.exe wasn't responsible for actually programming the mouse's driver and only seemed to deal with registry keys. I now concentrated all my efforts on razerhid.exe as it had the delicious kernel32!DeviceIoControl import that was probably doing all the dirty work of programming the mouse. After considerable debugging and tracing through the god-awful MFC disassembly I hit upon a function that was possibly performing the actual device programming.

; comments describe the function that the call points to.
.text:004031B0 sub_4031B0      proc near               
.text:004031B0                                         
.text:004031B0                 push    esi
.text:004031B1                 mov     esi, ecx
.text:004031B3                 call    sub_402DA0   ; 4 DeviceIoControl calls that use contents of the 
                                                      sensitivity settings from the registry
.text:004031B8                 mov     ecx, esi
.text:004031BA                 call    sub_402D30   ; a couple of calls to DeviceIoControl
.text:004031BF                 mov     ecx, esi
.text:004031C1                 call    sub_402EC0   ; call to SetDoubleClickTime
.text:004031C6                 mov     ecx, esi
.text:004031C8                 call    sub_402ED0   ; call to DeviceIoControl, SystemParametersInfoA, 
                                                      SwapMouseButton
.text:004031CD                 mov     ecx, esi
.text:004031CF                 call    sub_402F70   ; calls to SystemParametersInfo and RegQueryValueEx
.text:004031D4                 mov     ecx, esi
.text:004031D6                 call    sub_403110   ; calls to SystemParametersInfo
.text:004031DB                 pop     esi
.text:004031DC                 retn
.text:004031DC sub_4031B0      endp

After some more boring debugging and live execution manipulation, it seemed like sub_402D30 was the most likely candidate. Time to test it out by writing a simple program to duplicate the function sub_402D30.

; comments are IDA generated
.text:00402D30 sub_402D30      proc near               ; CODE XREF: sub_4031B0+A
.text:00402D30                 mov     eax, hDevice
.text:00402D35                 push    ebx
.text:00402D36                 push    edi
.text:00402D37                 mov     edi, ecx
.text:00402D39                 test    eax, eax
.text:00402D3B                 jz      short loc_402D97
.text:00402D3D                 mov     ecx, [edi+0E20h]
.text:00402D43                 xor     ebx, ebx
.text:00402D45                 test    ecx, ecx
.text:00402D47                 jle     short loc_402D97
.text:00402D49                 push    ebp
.text:00402D4A                 mov     ebp, ds:Sleep
.text:00402D50                 push    esi
.text:00402D51                 mov     esi, ds:DeviceIoControl
.text:00402D57                 jmp     short loc_402D5E
.text:00402D59 ; ---------------------------------------------------------------------------
.text:00402D59
.text:00402D59 loc_402D59:                             ; CODE XREF: sub_402D30+63
.text:00402D59                 mov     eax, hDevice
.text:00402D5E
.text:00402D5E loc_402D5E:                             ; CODE XREF: sub_402D30+27
.text:00402D5E                 mov     ecx, [edi+778h]
.text:00402D64                 push    0               ; lpOverlapped
.text:00402D66                 push    offset BytesReturned ; lpBytesReturned
.text:00402D6B                 push    0               ; nOutBufferSize
.text:00402D6D                 push    0               ; lpOutBuffer
.text:00402D6F                 push    0               ; nInBufferSize
.text:00402D71                 test    ecx, ecx
.text:00402D73                 push    0               ; lpInBuffer
.text:00402D75                 jz      short loc_402D7E
.text:00402D77                 push    22244Ch
.text:00402D7C                 jmp     short loc_402D83
.text:00402D7E ; ---------------------------------------------------------------------------
.text:00402D7E
.text:00402D7E loc_402D7E:                             ; CODE XREF: sub_402D30+45
.text:00402D7E                 push    222450h         ; dwIoControlCode
.text:00402D83
.text:00402D83 loc_402D83:                             ; CODE XREF: sub_402D30+4C
.text:00402D83                 push    eax             ; hDevice
.text:00402D84                 call    esi ; DeviceIoControl
.text:00402D86                 push    0Ah             ; dwMilliseconds
.text:00402D88                 call    ebp ; Sleep
.text:00402D8A                 mov     eax, [edi+0E20h]
.text:00402D90                 inc     ebx
.text:00402D91                 cmp     ebx, eax
.text:00402D93                 jl      short loc_402D59
.text:00402D95                 pop     esi
.text:00402D96                 pop     ebp
.text:00402D97
.text:00402D97 loc_402D97:                             ; CODE XREF: sub_402D30+B
.text:00402D97                                         ; sub_402D30+17 
.text:00402D97                 pop     edi
.text:00402D98                 pop     ebx
.text:00402D99                 retn
.text:00402D99 sub_402D30      endp

Bingo ! Simply sending the control code 222450h set the device to 800CPI mode and sending 22244Ch set it to 1800CPI. Finally, I can now save a combined working set of about 20 megs from occupying physical memory ! I won't necessarily notice it in my 8GB mem bucket, but hey, the OCD seems to have died off. I can sleep peacefully now.

Download:


Sample code to set DPI:
set800.cpp
set1800.cpp

Note: I've merely put these files up here for entertainment purposes. Using these might mess with razers config tool. To make this code more robust you need to add some calls to set a few registry keys, investigate what the proper practice is when using DeviceIOControl, etc (Whether you need to confirm that the device has been correctly programmed, Whether delays are needed in around DeviceIOControl calls, Whether all error conditions are handled etc)
..............
This is fairly trivial in hindsight, but I didn't find the help of any use when I was stuck debugging an user mode app through remote kd. BTW, I hope you're familiar with console debuggers because there doesn't seem to be a way to leverage any of windbg's GUI features over a remote kd session.

Once you've got kd running and connected to the target, make sure the usermode app is running. Break into KD to quickly get the process id in hex:

nt!RtlpBreakWithStatusInstruction:
81881760 cc              int     3
1: kd> !process 0 0 notepad.exe
PROCESS 84b127f8  SessionId: 1  Cid: 0ff0    Peb: 7ffde000  ParentCid: 09a4
    DirBase: 6b25c280  ObjectTable: 9b80e530  HandleCount: 170.
    Image: notepad.exe

Here Cid is the process id. Next we will break inside the process context of notepad to set a local breakpoint. This can be acomplished fairly easily using the command !bpid 0ff0

1: kd> !bpid 0ff0
Finding wininit.exe (1)...
Finding winlogon.exe (1)...
Waiting for winlogon.exe to break.  This can take a couple of minutes...
Break instruction exception - code 80000003 (first chance)
Break into process ff0 set.  The next break should be in the desired process.
Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
001b:77b82ea8 cc              int     3
0: kd> !process
PROCESS 84b127f8  SessionId: 1  Cid: 0ff0    Peb: 7ffde000  ParentCid: 09a4
    DirBase: 6b25c280  ObjectTable: 9b80e530  HandleCount: 170.
    Image: notepad.exe
    VadRoot 86164120 Vads 121 Clone 0 Private 1029. Modified 2564. Locked 0.
    DeviceMap 92071bf8
    Token                             9e30cca0
    ElapsedTime                       00:15:00.188
    UserTime                          00:00:00.093
    KernelTime                        00:00:00.124
    QuotaPoolUsage[PagedPool]         144744
    QuotaPoolUsage[NonPagedPool]      5808
    Working Set Sizes (now,min,max)  (3327, 50, 345) (13308KB, 200KB, 1380KB)
    PeakWorkingSetSize                3704
    VirtualSize                       77 Mb
    PeakVirtualSize                   106 Mb
    PageFaultCount                    5972
    MemoryPriority                    BACKGROUND
    BasePriority                      8
    CommitCharge                      1511

        THREAD 849ddd78  Cid 0ff0.0f58  Teb: 7ffdf000 Win32Thread: fe577e98 WAIT: (WrUserRequest) UserMode Non-Alertable
            84b01350  SynchronizationEvent

        THREAD 849dfa90  Cid 0ff0.0f88  Teb: 7ffdc000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Non-Alertable
            849e7cf0  QueueObject

        THREAD 84a41ac0  Cid 0ff0.083c  Teb: 7ffdb000 Win32Thread: 00000000 WAIT: (DelayExecution) UserMode Non-Alertable
            84a41b48  NotificationTimer

        THREAD 849957d0  Cid 0ff0.0b10  Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0

Now after confirming we're in the right process context, we can now proceed to set breakpoints.

Another way to do this is to use .process /i 84b127f8 to break into notepad's context and then set the breakpoints.
..............
In no particular order, some of my favourite trance tunes from 2009.

Arnej - They need us YT Link

A.M.R. - Elevation (Jonas Hornblad Remix) YT Link

Poshout - For You (Ilya Soloviev Remix) YT Link

Rank 1 - L.E.D. There Be Light YT Link

Martin Roth & Dj Eco - Tonight Is Forever (Martin Roth Edit) YT Link

Chephren Blake feat. Meighan Nealon - Year After (Original Mix) YT Link

Claudia Cazacu feat Audrey Gallagher - Free Falling YT Link

Above & Beyond pres. Oceanlab - Lonely Girl (Gareth Emery Remix) YT Link

Tritonal feat. Soto - Piercing Quiet (Original Mix) YT Link

Solarstone Ft. Elizabeth Fields - Part Of Me (The Thrillseekers Remix) YT Link

Steve Brian - Yaya (Original Mix) YT Link

Wippenberg- Pong (Extended Mix) YT Link

The Doppler Effect - Beauty Hides In The Deep (John O'Callaghan Remix) YT Link

Starchaser Feat Lo-Fi Sugar - So High (Thomas Schwartz And Fausto Fanizza Remix) YT Link

Nic Chagall Featuring Jonathan Mendelsohn - This Moment (Prog Mix) YT Link

Armin Van Buuren feat. Jacqueline Govaert - Never Say Never (Alex Gaudino Remix) YT Link

Matt Darey pres. Urban Astronauts ft Kate Louise Smith - See The Sun (Moonbeam Mix) YT Link

Tydi Feat Audrey Gallagher - You Walk Away (Original Mix) YT Link

Dash Berlin with Cerf, Mitiska & Jaren - Man On The Run (Original Vocal Mix) YT Link

Tiesto - Kaleidoscope feat Jónsi YT Link

Dash Berlin feat. Emma Hewitt - Waiting (Original Mix) YT Link

BT feat. Jes - Every Other Way (Armin van Buuren Remix) YT Link

John O'Callaghan feat. Sarah Howells - Find Yourself (Cosmic Gate Remix) YT Link

Jorn van Deynhoven - Fast Lane YT Link

Sunset - Beautiful Life (Dmitry Bessonov Remix) YT Link

Above & Beyond - Anjunabeach (Nitrous Oxide Remix) YT Link

Ferry Tayle & Static Blue - Trapeze (Daniel Kandi Remix) YT Link

Sigur Rós - Hoppípolla (Chicane - Poppipolla remix) YT Link

Oceanlab - On A Good Day (Above & Beyond Club Mix) YT Link

John O'Callaghan Feat. Lo-Fi Sugar - Never Fade Away(Andy Duguid Remix) YT Link
..............