How to reverse engineer a Windows 95 target
Version 0.01

by reverser+ (MSRE), 1997

Part E: VXD vagaries and mysteries - 01 September 1997

Courtesy of Reverser's page of reverse engineering

Well, a very interesting essay... I wrote it myself! :-) This essay will be divided in five (or more) parts:
 A = Introduction to filemon
B = reverse engineering without source code 
C = Filemon reversed 
D = Back to Main
E = VXD vagaries and mysteries
Although already disponible, this essay is still under construction and will be modified and ameliorated until the wording below will disappear (I reckon until mid-October)


How to reverse engineer a Windows 95 program: filemon
Part E: VxD vagaries and mysteries

(c) Reverser (MSRE), 1997. All rights reversed

Print as html document, else use courier 8

VxDs or the "black art" in Windows
Well, notwithstanding the banner "Under construction" above, many of you have emailed me asking where did remain this fifth part of my filemon tutorial (the one about VxD reverse engineering). A first explanation of the delay can be condensed in this short sentence: VxD reverse engineering is difficult because VxD programming seems to have been a sort of "black art", reserved to few "afecionados"... remember that back in the times of Windows 3.0. you where not even ALLOWED to program VxD unless you where Micro$oft certified... I'm not jocking... Micro$oft always loved to keep knowledge of its Oss "guts" half secret...
Let's start from the beginning... it's all a question of hooks by the way... remember the good old DOS hooks? You intercepted some interrupts (hooked them) and wrote your routines. The intercepted pointers pointed to your code, which executed and, at the end, returned control to the "correct" interrupt... many protections (and many viruses) where based on this hooking, have a look at +ORC's (very old) example for UniversalMilitarySimulator_I or at any disassembled virus of the early '90 and you'll immediately see what I mean.
Well, the new hooks for Windows 95 have been placed at the lowest level possible: the virtual device (VxD) level... and this gives programmers (and reverse engineers :-) quite a lot of input and output control, as you will see.
(Please don't take all too seriously my jokes -in this part of the tutorial- about "white" VxD reversing and "black" VxD writing)

VMM_ Get_System_Time_Address... an idea for a very tough protection
BTW, a side product of this VxD hooking is the possibility of writing VERY TOUGH protections (shareware programmers, are you reading this?). I'm not aware that somebody has used until now the following trick (that we'll deeply examine in this part of my tutorial): There is a VMM (Virtual Machine Manager) service Get_System_Time_Address, which returns a pointer to a memory location where Windows keeps track of the number of milliseconds since Windows booted. Accessing this location directly avoids the overhead of calling a service like Get_System_Time.
Btw, as you will see examining the VMM.vxd (see below HOW to do it and wich tools to use), there are many other interesting services, like for instance the following two:
1003F @ 00002970 Get_System_Time 
100CF @ 00002976 Get_Last_Updated_System_Time
History: mother of all reverse engineers
How did I tackle the task of reverse engineering the VxD in filemon, once I noticed that it was quite complicated for me to reverse engineer? Simple: I did a RESEARCH. See, Mark Russinovich and Bryce Cogswell have not pulled filemon out of an empty hat... they must have worked on similar projects before, and it was probable that they had implemented their first VxD "essays" in a much easier way. If you know how to search the web, the rest is easy (and if you don't know how to search effectively the web, just leave this cracking stuff alone for a while and go learn "searching", come back when you are finished).
On Dr Dobb's Journal, issue 245, March 1996,
there is an interesting article by Mark Russinovich and Bryce Cogswell: Windows 95 journaling and playback, which is useful to understand how VxDs are implemented and, even better given our reverse engineering target, how the same Mark Russinovich and Bryce Cogswell use to implement them. I'll use a lot of the code and of the text of that article in this part of my tutorial... I believe that it is worth reading.
Basically the point was to underline the difference in "hooking" between Windows 3.1. and Windows 95, using a "recorder" program, like the one inside the main utility group of Windows 3.1., which disappeared in windows 95 (Mark Russinovich and Bryce Cogswell give the code for a Windows 95 recorder in that same article).

Old hooking, new hooking
Windows 3.1. hooks worked at the APPLICATION-MESSAGE level, like most of our patches when we de-protect, btw, and have been carried forward inside Windows 95, generally unchanged (although Micro$oft no longer provides a recorder program).
While these hooks are sufficient for many applications, they have significant shortcomings, for example they do not "journal" keyboard input going into DOS windows, or input going into a DOS full-screen session (many games). Another problem is that the old hooks force all input coming from the mouse and keyboard to be funneled into a journaling program for it to save, before being passed on to the target application. The inverse happens in playback (remember that we are speaking here of a "recorder" program), with Windows asking the journaler for input to simulate.
Windows 95 has a decentralized input scheme: Windows 95 feeds input directly to the INPUT QUEUE of applications. It is therefore no more necessary that a windows program participate ACTIVELY in the journaling process, with the consequence of a performance degrading in Windows 3.1., because these programs had to "wake up" at every mouse or keyboard input, using up cycles that other programs might have needed (so Windows 95 is sort of an "improvement", after all :-)
Since the new hooks have NO windows application-level API, they are inaccessible to most developers, which is exactly what Micro$oft likes: "toy applications for the stupid slaves and rentable programs "that sell" for Micro$oft's so called "programmers".
But let's be clear: the new VxD hooking techniques are only an amelioration (history "docet", as always) of the old
SetWindowsHookEx(idHook, hkprc, hinst, htask) procedure,
int idHook;                      /* type of hook to install	*/
HOOKPROC hkprc;                  /* procedure-instance address of filter function	*/
HINSTANCE hinst;                 /* handle of application instance	*/
HTASK htask;                     /* task to install the hook for	*/

The SetWindowsHookEx function installs an application-defined hook function into 
a hook chain. This function is an extended version of the older SetWindowsHook
function, which in turn derived from the Windows 3.0 DefHookProc function, which 
calls the next function in a chain of hook functions. A hook function is a 
function that processes events before they are sent to an application's 
message-processing loop in the WinMain function. When an application defines 
more than one hook function by using the SetWindowsHook function, Windows 
forms a linked list or hook chain. Windows places functions of the same 
type in a chain
As you can see... we are just following the development of our good old DOS interrupt hooks. Back to the "new" VxD hooking...

Keyboard hooks and mouse hooks
Two different separate hooks, for the mouse and for the keyboard are necessary since SEPARATE VxDs deal with each type of input. Both VxDs have a VxD level API, allowing other VxDs to request to see inputs as they are received BY THE SYSTEM, as well as to generate simulated input from a device.
One year before our target filemon and its companion regmon, Mark Russinovich and Bryce Cogswell have developed "recorder", a macro recorder application, which consists of a Windows 95 32-bit GUI as user interface and a VxD that serves as the recording and playback controller... you see that the layout of all their programs, past and present (and probably future) is always the same... history matters a lot in our trade, as +ORC teach us. You'll find the source code (complete with the very nice notice "You have the right to take this code and use it in whatever way you wish", which in our case is not really necessary, since that is exactly what we usually do anyway with all the programs we put our hands on :-) at Dr Dobb's, an American pretty expensive magazine "for real programmers" that publishes at times well written articles, many of them about "minor" languages. Unfortunately the articles ARE NOT on-line (as usual there is a "commercial" catch somewhere), yet the source code is. Have a look at, and fetch "March 1996" source code, you'll find btw you'll find a LOT of interesting code peeking around there.

How does recorder record?
Let's see how Recorder VxD simulates input from the mouse and the keyboard... I know, I know, your brain is still full of filemon's code, and now reverser takes you on a boat ride on ANOTHER, completely different target. But you want to understand VxDs don't you? And you would like to reverse engineer them as much as I do, don't you? Therefore shut up and follow me, you'll be eventually rewarded.
Mark Russinovich and Bryce Cogswell's recorder sees system input via "service hooking", an obscure feature of the Windows VxD architecture that let's you see JUST ABOUT EVERYTHING GOING ON INSIDE THE GUTS OF WINDOWS and gives you the control to completely change its behavior.
Just like old DOS interrupt hooking, once a service is hooked, any VxD or application calling the service gets redirected to the hooker VxD first. So your hooking VxD takes control: you can choose to pass the request on to the next VxD of the chain, CHANGE THE PARAMETERS to the request and pass the same request on "MAGICALLY ALTERED", or service the request itself yourself... yes, yes, your +cracker brain begins now to perceive the huge power that this can give us (and not only in reverse engineering and patching targets... future windows virii writers, are you reading this? :-)

How do I hook VxDs, man?
Well, I'm not going to transform you in Micro$oft's programmers with my tutorial, VxD programming needs the SDK, so they say to trap you in... that's the dark path +ORC warned us about, my readers, from there you would never come back... Yet I hope, through some simple tools, to impart you the ability to reverse engineer most VxDs WITHOUT much knowledge of Windoze's programming techniques... you'll be able to do it in name of the "white magical power" conferred to us by our superior assembly understanding... just follow on, at the end it will be indeed wizards against wizards. To make hooking VxD services possible, each VxD has a memory location assigned for each of its services that points to the top of a hook chain. When a new hooker is "registered" for a service, the appropriate address is modified in order to point to the NEW hook routine.
The hook routine itself must be declared as a Hook_Proc in its assembly language declaration like this:
BeginProc Hook_routine
                 Hook_Proc Chain_Save
Chain_Save is a double word variable that YOU assign, and to which Hook_Device_Service stores the PREVIOUS top of the hook chain. The Hook_Proc tag causes the code in this example to appear at the START of the procedure:
jmp Hook_routine       ;skip over the book-keeping info
jmp Chain_Save         ;bogus code, its just here to point windows at
                       ;the variable storing the previous service address
dd 0                   ;not used
Hook_routine:          ;your home made hooking routine is here
So the above code appears every time you use the Hook_Proc tag.
When a hook is removed from the chain, the link to the next service in the chain is obtained from the Chain_Save location above, making hooking and unhooking transparent to the VxD programmer. The Chain_Save variable can also be used by the hooking routine to chain to the previous hooker if it wants to pass the request (modified or "pure") on.
Mark Russinovich and Bryce Cogswell's recorder must hook the Virtual Keyboard Driver VxD service D0012 @ 00000E00 VKD_Filter_Keyboard_Input (we'll see very soon how to get these VxDs disassembled and how to get these data out of them :-). This service is called by the VKD itself (VKD.vxd) upon keyboard input. The service was written with the sole intention that some other VxD would hook it to record, and possibly alter, keyboard input. Let's have a look at the VKD call to the service and to the service itself:
; VKD calls its own service with input
mov		cl, scancode                ;scancode is the keyboard input
VxDCall  	VKD_Filter_Keyboard_Input   ;call the service
jc		noinput                     ;if carry set kill the input
And this is the disassembly (wdasm89) from VKD.vxd:
:00000E00 F8                      clc      ;clear carry flag
:00000E01 C3                      ret      ;ret
Note that we are at :E00, would you have been interested in
D0001 @ 0000416B VKD_Define_Hot_Key
Then you would have had this code snippet:
:0000416B 51                      push ecx
:0000416C 57                      push edi
:0000416D 33FF                    xor edi, edi
:0000416F F6C180                  test cl, 80
:00004172 741A                    je 0000418E
:00004174 80E17F                  and cl, 7F
:00004177 0FBC3D4D120000          bsf edi, dword ptr [0000124D]
:0000417E 740B                    je 0000418B
:00004180 0FB33D4D120000          btr dword ptr [0000124D], edi
:00004187 73EE                    jnb 00004177
:00004189 EB03                    jmp 0000418E
Have a little patience, please, you'll soon learn how to reverse engineer VxD code WITHOUT any Micro$oft SDK... let's go on to the second interesting listing from our "historical" target record...
; default filter service
BeginProc		VKD_Filter_Keyboard_Input

