SysenterHook


/*

------------------ BEGIN MAKEFILE -----------------


#

# DO NOT EDIT THIS FILE!!!  Edit .\sources. if you want to add a new source

# file to this component.  This file merely indirects to the real make file

# that is shared by all the components of NT OS/2

#

!INCLUDE $(NTMAKEENV)\makefile.def


------------------ END MAKEFILE -------------------

*/


/*

------------------ BEGIN SOURCES ------------------


TARGETNAME=SysenterHook

TARGETPATH=obj

TARGETTYPE=DRIVER

INCLUDES=

SOURCES=SysenterHook.c


----------------- END SOURCES ---------------------

*/


//

//  Demonstration of hooking SYSENTER to see user to kernel mode

//  transition.  Extract the SOURCES and MAKEFILE above as needed then

//  use the DDK build environment to create the driver.  Use a driver

//  loader to load the driver into the kernel.

//

//  Michael Wookey / May 2006

//


#include <ntddk.h>


//

//  See Intel docs - SYSENTER instruction (Vol 2B)

//

#define IA32_SYSENTER_EIP 0x176


//

//  The address of the original KiFastCallEntry routine

//

ULONG Orig_KiFastCallEntry = 0;


//

//  This is the replacement routine

//

__declspec(naked) Hook_KiFastCallEntry()

{

    //

    //  For now, do nothing but passthrough to the original function.

    //  Breakpoint here to see the user to kernel mode transitions.

    //

    __asm jmp dword ptr Orig_KiFastCallEntry

}


NTSTATUS 

DriverEntry(

    PDRIVER_OBJECT DriverObject, 

    PUNICODE_STRING RegistryPath

    )

{

    __asm {


        //

        //  Read the routine that handles SYSENTER by reading the given

        //  Model State Register (MSR).

        //  

        mov     ecx, IA32_SYSENTER_EIP

        rdmsr


        //

        //  Store the original routine.

        //

        mov     Orig_KiFastCallEntry, eax


        //

        //  Replace this routine by writing to MSR IA32_SYSENTER_EIP

        //  (which is already in ECX) with the address of our hook.

        //

        mov     eax, Hook_KiFastCallEntry

        wrmsr 

    }

    

    return STATUS_SUCCESS;

}


/* EOF */