How to reverse engineer a Windows 95 target
REVERSE ENGINEERING EXERCISES FOR THE MASSES - (2e)
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
REVERSE ENGINEERING EXERCISES FOR THE MASSES - (2e)
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 chainAs 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 http://www.ddj.com, and fetch "March 1996" source code, you'll find record.zip... 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:
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
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.
BeginProc Record_Keyboard, Hook_Proc Keyboard_Proc
; record the input
mov ebx, Buffer_ptr
cmp ebx, offset32 Buffer + BUFFER_SIZE - sizeof REC_mouse_entry
mov [ebx].rectype, KEYBDTYPE
mov [ebx].scancode, cl ; scancode is in cl
mov eax, System_Time
mov eax, [eax] ; get the timestamp
mov [ebx].timestamp, 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
clc ; let the key through
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 vxdlib.zip
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: dumplx.zip, 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)
vxdmon.zip (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.
TO BE CONTINUED
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
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:
(c) reverser+ 1997. All rights reserved.
You are deep inside reverser's page of reverse engineering,
choose your way out:
is reverse engineering legal?