GetVxDServiceOrdinal 	eax, VKD_Filter_Keyboard_Input ;get the ID of the filter service
mov esi, offset 32	Record_keyboard                ;address of our hook routine
VMM Call 	Hook_Device_Service                    ;hook
mov		Keyboard_Proc, esi                     ;save previous hook

; Record_Keyboard - Records keyboard input into the input buffer.
; Entry: CL - Scancode of key pressed.
Public Record_Keyboard
BeginProc Record_Keyboard, Hook_Proc Keyboard_Proc
	push	eax
	push	ebx
; record the input
	mov	ebx, Buffer_ptr
	cmp	ebx, offset32 Buffer + BUFFER_SIZE - sizeof REC_mouse_entry
	jae	rk_done
	mov	[ebx].rectype, KEYBDTYPE
	mov	[ebx].scancode, cl		; scancode is in cl
	push	eax
	mov	eax, System_Time
	mov     eax, [eax]			; get the timestamp
	mov	[ebx].timestamp, eax
	pop	eax
	add	ebx, sizeof REC_kbd_entry	; move forward in buffer
	mov	Buffer_ptr, ebx
	mov	[ebx].rectype, INVALIDTYPE	; mark end of macro
; call the previous hooker
	call	Keyboard_Proc
	pop	ebx
	pop	eax
	clc					; let the key through
