I have tangled my self in a web and don't know how to get out of it :)mov

By some trial and error
i have hooked like this

mov esi, offset32 MyHookProc
GetVxDServiceOrdinal eax, _RegOpenKey
VMMCall Hook_Device_Service
jc error

How do i unhook ???
How do i get the address of the original function before hooking :) ??

Am i totally Dumb !!
Posted on 2004-02-13 01:08:49 by monty
Hi, monty

Did you read my answers to your previous questions ???? :confused:
Did you accessed the Russinovich site ????
Did you read the VxDMon source code ????

Well, the answer to your question is register ESI. Look:

; hook the mouse input routine

GetVxDServiceOrdinal eax, VMD_Post_Pointer_Message
; get the id of the service
mov esi, offset32 Record_Mouse ; pass our hook routine address
VMMCall Hook_Device_Service ; hook it
mov Mouse_Proc, esi ; save service address

Good luck :alright:
Posted on 2004-02-13 05:30:33 by Opcode

You should use Unhook_Device_Service to unhook the service you previously hooked.

GetVxDServiceOrdinal eax, VMM_Add_DDB ; Service to hook - CHANGE TO ANY OTHER
mov esi, OFFSET32 HookProc ; pointer to our hook procedure
VMMCall Hook_Device_Service ; address of service returned in ESI
jc hookfailed
jmp ExitOK

GetVxDServiceOrdinal eax, VMM_Add_DDB ; service to unhook
mov esi, OFFSET32 HookProc ; pointer to our hook procedure
VMMCall Unhook_Device_Service
jc unhookfailed
jmp ExitOK2

Posted on 2004-02-13 10:42:34 by Kayaker
Yes opcode i did went to sysinternals they are not giving the source code to regmon now ,

i do have the code of vcmon but as might have guessed it is quite overwhelming for a newbie like me to swallow it all , so i am taking small steps little bit from here and there

but i got it finally .

one last nagging doubt i have , if you could just explain this to me

this is my hooking code
mov esi, offset32 RegOpenKey_Hook
GetVxDServiceOrdinal eax, _RegOpenKey
VMMCall Hook_Device_Service

This is my hook proc
BeginProc RegOpenKey_Hook, HOOK_PROC, Prev_RegOpenKey, HIGH_FREQ, CCALL

ArgVar hKey, DWORD
ArgVar lpszSubKey, DWORD
ArgVar lphKey, DWORD


pushfd ; save flags on stack
pushad ; save registers on stack
mov esi, lpszSubKey ; points to string to write
VMMCall Out_Debug_String

cCall , <hKey, lpszSubKey, lphKey>

EndProc RegOpenKey_Hook

where Prev_RegOpenKey is a vaiable i have declared so
Prev_RegOpenKey DD ?

all this is working fine , but i have never put anything in Prev_RegOpenKey then how am i able to call it ???????? without a blue screen showing up
Posted on 2004-02-14 00:09:34 by monty

A few comments from looking at my old notes.

I'm not sure exactly why you use the HIGH_FREQ, CCALL in your BeginProc, but I'll assume that's the way you want to set it up.

From the notes I have, the BeginProc macro which is needed for a hook routine has the syntax:
; <BeginProc ProcName, HOOK_PROC, hook_var, segment_type>

The hook_var parameter is the name of the variable into which the address of the previous hook will be stored, which you have correctly declared. The segment_type should I believe be LOCKED, since all Hook and Interrupt routines should go in a locked code segment. The rest of your code can be in a VxD_PAGEABLE_CODE_SEG, but it's only logical you DON'T want your hook routine to be paged out, hence I would strongly suggest you use VxD_LOCKED_CODE_SEG.

When your HookProc is called, all the parameters required for the particular service you hooked are sitting on the stack, so what you can do is set up a stack frame at the start, save all the registers and flags, then when you are ready to chain back to the original handler simply pop them off the stack and do a simple jump. There is no need to do a Call + parameters setup. In fact you DON'T want to do a Call else it would in theory return to your own code instead of actually chaining. Your hook is supposed to not exist remember, you do your thing then pass execution on to where it was supposed to go in the first place...

