可能现在没什么人弄进程保护了...发一段代码...里面某些变量对不上意义...因为之前HOOK 别的函数...懒得改名了..将就
  #include "ntddk.h" 
#include "myh.h"
/*
//可能有MP后不起作用了
*/
UCHAR *
PsGetProcessImageFileName(
    __in PEPROCESS Process
    );

typedef VOID  (FASTCALL *KIINSERTQUEUEAPC)(IN PKAPC Apc,IN KPRIORITY Increment);
KIINSERTQUEUEAPC g_OldKiInsertQueueApc;

ULONG g_OldObpAllocateObjectOffset;
ULONG* g_TargetMmExchangeValue;
BOOLEAN bIsHook=FALSE;

VOID FASTCALL Fake_KiInsertQueueApc(IN PKAPC Apc,IN KPRIORITY Increment)
{
  ULONG pTargetThread;
    ULONG pTargetProcess;
    UCHAR *pTargetProcessName;
  
  if(MmIsAddressValid((PULONG)((ULONG)Apc+0x008)))
  pTargetThread=*((PULONG)((ULONG)Apc+0x008)); //   +0x008 Thread           : Ptr32 _KTHREAD
    if(MmIsAddressValid((PULONG)((ULONG)pTargetThread + 0x044 )))
  pTargetProcess =*((PULONG)((ULONG)pTargetThread + 0x044 ));  //+0x034 ApcState         : _KAPC_STATE      
    
  pTargetProcessName=PsGetProcessImageFileName((PEPROCESS)pTargetProcess);
    
  if((_stricmp(pTargetProcessName,"notepad.exe")==0)&&(Increment==2))
    //DbgPrint("hi---notepad.ex ");
    return;
  //  return ;
//  DbgPrint("hi--- ");
  g_OldKiInsertQueueApc(Apc,Increment);


    
}

VOID MmExchangeValue(PULONG  Target,ULONG  Value)
{
  KIRQL oldIrql;
  oldIrql = KeRaiseIrqlToDpcLevel(); //注意自旋锁
  __asm
  {
    CLI          
    MOV  EAX, CR0    
    AND EAX, NOT 10000H 
    MOV  CR0, EAX    
  }
    
    
    InterlockedExchange(Target,Value);
      
  __asm 
  {
    MOV  EAX, CR0    
    OR  EAX, 10000H    
    MOV  CR0, EAX      
    STI          
  }
  KeLowerIrql(oldIrql); 
}



BOOLEAN  HookKiInsertQueueApc()
{
  BYTE* FunctionAddress;
  BYTE* CurrentAddress;
  ULONG tempAddr, HookAddress,NewOffset;
  PVOID KeInsertQueueApcAddr;
  UNICODE_STRING Uni_ObCreateObject;
  
  RtlInitUnicodeString(&Uni_ObCreateObject,L"KeInsertQueueApc");
  KeInsertQueueApcAddr =  MmGetSystemRoutineAddress(&Uni_ObCreateObject);
  
  if(KeInsertQueueApcAddr == NULL)
    return FALSE;
  
  FunctionAddress=(BYTE*)KeInsertQueueApcAddr;
  
  for(CurrentAddress=FunctionAddress;CurrentAddress<FunctionAddress+0x200; CurrentAddress++)
  {
    if(MmIsAddressValid((BYTE*)CurrentAddress))
      
    if(*(BYTE*)CurrentAddress==0x28&&*(BYTE*)(CurrentAddress+1)==0xe8)
    {
      tempAddr = *(ULONG*)(CurrentAddress+2);
      if(MmIsAddressValid((ULONG*)((BYTE*)(CurrentAddress+1)+1)))
      {
        
        if(tempAddr&0x10000000)
        {
          NewOffset = (ULONG)Fake_KiInsertQueueApc+0xFFFFFFFB-(ULONG)(CurrentAddress+1);
          g_OldObpAllocateObjectOffset = *(ULONG*)((BYTE*)(CurrentAddress+2));
          HookAddress=*(ULONG*)((BYTE*)(CurrentAddress+2))+(ULONG)(CurrentAddress+1)-0xFFFFFFFB;
          g_TargetMmExchangeValue = (ULONG*)((BYTE*)(CurrentAddress+2));
          //DbgPrint("hi--- %x",HookAddress);
          MmExchangeValue((ULONG*)((BYTE*)(CurrentAddress+2)),NewOffset);
          bIsHook =TRUE;
        }
        else
        {
          NewOffset = (ULONG)Fake_KiInsertQueueApc-(ULONG)(CurrentAddress+1)-5;
          g_OldObpAllocateObjectOffset = *(ULONG*)((BYTE*)(CurrentAddress+2));
          HookAddress=*(ULONG*)((BYTE*)(CurrentAddress+2))+(ULONG)(CurrentAddress+1)+5;
          g_TargetMmExchangeValue = (ULONG*)((BYTE*)(CurrentAddress+2));
          MmExchangeValue((ULONG*)((BYTE*)(CurrentAddress+2)),NewOffset);
          bIsHook =TRUE;
        }
         g_OldKiInsertQueueApc = (KIINSERTQUEUEAPC)HookAddress;
        //DbgPrint("hi--- %x", g_OldObpAllocateObject);
        break;
      }
    }
  }
  return TRUE;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



VOID Unload(PDRIVER_OBJECT DriverObject) 

  if(bIsHook ==TRUE)
  MmExchangeValue(g_TargetMmExchangeValue,g_OldObpAllocateObjectOffset);
  


NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING str) 

  
  HookKiInsertQueueApc();

  
  DriverObject->DriverUnload = Unload; 
  return STATUS_SUCCESS; 
}