EndProc Record_Keyboard
We'll later examine more deeply the above code, for the moment just get a "feeling" for this stuff. Let's go on.
To alter input, a hooking VxD simply changes here the value of the CL register to a new scancode, to kill input, the hooking routine sets the carry flag before it returns. The recorder VxD hook procedure saves the value of the CL register (and the current time) into a buffer. Listing TWO, above, hooks the service, while listing THREE, above, is a keyboard-recording routine (that you may also find useful for incorporating in your own probes... in order to trap keyboard input... should you ever need to do something like that :-)

Some VMM32.VXD snooping
Have a look at your Windows/system directory... you'll see there vmm32.vxd, an 807.975 bytes long VxDs "collection", let's have a look at it, we want to examine the VKD, don't we. Hay! This is a compressed and encrypted file! Oh poor crackers! Will they not even be able to get a sound dead listing out of it?
Yes, we will! Good old +ORC did teach us how to get at the VxDs, didn't he? So let's follow +his instructions and then we will be able to have a look at Micro$oft hidden and encrypted VKD.vxd (please don't confuse VKD, virtual keyboard driver, with VxD, virtual Device driver :-). Let's recall +ORC's words:
...and you'll need a special tool to extract Windows Virtual Device Drivers
(VxDs) from W3 (WIN386.EXE) & W4 (VMM32.VXD) format archive files. 
You see... inside these archives dwell all the virtual devices drivers currently
used by your machine, which have been (as usual) purposely HIDDEN there by 
Micro$oft... but I'll explain you how to fetch them using a couple of tools that have
been written by a man I have met some years ago, a master of executable 
Well, since the very first tool to use is the vxdlib extractor, in our case, searching for VKD.vxd, just do the following:
1) get VXDLIB v.1.01                         ;get
2) c:\windows\system\VXDLIB -u vmm32.vxd     ;unpack this vxd huge archive
3) c:\windows\system\VXDLIB -l vmm32.vxd     ;gives you 45 total VxDs
4) c:\windows\system\VXDLIB -u vmm32.vxd VKD ;extract your target VKD
result ->   VKD.vxd 001EB000 001F7000 0000C000
and you'll get the file VKD.vxd, 49280 (0xC080) bytes, inside your windows/system directory, use W3map to have a look at this VxD, or, even better, just disassemble it (now) with wdasm89, you'll notice the many "objects" (LCOD, MCOD, VMCR... etc) inside it... Another (quicker) possibility is to use another fine utility:, by Clive Turvey, the same Author of vxdlib.exe. Btw, Clive Turvey is the "successor" of Andrew Schulman at the "Windows Source" project (Version three and following versions)... so the tools that +ORC has pointed out for us have been made by the "top gurus" of this planet.

