虚拟键盘驱动 MASM+KmdKit

 
源自VC版,一些过滤模拟功能没有弄好,但是不影响在设备管理器中模拟出虚拟键盘,用于单价多用户环境非常方便。
 
.386
.model flat, stdcall
option casemap:none

include w2k/ntstatus.inc
include w2k/ntddk.inc
include w2k/ntoskrnl.inc
include w2k/ntddkbd.inc
include w2k/hal.inc
includelib d:/masm32/lib/w2k/ntoskrnl.lib
include Strings.mac
includelib hal.lib
 
IOCTL_TEST                  equ CTL_CODE(FILE_DEVICE_UNKNOWN, 801h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_SENDKEY                   equ CTL_CODE(FILE_DEVICE_UNKNOWN, 802h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_INTERNAL_KEYBOARD_CONNECT   equ CTL_CODE(FILE_DEVICE_UNKNOWN, 803h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_KEYBOARD_QUERY_ATTRIBUTES   equ CTL_CODE(FILE_DEVICE_UNKNOWN, 804h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_KEYBOARD_SET_TYPEMATIC      equ CTL_CODE(FILE_DEVICE_UNKNOWN, 805h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_KEYBOARD_SET_INDICATORS     equ CTL_CODE(FILE_DEVICE_UNKNOWN, 806h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_KEYBOARD_QUERY_TYPEMATIC    equ CTL_CODE(FILE_DEVICE_UNKNOWN, 807h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_KEYBOARD_QUERY_INDICATORS   equ CTL_CODE(FILE_DEVICE_UNKNOWN, 808h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION    equ CTL_CODE(FILE_DEVICE_UNKNOWN, 809h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_KEYBOARD_INSERT_DATA        equ CTL_CODE(FILE_DEVICE_UNKNOWN, 810h, METHOD_BUFFERED, FILE_ANY_ACCESS)
pSeviceCallback        typedef  proto :PDEVICE_OBJECT,:PKEYBOARD_INPUT_DATA,:PKEYBOARD_INPUT_DATA,:dword
_pSeviceCallback       typedef ptr   pSeviceCallback
Keys STRUCT
        Flags           DWORD ?
        Press    DWORD ?
        Code            DWORD ?
Keys ENDS
VK_SENDKEY STRUCT
 Count    DWORD ?
 Temp  Keys   <>
VK_SENDKEY ENDS
PVK_SENDKEY typedef ptr VK_SENDKEY
DEVICE_EXTENSION STRUCT
 fdo                     PDEVICE_OBJECT  ?
 NextStackDevice   PDEVICE_OBJECT  ?
DEVICE_EXTENSION ENDS
pDEVICE_EXTENSION typedef ptr DEVICE_EXTENSION
Data STRUCT
        Flags           DWORD ?
        UnitId          DWORD ?
        MakeCode        DWORD ? 
Data ENDS
MYKEYBOARD_INPUT_DATA typedef ptr Data
.data
KeyboardClassDO   PDEVICE_OBJECT ?
FunctionDevice    PDEVICE_OBJECT ?
UnitId            dd 0
SeviceCallback    _pSeviceCallback ?
.const
CCOUNTED_UNICODE_STRING   " //Device//VKeyboard",DeviceName,4                          
CCOUNTED_UNICODE_STRING                 " //DosDevices//VKeyboard",SymbolicLinkName,4                        
CCOUNTED_UNICODE_STRING                 " //Device//KeyboardClass0", TargetDeviceName, 4
.code
.code
SeviceCallback proc DeviceObject:PDEVICE_OBJECT,InputDataStart:PKEYBOARD_INPUT_DATA,InputDataEnd:PKEYBOARD_INPUT_DATA,InputDataConsumed:dword
 
 
 ret
SeviceCallback endp
DriverEntry proc pDriverObject:PDRIVER_OBJECT,RegistryPath:PUNICODE_STRING                               
LOCAL deviceNameUnicodeString,deviceLinkUnicodeString:UNICODE_STRING
LOCAL status:NTSTATUS
LOCAL pDeviceObject:PVOID
      mov status,STATUS_DEVICE_CONFIGURATION_ERROR
      invoke IoCreateDevice, pDriverObject, 0, addr DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pDeviceObject
                                    
      .if eax == STATUS_SUCCESS                                                                         
            invoke IoCreateSymbolicLink, addr SymbolicLinkName, addr DeviceName                    
           .if eax == STATUS_SUCCESS                                                                      
                mov eax, pDriverObject
                assume eax:PTR DRIVER_OBJECT
                mov esi,[eax].DriverExtension
                assume esi:PTR DRIVER_EXTENSION
                ;添加设备
                mov [esi].AddDevice,offset AddDevice;
                ;Windows应用程序交互函数
                mov [eax].MajorFunction[IRP_MJ_CREATE*(sizeof PVOID)], offset DispatchCreateClose        
                mov [eax].MajorFunction[IRP_MJ_CLOSE*(sizeof PVOID)], offset DispatchCreateClose             
                mov [eax].MajorFunction[IRP_MJ_DEVICE_CONTROL*(sizeof PVOID)], offset DispatchControl
                mov [eax].MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL*(sizeof PVOID)], offset DispatchInternal
                mov [eax].DriverUnload, offset DriverUnload
                ;即插即用、电源管理、系统控制函数
                mov [eax].MajorFunction[IRP_MJ_SYSTEM_CONTROL],offset  SystemControl
                mov [eax].MajorFunction[IRP_MJ_POWER*(sizeof PVOID)], offset DispatchPower
                mov [eax].MajorFunction[IRP_MJ_PNP*(sizeof PVOID)], offset DispatchPnp
                assume eax:nothing
                assume esi:nothing
                mov status, STATUS_SUCCESS
           .else
                invoke IoDeleteDevice, pDeviceObject
           .endif
      .endif
      mov eax, status
      ret
DriverEntry endp
DispatchCreateClose proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
       mov eax, pIrp
       assume eax:ptr _IRP
       mov [eax].IoStatus.Status, STATUS_SUCCESS
       and [eax].IoStatus.Information, 0
       assume eax:nothing
       fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
       mov eax, STATUS_SUCCESS
       ret
DispatchCreateClose endp
DriverUnload proc pDriverObject:PDRIVER_OBJECT
       invoke IoDeleteSymbolicLink, addr SymbolicLinkName                        
       mov eax, pDriverObject
       invoke IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject             
       ret
DriverUnload endp
DispatchPnp proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
LOCAL Status : NTSTATUS
LOCAL MinorFunction:dword
 .if FunctionDevice == PDEVICE_OBJECT
         mov ecx, pIrp
         and (_IRP PTR [ecx]).IoStatus.Information, 0
         mov eax, Status
         mov (_IRP PTR [ecx]).IoStatus.Status, eax
         fastcall IofCompleteRequest, ecx, IO_NO_INCREMENT
                mov eax, Status
 .endif
 mov Status, STATUS_UNSUCCESSFUL
 mov esi, pIrp
 assume esi:ptr _IRP
 mov [esi].IoStatus.Status, STATUS_UNSUCCESSFUL
 and [esi].IoStatus.Information, 0
 IoGetCurrentIrpStackLocation esi
 mov edi, eax
 assume edi:ptr IO_STACK_LOCATION
 .if [edi].MinorFunction==IRP_MN_REMOVE_DEVICE
         .if DEVICE_EXTENSION.NextStackDevice
                 invoke IoDetachDevice, DEVICE_EXTENSION.NextStackDevice
         .endif
         mov eax, pDeviceObject
  and pDeviceObject, NULL
  invoke IoDeleteDevice, pDeviceObject
 .endif
 mov Status, STATUS_SUCCESS
 assume esi:nothing
 assume edi:nothing
 ret
DispatchPnp endp
DispatchPower proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
 invoke PoStartNextPowerIrp, pIrp
    IoSkipCurrentIrpStackLocation pIrp 
 mov eax, pDeviceObject
 mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
 mov eax, (DEVICE_EXTENSION ptr [eax]).NextStackDevice
 invoke PoCallDriver, eax, pIrp
 ret
DispatchPower endp
AddDevice proc pDeviceObject:PDEVICE_OBJECT, pDriverObject:PDRIVER_OBJECT
LOCAL Status : NTSTATUS
LOCAL pFilterDeviceObject:PDEVICE_OBJECT
local pTargetDeviceObject:PDEVICE_OBJECT
local pTargetFileObject:PFILE_OBJECT
LOCAL pControlDeviceObject:PDEVICE_OBJECT 
local status:NTSTATUS
 invoke DbgPrint, $CTA0("KbdSpy: Entering KeyboardAttach/n")
 mov status, STATUS_UNSUCCESSFUL
 .if ( pFilterDeviceObject != NULL )
  mov status, STATUS_SUCCESS
 .else
  mov eax, pControlDeviceObject
  mov ecx, (DEVICE_OBJECT PTR [eax]).DriverObject
  invoke IoCreateDevice, ecx, sizeof DEVICE_EXTENSION, NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, addr pFilterDeviceObject
  .if eax == STATUS_SUCCESS 
   invoke IoGetDeviceObjectPointer, addr TargetDeviceName, FILE_READ_DATA, addr pTargetFileObject, addr pTargetDeviceObject
   .if eax == STATUS_SUCCESS   
    mov eax, pDriverObject
    and (DRIVER_OBJECT PTR [eax]).DriverUnload, NULL   
    invoke IoAttachDeviceToDeviceStack, pFilterDeviceObject, pTargetDeviceObject
    .if eax != NULL
     mov edx, eax
     mov ecx, pFilterDeviceObject
     mov eax, (DEVICE_OBJECT ptr [ecx]).DeviceExtension
     assume eax:ptr DEVICE_EXTENSION
     mov [eax].NextStackDevice, edx
     push pTargetFileObject
     pop [eax].NextStackDevice
     assume eax:nothing
     assume edx:ptr DEVICE_OBJECT
     assume ecx:ptr DEVICE_OBJECT
     mov eax, [edx].DeviceType
     mov [ecx].DeviceType, eax
     mov eax, [edx].Flags
     and eax, DO_DIRECT_IO + DO_BUFFERED_IO + DO_POWER_PAGABLE
     or [ecx].Flags, eax
     and [ecx].Flags, not DO_DEVICE_INITIALIZING
     assume edx:nothing
     assume ecx:nothing
     mov status, STATUS_SUCCESS
    .else  
     invoke ObDereferenceObject, pTargetFileObject    
     invoke IoDeleteDevice, pFilterDeviceObject
     and pFilterDeviceObject, NULL 
     mov eax, pDriverObject
     mov (DRIVER_OBJECT PTR [eax]).DriverUnload, offset DriverUnload
     invoke DbgPrint, $CTA0("KbdSpy: Couldn't attach to target device/n")
     mov status, STATUS_NO_SUCH_DEVICE
    .endif      
   .else  
    invoke IoDeleteDevice, pFilterDeviceObject
    and pFilterDeviceObject, NULL     
    invoke DbgPrint, $CTA0("KbdSpy: Couldn't get target device object pointer/n")
   .endif
  .else
   invoke DbgPrint, $CTA0("KbdSpy: Couldn't create filter device/n")
  .endif
 .endif
 mov eax, status
 ret
AddDevice endp
SystemControl proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
LOCAL Status : NTSTATUS
 .if FunctionDevice == DEVICE_EXTENSION.fdo
         fastcall IofCompleteRequest, ecx, IO_NO_INCREMENT  
 .endif
        mov eax, Status
 ret
SystemControl endp
DispatchInternal proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
LOCAL Status : NTSTATUS
local pEventObject:PKEVENT
local ioControlCode:dword
        mov Status,STATUS_SUCCESS
        mov esi, pIrp
        assume esi : ptr _IRP
        IoGetCurrentIrpStackLocation esi
        mov edi, eax
        assume edi : ptr IO_STACK_LOCATION
        mov eax, [edi].Parameters.DeviceIoControl.IoControlCode
        mov ioControlCode,eax
        .if eax==IOCTL_INTERNAL_KEYBOARD_CONNECT
       
        .elseif eax==IOCTL_KEYBOARD_QUERY_ATTRIBUTES
         
        .elseif eax==IOCTL_KEYBOARD_SET_TYPEMATIC
         
        .elseif eax==IOCTL_KEYBOARD_SET_INDICATORS
         
        .elseif eax==IOCTL_KEYBOARD_QUERY_TYPEMATIC
       
        .elseif eax==IOCTL_KEYBOARD_QUERY_INDICATORS
         
        .elseif eax==IOCTL_KEYBOARD_QUERY_INDICATOR_TRANSLATION
       
        .elseif eax==IOCTL_KEYBOARD_INSERT_DATA
          
        .endif
    IoSkipCurrentIrpStackLocation pIrp
 mov eax, pDeviceObject
 mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
 mov eax, (DEVICE_EXTENSION ptr [eax]).NextStackDevice
 invoke IoCallDriver, eax, pIrp
 assume edi:nothing
 assume esi:nothing
 ret
DispatchInternal endp
DispatchControl proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
local inputBuffer:PVOID    
local inputBufferLength:dword       
local outputBuffer:PVOID                 
local outputBufferLength:dword
local ioControlCode:dword
local workItem:dword ;WORK_QUEUE_ITEM
LOCAL Status : NTSTATUS
LOCAL dwBytesReturned
LOCAL IoStatus:dword
LOCAL IoBuffer:dword
LOCAL NumSend:dword
        mov Status,STATUS_SUCCESS
        mov esi, pIrp
        assume esi : ptr _IRP
        IoGetCurrentIrpStackLocation esi
        mov edi, eax
        assume edi : ptr IO_STACK_LOCATION
        mov eax,[esi].IoStatus.Status
        mov IoStatus,eax
        mov eax,[esi].AssociatedIrp.SystemBuffer
        mov IoBuffer,eax
        mov eax, [edi].Parameters.DeviceIoControl.IoControlCode
        mov ioControlCode,eax
        mov eax, [esi].AssociatedIrp.SystemBuffer
        mov inputBuffer,eax
        mov outputBuffer,eax
        mov eax,[edi].Parameters.DeviceIoControl.InputBufferLength
        mov inputBufferLength,eax
        mov eax,[edi].Parameters.DeviceIoControl.OutputBufferLength
        mov outputBufferLength,eax
 mov Status, STATUS_UNSUCCESSFUL
 mov esi, pIrp
 assume esi:ptr _IRP
 mov [esi].IoStatus.Status, STATUS_UNSUCCESSFUL
 and [esi].IoStatus.Information, 0
 IoGetCurrentIrpStackLocation esi
 mov edi, eax
 assume edi:ptr IO_STACK_LOCATION
        mov Status, STATUS_INVALID_DEVICE_REQUEST
        mov NumSend,0
@loop:
        mov esi,VK_SENDKEY.Count
 .if ioControlCode == IOCTL_SENDKEY
         .if IoBuffer==0 || inputBufferLength < sizeof VK_SENDKEY  || esi > 5
                 mov Status,  STATUS_INVALID_PARAMETER             
                 jmp @exit
                .endif
                xor ecx,ecx
        @@:
                inc ecx
                .if ecx> esi
                 jmp @f
                .endif
                mov eax,VK_SENDKEY.Temp.Press
                .if eax==0
                        mov eax,KEYBOARD_INPUT_DATA
                 mov Data[ecx],eax
                .endif
               
                invoke SeviceCallback,KeyboardClassDO,Data, Data[ecx],addr NumSend
                mov Status,STATUS_SUCCESS
        @@:        
        .else
         mov Status, STATUS_INVALID_DEVICE_REQUEST
        .endif
 
@exit: 
 mov ecx, pIrp
 and (_IRP PTR [ecx]).IoStatus.Information, 0
 mov eax, Status
 mov (_IRP PTR [ecx]).IoStatus.Status, eax
        fastcall IofCompleteRequest, ecx, IO_NO_INCREMENT
        mov eax, Status
        assume edi:nothing
        assume esi:nothing
 ret
DispatchControl endp
end DriverEntry
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值