From ea5522e1d84ae77bcb397cbe86b2aac1b530672c Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 19 Feb 2011 21:50:11 +0000 Subject: [PATCH] [NTOSKRNL] Add support for debug pre/post syscall hooks, that can be registered from win32k. They only exist on DBG versions. svn path=/trunk/; revision=50823 --- reactos/ntoskrnl/include/internal/kd.h | 9 ++++++++ reactos/ntoskrnl/kd/kdmain.c | 19 ++++++++++++++- reactos/ntoskrnl/ke/i386/traphdlr.c | 32 ++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/reactos/ntoskrnl/include/internal/kd.h b/reactos/ntoskrnl/include/internal/kd.h index b61d498b771..53ee9b0f4b2 100644 --- a/reactos/ntoskrnl/include/internal/kd.h +++ b/reactos/ntoskrnl/include/internal/kd.h @@ -363,3 +363,12 @@ extern KD_CONTEXT KdpContext; extern ULONG Kd_WIN2000_Mask; #endif + +#if DBG +#define ID_Win32PreServiceHook 'WSH0' +#define ID_Win32PostServiceHook 'WSH1' +typedef void (NTAPI *PKDBG_PRESERVICEHOOK)(ULONG, PULONG_PTR); +typedef ULONG_PTR (NTAPI *PKDBG_POSTSERVICEHOOK)(ULONG, ULONG_PTR); +extern PKDBG_PRESERVICEHOOK KeWin32PreServiceHook; +extern PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook; +#endif diff --git a/reactos/ntoskrnl/kd/kdmain.c b/reactos/ntoskrnl/kd/kdmain.c index 6b16582735a..ac1f0bc4911 100644 --- a/reactos/ntoskrnl/kd/kdmain.c +++ b/reactos/ntoskrnl/kd/kdmain.c @@ -71,7 +71,7 @@ KdpServiceDispatcher(ULONG Service, case EnterDebugger: DbgBreakPoint(); break; - + case KdSpare3: MmDumpArmPfnDatabase(FALSE); break; @@ -82,6 +82,23 @@ KdpServiceDispatcher(ULONG Service, break; } + /* Register a debug callback */ + case 'CsoR': + { + switch (Buffer1Length) + { + case ID_Win32PreServiceHook: + KeWin32PreServiceHook = Buffer1; + break; + + case ID_Win32PostServiceHook: + KeWin32PostServiceHook = Buffer1; + break; + + } + break; + } + /* Special case for stack frame dumps */ case 'DsoR': { diff --git a/reactos/ntoskrnl/ke/i386/traphdlr.c b/reactos/ntoskrnl/ke/i386/traphdlr.c index 4822b71b8aa..1d3b098504a 100644 --- a/reactos/ntoskrnl/ke/i386/traphdlr.c +++ b/reactos/ntoskrnl/ke/i386/traphdlr.c @@ -46,6 +46,10 @@ UCHAR KiTrapIoTable[] = }; PFAST_SYSTEM_CALL_EXIT KiFastCallExitHandler; +#if DBG +PKDBG_PRESERVICEHOOK KeWin32PreServiceHook = NULL; +PKDBG_POSTSERVICEHOOK KeWin32PostServiceHook = NULL; +#endif /* TRAP EXIT CODE *************************************************************/ @@ -1443,6 +1447,28 @@ KiDebugServiceHandler(IN PKTRAP_FRAME TrapFrame) KiDebugHandler(TrapFrame, TrapFrame->Eax, TrapFrame->Ecx, TrapFrame->Edx); } + +FORCEINLINE +VOID +KiDbgPreServiceHook(ULONG SystemCallNumber, PULONG_PTR Arguments) +{ +#if DBG + if (SystemCallNumber >= 0x1000 && KeWin32PreServiceHook) + KeWin32PreServiceHook(SystemCallNumber, Arguments); +#endif +} + +FORCEINLINE +ULONG_PTR +KiDbgPostServiceHook(ULONG SystemCallNumber, ULONG_PTR Result) +{ +#if DBG + if (SystemCallNumber >= 0x1000 && KeWin32PostServiceHook) + return KeWin32PostServiceHook(SystemCallNumber, Result); +#endif + return Result; +} + DECLSPEC_NORETURN VOID FORCEINLINE @@ -1553,10 +1579,16 @@ KiSystemCall(IN PKTRAP_FRAME TrapFrame, while (TRUE); } + /* Call pre-service debug hook */ + KiDbgPreServiceHook(SystemCallNumber, Arguments); + /* Get the handler and make the system call */ Handler = (PVOID)DescriptorTable->Base[Id]; Result = KiSystemCallTrampoline(Handler, Arguments, StackBytes); + /* Call post-service debug hook */ + Result = KiDbgPostServiceHook(SystemCallNumber, Result); + /* Make sure we're exiting correctly */ KiExitSystemCallDebugChecks(Id, TrapFrame);