If you do, you'll see at the bottom the following very interesting "DDB" table:
DDB Service Table

	   D0000 @ 00004164 VKD_Get_Version
	   D0001 @ 0000416B VKD_Define_Hot_Key
	   D0002 @ 000041EA VKD_Remove_Hot_Key
	   D0003 @ 0000422E VKD_Local_Enable_Hot_Key
	   D0004 @ 00004245 VKD_Local_Disable_Hot_Key
	   D0005 @ 0000425C VKD_Reflect_Hot_Key
	   D0006 @ 0000429E VKD_Cancel_Hot_Key_State
	   D0007 @ 000000DA VKD_Force_Keys
	   D0008 @ 00000124 VKD_Get_Kbd_Owner
	   D0009 @ 00006000 VKD_Define_Paste_Mode
	   D000A @ 00006019 VKD_Start_Paste
	   D000B @ 000060B8 VKD_Cancel_Paste
	   D000C @ 0000012B VKD_Get_Msg_Key
	   D000D @ 00000158 VKD_Peek_Msg_Key
	   D000E @ 00000180 VKD_Flush_Msg_Key_Queue
	   D000F @ 0000403C VKD_Enable_Keyboard
	   D0010 @ 00004000 VKD_Disable_KeyBoard
	   D0011 @ 0000005C VKD_Get_Shift_State
	   D0012 @ 00000E00 VKD_Filter_Keyboard_Input
	   D0013 @ 00000F79 VKD_Put_Byte
	   D0014 @ 00000068 VKD_Set_Shift_State