A little code from my hook proc might help explain. Note also my use of an Exception Handler, you may want to implement this in various parts of your vxd code for safety.


OldServiceAddress DWORD ? ; address of original Service routine
EXCEPTION Exception_Handler_Struc <>


;=========================Begin HookProc=======================
BeginProc HookProc, HOOK_PROC, OldServiceAddress, LOCKED

; Important: Note syntax of BeginProc macro needed for a hook routine:
; <BeginProc ProcName, HOOK_PROC, hook_var, segment_type>
; If hook uses Hook_Device_Service, Hook_V86_Fault, Hook_PM_Fault,
; or Hook_VMM_Fault, then it must be marked with the HOOK_PROC attribute
; so that the service can be unhooked.
; The hook_var parameter is the name of the variable into which the
; address of the previous hook will be stored.

; Create a stack frame so we can access stack parameters at time of hook,
; parameters will vary with Service hooked.
push ebp
mov ebp, esp


; Install Exception Handler
; Place any code that might generate an error between
; EH_Start_EIP and EH_End_EIP
mov EXCEPTION.EH_Reserved,0
mov EXCEPTION.EH_Start_EIP,offset32 PROTECT1
mov EXCEPTION.EH_Handler,offset32 EHandler1

mov esi, offset32 EXCEPTION ; points to an Exception_Handler_Struc
VMMCall Install_Exception_Handler ; set up exception handler


; Do your stuff here, fill some data structures with info from
; the stack variables for later retrieval, whatever.


mov esi, offset32 EXCEPTION ; points to an Exception_Handler_Struc
VMMcall Remove_Exception_Handler ; remove exception handler


pop ebp

jmp [OldServiceAddress] ; Chain to previous hook

GetVxDServiceOrdinal eax, VMM_Add_DDB ; service to unhook
mov esi, OFFSET32 HookProc ; pointer to our hook procedure
VMMCall Unhook_Device_Service


EndProc HookProc
;===================End HookProc==================


Hope this helps,
Posted on 2004-02-14 01:37:55 by Kayaker
OH my god what a wonderfull explaination , i love it
i will read more in to it and try to implement all that

one more thing , i didn't quite understand
push ebp
mov ebp, esp

will this code vary incase of different parameters passed ,
could you please explain more

Thanks a bunch Kayakar
Posted on 2004-02-14 02:31:58 by monty
I'm glad it was useful. I don't believe there should be any difference in how you set up or access the parameters from the stack frame, but you will have to confirm what each stack parameter represents for your particular service.

The VMMCall for VMM_Add_DDB for example passes the offset of a Vxd_Desc_Block structure. I don't know at what point the "hook" actually occurs and your own code is called, so you'll have to test the stack to see where the parameters you are *expecting* actually are.

For VMM_Add_DDB, in my hook proc happened to be the Driver Name, not necessarily where I *expected* it from the structure of the Vxd_Desc_Block, so this is why you need to test.

push ebp
mov ebp, esp
; == DDB_Name

VMM_Add_DDB is called as part of the VxD loader services and can be used to detect a driver being loaded. It adds a Vxd_Desc_Block structure (DDB or Device Description Block) to the linked device list chain. This chain can be "walked" to identify and analyze each application or Kernel system driver loaded on your system.

Heh, it's good to see some people are still coding vxd's ;-)
Posted on 2004-02-14 13:59:46 by Kayaker
Thanks Again Kayaker :)

just one more thing could you please shed some light on APC
i want to Queue some data to the User mode application as well

Heh, it's good to see some people are still coding vxd's ;-)

Thats what i was worried about when i started this , will i be able to get help from some ppl who STILL codes VXD's :)
Posted on 2004-02-15 01:08:05 by monty
Well I don't code 'em anymore but...
Can you even do APC's in vxd's? There may be something similar, but if what you're trying to do is pass info back to user mode the easiest way is to create a data structure in your vxd, fill it up in your hook proc with whatever you want, then access the data later from a separate DeviceIOControl call back in user mode. If your data structure is again in a locked segment you can simply pass back a pointer to it through lpOutBuffer and spit it out again in usermode.

I gave a complete example of this a while back in this thread which should explain it.

Posted on 2004-02-15 04:46:19 by Kayaker