庆祝转正[代码片段2]

以下代码的一份完整代码的第二部分,第一部分请见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;
}

你可能感兴趣的:(HookPort)