Here the comment by Clive Turvey:
    Windows does not use imports but instead uses INT 20h dynamic
    links that are fixed up on the fly. In assembler these calls are in
    the form VMMCall, VMMJmp, VxDCall & VxDJmp. Windows only exports a
    single pointer to the DDB a device driver header, this header contains
    function exports that other VxDs can call with the dynamic linking
    described above. When known the name associated with a dynamic function
    number is displayed (by dumplx.exe)
Yes, we begin to understand... we are now almost ready to begin our holy VxDs reversing... let's see if we really have all the necessary weapons...

VxD reversing "white" tools (as alternative to the "black" SDK suite :-)
Let's resume the VERY important tools that you'll need on your VxDs endeavour:
The vxdlib.exe unpacker/extractor (otherwise there is no "dead listing" of Micro$oft's VxDs)
The dumplx.exe dumper (otherwise you won't get the DDB service table) (60.260 bytes) by "our" duo: Mark Russinovich and Bryce Cogswell another important tool to study "alive" the working of VxDs
Obviously there is a SoftIce approach as well (SoftIce has everything)...
VXD This command displays the VxD map in the command window, you may use the VxD names to set breakpoints at the entry points of the VxD service routines you are interested in (you may also use VXD WINICE to see Softice own VxD :-)

VCALL display the names and addresses of VxD callable routines (note that the addresses displayed are NOT valid until the VMM VxD has been initialized. Here an example:

VM Displays information on virtual machines, if you specify a VM-ID parameter, then the register values of this VxD are displayed (may be unvalid, study the VM instructions). VM is the command you'll most use when you crack VxD, DPMI applications and DOS programs running in VMs.

I showed you two examples above. Now let's see how register's code calls these services: (you'll find the code inside the file "record.asm" For instance this snippet, that we have already seen above:
; first hook the keyboard input

	GetVxDServiceOrdinal eax, VKD_Filter_Keyboard_Input
	mov	esi, offset32 Record_Keyboard
	VMMCall	Hook_Device_Service
	jnc	installmouse
Now do the following:
1) Disassemble record.vxd with wdasm89 and save the *.asm file
2) dumplx record.vxd and look at the DBB entry:
DDB Entry

	00000000 DDB_Next
	0400     DDB_SDK_Version
	0000     DDB_Req_Device_Number
	 1.00    DDB_Device_Version
	0000     DDB_Flags
	80000000 DDB_Init_Order
	00002080 DDB_Control_Proc
	00000000 DDB_V86_API_Proc
	00000000 DDB_PM_API_Proc
	00000000 DDB_V86_API_CSIP
	00000000 DDB_PM_API_CSIP
	00000000 DDB_Reference_Data
	00000000 DDB_Service_Table_Ptr
	00000000 DDB_Service_Table_Size
	00000000 DDB_Win32_Service_Table_Ptr
	50726576 DDB_Prev
	00000050 DDB_Size
	52737631 DDB_Reserved1
	52737631 DDB_Reserved2
	52737631 DDB_Reserved3

(c) reverser+ 1997. All rights reserved.
You are deep inside reverser's page of reverse engineering, choose your way out:
filemon1filemon2 filemon3 filemon4

homepage links red anonymity +ORC students' essays tools cocktails
antismut search_forms mail_reverser
is reverse engineering legal?