以下代码的一份完整代码的第二部分,第一部分请见http://hi.baidu.com/ejoywx/item/34e6111be1fba7d9bf90428d
PVOID BuildMDL(PVOID VirtualAddress, ULONG Length, PMDL *pMDL) { PMDL Mdl = NULL; PVOID retval = NULL; Mdl = IoAllocateMdl(VirtualAddress, Length, FALSE, FALSE, NULL); *pMDL = Mdl; if ( Mdl ) { MmProbeAndLockPages( Mdl, KernelMode, IoModifyAccess); if ( Mdl->MdlFlags & ( MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL ) ) { retval = Mdl->MappedSystemVa; } else { retval = MmMapLockedPagesSpecifyCache( Mdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority); } } return retval; } VOID FreeMDL(PMDL Mdl) { MmUnlockPages( Mdl ); IoFreeMdl( Mdl ); } typedef struct _DPCCONTEXT { PKSPIN_LOCK SpinLock; PULONG iCount ; }DPCCONTEXT,*PDPCCONTEXT; VOID DeferredRoutine(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1,PVOID SystemArgument2 ) { PDPCCONTEXT Context = (PDPCCONTEXT)DeferredContext; KIRQL OldIrql = 0; __asm cli; OldIrql = KeRaiseIrqlToDpcLevel(); InterlockedIncrement( (volatile LONG *)(Context->iCount) ); KefAcquireSpinLockAtDpcLevel( Context->SpinLock); KefReleaseSpinLockFromDpcLevel( Context->SpinLock ); KeLowerIrql( OldIrql ); __asm sti } NTSTATUS ModifyHookPort( PVOID HookPoint, PVOID SystemVa, PVOID FilterFunc, PLARGE_INTEGER OldBytes ) { NTSTATUS Status = STATUS_UNSUCCESSFUL; LARGE_INTEGER NewBytes = {0}; KDPC DpcArray[32]= {0}; ULONG iActiveCpu = 0; ULONG ActiveCPUs = 0; ULONG CurrentCpu = 0; ULONG Index = 0; ULONG iDpcCount = 0; ULONG iLikeNop = 0; KSPIN_LOCK SpinLock = 0; DPCCONTEXT DpcContext = {0}; KIRQL OldIrql = 0; //if ( SystemVa && FilterFunc ) { NewBytes.LowPart = 0xE9909090; NewBytes.HighPart= (ULONG)FilterFunc - (ULONG)HookPoint - 8; ActiveCPUs = KeQueryActiveProcessors(); Index = 0; do { if ( ( ActiveCPUs >> Index ) & 0x01 ) { ++iActiveCpu; } } while ( ++Index < 31 ); if ( iActiveCpu == 1 ) { __asm cli; OldIrql = KeRaiseIrqlToDpcLevel(); if( OldBytes ) { OldBytes->QuadPart = *(PULONGLONG)SystemVa; } InterlockedCompareExchange64( (LONGLONG volatile*)SystemVa, *(PLONGLONG)&NewBytes, *(PLONGLONG)SystemVa ); KeLowerIrql( OldIrql ); __asm sti; Status = STATUS_SUCCESS; } else { KeInitializeSpinLock( &SpinLock ); DpcContext.SpinLock = &SpinLock; DpcContext.iCount = &iDpcCount; Index = 0; do { KeInitializeDpc( &DpcArray[Index], DeferredRoutine, &DpcContext ); } while ( ++Index < 31 ); __asm cli; KeAcquireSpinLock( &SpinLock, &OldIrql ); CurrentCpu = KeGetCurrentProcessorNumber(); Index = 0; do { if ( ( ActiveCPUs >> Index ) & 0x01 ) { if ( Index != CurrentCpu ) { KeSetTargetProcessorDpc( &DpcArray[Index], (CCHAR)Index ); KeSetImportanceDpc( &DpcArray[Index], HighImportance); KeInsertQueueDpc( &DpcArray[Index], NULL, NULL ); } } } while ( ++Index < 31 ); Index = 0; do { iLikeNop = 1000000; while ( --iLikeNop ); if ( iDpcCount == iActiveCpu-1 ) { if( OldBytes ) { OldBytes->QuadPart = *(PULONGLONG)SystemVa; } InterlockedCompareExchange64( (LONGLONG volatile*)SystemVa, *(PLONGLONG)&NewBytes, *(PLONGLONG)SystemVa ); Status = STATUS_SUCCESS; break; } }while ( ++Index <= 15 ); KeReleaseSpinLock( &SpinLock, OldIrql); __asm sti } } return Status; } NTSTATUS MagicHookFunc(PVOID HookPoint, PVOID FilterFunc, PLARGE_INTEGER OriginalBytes) { NTSTATUS Status = STATUS_UNSUCCESSFUL; PMDL pMdl = NULL; PUCHAR SystemVa = NULL; if ( HookPoint && FilterFunc ) { SystemVa = BuildMDL( HookPoint, 8, &pMdl); if ( pMdl ) { Status = ModifyHookPort( HookPoint, SystemVa, FilterFunc, OriginalBytes ); FreeMDL(pMdl); } } return Status; }