From 2c22f0e8a41fdfc970abc2d20fa631a26fb31fb1 Mon Sep 17 00:00:00 2001 From: wj32 Date: Sat, 25 Jul 2009 00:13:41 +0000 Subject: [PATCH] added the use of an active logger count git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1632 21ef857c-d57f-4fe0-8362-d861dc6d29cd --- trunk/KProcessHacker/i386/kprocesshacker.sys | Bin 35328 -> 35328 bytes trunk/KProcessHacker/include/sync.h | 38 +++++++++++++++++ trunk/KProcessHacker/include/sysservicep.h | 2 + trunk/KProcessHacker/sync.c | 35 +++++----------- trunk/KProcessHacker/sysservice.c | 41 ++++++++++++------- 5 files changed, 76 insertions(+), 40 deletions(-) diff --git a/trunk/KProcessHacker/i386/kprocesshacker.sys b/trunk/KProcessHacker/i386/kprocesshacker.sys index 6bf89293a90faf23ef6c7d04da2f6f874af3c336..b4699c76d05becb504ac197885af47e9119873ea 100644 GIT binary patch delta 4095 zcmZu!3se+mvhKfUfI$ZV1B$@#P@X=4o)<$85_Dz(R~#Ij5#`|nv%TnXjmu~fMKHkC zu_eJRb5s6PyHUYeh=Hy%T6oWeXW?S+zeAmQLqriF#8{8nAqKkF|e1I$@B0BvVfd{ zMD{fj=<8sAOGpL$Qk_rUgv09JkU}U3I5PI&WQJ+$+;a$xFc z@I_DrEYQA0>V5rM3n4m48rO(k-W<1>tOt4Ar15Epwb5TQSDZgA60co-pdO}%Zi-p& zBuus1Aq_l`WwE#E`WA!xbZ-e^+)|V8ROpp}_#)2l&TB5#ZYRyfngRB13+ESq;65G< zJvOn)?-_)*Bh$#Q;7X*q&Y|J%xy1|i!O)J(<^t^_-Fv8OYVy|%Hk_038CzLV-WkSR zRDPnoSiDnG;&h1~ja$4Vwf#euIoZ2a?sdRkW+C86j{oVN^X1 zIr0jsqe%8>l;y6+m1Q-ntS;h1*`{geNyskOY&grw4|mS#!@aBam!R9w<9@Ggh`LVk z)((qxwxMjBrY019s%*n<7jAKG)QfFcar4={(G-eZ;t%2{G=(``p24GJhdsQqV%hml z^`oq~+@}-p&4`!f$S`zLZ{4+!FpOt>J5oQDMxeA(?5^k%@=#Bb?#V`39BjI`<(BhA z3+j$$|5N2nJx1Tu>(s@vfv%CnSH}uN`DnNkj!irhvK)OltIf@}uN=|?cs9yIcEC_n z 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 E2FFF*AOHXW diff --git a/trunk/KProcessHacker/include/sync.h b/trunk/KProcessHacker/include/sync.h index ad3937920..c6f2d6100 100644 --- a/trunk/KProcessHacker/include/sync.h +++ b/trunk/KProcessHacker/include/sync.h @@ -25,6 +25,44 @@ #include "kph.h" +/* General synchronization macros */ + +/* KphEqualSpin + * + * Spins until the first value is equal to the second + * value. + */ +FORCEINLINE VOID KphSpinUntilEqual( + __inout PLONG Value, + __in LONG Value2 + ) +{ + while (InterlockedCompareExchange( + Value, + Value2, + Value2 + ) != Value2) + PAUSE(); +} + +/* KphNotEqualSpin + * + * Spins until the first value is not equal to the second + * value. + */ +FORCEINLINE VOID KphSpinUntilNotEqual( + __inout PLONG Value, + __in LONG Value2 + ) +{ + while (InterlockedCompareExchange( + Value, + Value2, + Value2 + ) == Value2) + PAUSE(); +} + /* Spin Locks */ /* KphAcquireBitSpinLock diff --git a/trunk/KProcessHacker/include/sysservicep.h b/trunk/KProcessHacker/include/sysservicep.h index 0dcdbead4..06b8000e8 100644 --- a/trunk/KProcessHacker/include/sysservicep.h +++ b/trunk/KProcessHacker/include/sysservicep.h @@ -82,6 +82,8 @@ typedef struct _KPHPSS_RESET_BLOCK #define TAG_EVENT_BLOCK ('BEhP') +#define KPHPSS_EVENT_BLOCK_MAX_SIZE 0x200 + #define KPHPSS_EVENT_PROBE_ARGUMENTS_FAILED 0x00000001 #define KPHPSS_EVENT_COPY_ARGUMENTS_FAILED 0x00000002 #define KPHPSS_EVENT_KERNEL_MODE 0x00000004 diff --git a/trunk/KProcessHacker/sync.c b/trunk/KProcessHacker/sync.c index 6aafc242f..99bd46bf8 100644 --- a/trunk/KProcessHacker/sync.c +++ b/trunk/KProcessHacker/sync.c @@ -27,6 +27,13 @@ ULONG KphpCountBits( __in ULONG_PTR Number ); +VOID KphpProcessorLockDpc( + __in PKDPC Dpc, + __in PVOID DeferredContext, + __in PVOID SystemArgument1, + __in PVOID SystemArgument2 + ); + /* KphfAcquireGuardedLock * * Acquires a guarded lock and raises the IRQL to APC_LEVEL. @@ -76,13 +83,6 @@ VOID FASTCALL KphfReleaseGuardedLock( KeLowerIrql(oldIrql); } -VOID KphpProcessorLockDpc( - __in PKDPC Dpc, - __in PVOID DeferredContext, - __in PVOID SystemArgument1, - __in PVOID SystemArgument2 - ); - /* KphAcquireProcessorLock * * Raises the IRQL to DISPATCH_LEVEL and prevents threads from @@ -175,12 +175,7 @@ BOOLEAN KphAcquireProcessorLock( KeInsertQueueDpc(&ProcessorLock->Dpcs[i], ProcessorLock, NULL); /* Spinwait for all (other) processors to be acquired. */ - while (InterlockedCompareExchange( - &ProcessorLock->AcquiredProcessors, - numberProcessors - 1, - numberProcessors - 1 - ) != numberProcessors - 1) - NOTHING; + KphSpinUntilEqual(&ProcessorLock->AcquiredProcessors, numberProcessors - 1); dprintf("KphAcquireProcessorLock: All processors acquired.\n"); ProcessorLock->Acquired = TRUE; @@ -241,12 +236,7 @@ VOID KphReleaseProcessorLock( InterlockedExchange(&ProcessorLock->ReleaseSignal, 1); /* Spinwait for all acquired processors to be released. */ - while (InterlockedCompareExchange( - &ProcessorLock->AcquiredProcessors, - 0, - 0 - )) - NOTHING; + KphSpinUntilEqual(&ProcessorLock->AcquiredProcessors, 0); dprintf("KphReleaseProcessorLock: All processors released.\n"); @@ -313,12 +303,7 @@ VOID KphpProcessorLockDpc( InterlockedIncrement(&processorLock->AcquiredProcessors); /* Spin until we get the signal to release the processor. */ - while (!InterlockedCompareExchange( - &processorLock->ReleaseSignal, - 1, - 1 - )) - NOTHING; + KphSpinUntilNotEqual(&processorLock->ReleaseSignal, 0); /* Decrease the number of acquired processors. */ InterlockedDecrement(&processorLock->AcquiredProcessors); diff --git a/trunk/KProcessHacker/sysservice.c b/trunk/KProcessHacker/sysservice.c index fe8603449..b8f5b8a0f 100644 --- a/trunk/KProcessHacker/sysservice.c +++ b/trunk/KProcessHacker/sysservice.c @@ -31,21 +31,24 @@ #include "include/sysservicep.h" #include "include/hook.h" +#include "include/sync.h" #include "include/trace.h" extern PDRIVER_OBJECT KphDriverObject; FAST_MUTEX KphSsMutex; /* Whether system service logging has been initialized. */ -BOOLEAN KphSsInitialized; +BOOLEAN KphSsInitialized = FALSE; /* The KiFastCallEntry hook. */ KPH_HOOK KphSsKiFastCallEntryHook; +/* The number of active loggers. */ +ULONG KphSsNumberOfActiveLoggers = 0; PKPH_OBJECT_TYPE KphSsClientEntryType; PKPH_OBJECT_TYPE KphSsProcessEntryType; +FAST_MUTEX KphSsProcessListMutex; LIST_ENTRY KphSsProcessListHead; -EX_RUNDOWN_REF KphSsRundownProtect; /* KphSsLogInit * @@ -58,6 +61,7 @@ NTSTATUS KphSsLogInit() /* Initialize the process list. */ InitializeListHead(&KphSsProcessListHead); ExInitializeFastMutex(&KphSsMutex); + ExInitializeFastMutex(&KphSsProcessListMutex); /* Initialize the object types. */ status = KphCreateObjectType( @@ -104,9 +108,6 @@ NTSTATUS KphSsLogStart() return STATUS_UNSUCCESSFUL; } - /* (Re-)initialize rundown protection. */ - ExInitializeRundownProtection(&KphSsRundownProtect); - /* Hook KiFastCallEntry. Logging will start from now. */ KphInitializeHook( &KphSsKiFastCallEntryHook, @@ -152,8 +153,8 @@ NTSTATUS KphSsLogStop() return status; } - /* Wait for all loggers to finish. */ - ExWaitForRundownProtectionRelease(&KphSsRundownProtect); + /* Spin until the logger count reaches 0. */ + KphSpinUntilEqual(&KphSsNumberOfActiveLoggers, 0); KphSsInitialized = FALSE; @@ -165,7 +166,9 @@ NTSTATUS KphSsLogStop() /* KphSsCreateClientEntry * * Creates a client entry which describes a client of the - * system service logger. Clients receieve system service log events. + * system service logger. Clients receieve system service log events. + * Note that a client may have several process entries associated + * with it. * * ClientEntry: A variable which receives a pointer to the client entry. * ProcessHandle: A handle to the client process, with PROCESS_VM_WRITE @@ -363,9 +366,9 @@ NTSTATUS KphSsCreateProcessEntry( processEntry->TargetProcess = processObject; processEntry->Flags = Flags; - ExAcquireFastMutex(&KphSsMutex); + ExAcquireFastMutex(&KphSsProcessListMutex); InsertHeadList(&KphSsProcessListHead, &processEntry->ProcessListEntry); - ExReleaseFastMutex(&KphSsMutex); + ExReleaseFastMutex(&KphSsProcessListMutex); *ProcessEntry = processEntry; @@ -386,9 +389,9 @@ VOID NTAPI KphpSsProcessEntryDeleteProcedure( KphDereferenceObject(processEntry->Client); - ExAcquireFastMutex(&KphSsMutex); + ExAcquireFastMutex(&KphSsProcessListMutex); RemoveEntryList(&processEntry->ProcessListEntry); - ExReleaseFastMutex(&KphSsMutex); + ExReleaseFastMutex(&KphSsProcessListMutex); } /* KphpSsCreateEventBlock @@ -450,6 +453,10 @@ NTSTATUS KphpSsCreateEventBlock( traceSize = capturedFrames * sizeof(PVOID); eventBlockSize = sizeof(KPHPSS_EVENT_BLOCK) + argumentsSize + traceSize; + /* Check if the event block is too large. */ + if (eventBlockSize > KPHPSS_EVENT_BLOCK_MAX_SIZE) + return STATUS_UNSUCCESSFUL; + /* Allocate the event block. */ eventBlock = ExAllocatePoolWithTag(PagedPool, eventBlockSize, TAG_EVENT_BLOCK); @@ -763,7 +770,7 @@ VOID NTAPI KphpSsLogSystemServiceCall( return; } - ExAcquireFastMutex(&KphSsMutex); + ExAcquireFastMutex(&KphSsProcessListMutex); currentListEntry = KphSsProcessListHead.Flink; processEntryCount = 0; @@ -790,7 +797,7 @@ VOID NTAPI KphpSsLogSystemServiceCall( currentListEntry = currentListEntry->Flink; } - ExReleaseFastMutex(&KphSsMutex); + ExReleaseFastMutex(&KphSsProcessListMutex); /* If we didn't find any process entries, don't bother creating the * event block. @@ -899,13 +906,17 @@ __declspec(naked) VOID NTAPI KphpSsNewKiFastCallEntry() mov cl, [ebx+eax] /* ecx = size of the arguments, in bytes. */ shr ecx, 2 /* divide by 2 to get the number of arguments (all ULONGs) */ - /* Call the KiFastCallEntry proc. */ + /* Call the KiFastCallEntry proc while maintaining the logger count + * so that the driver doesn't get unloaded while we're executing. + */ push esi /* Thread */ push edi /* ServiceTable */ push ecx /* NumberOfArguments */ push edx /* Arguments */ push eax /* Number */ + lock inc dword ptr KphSsNumberOfActiveLoggers call KphpSsLogSystemServiceCall + lock dec dword ptr KphSsNumberOfActiveLoggers /* Restore the registers and resume execution in KiFastCallEntry. */ pop eax