?? mouspy.bat
字號:
; underneath us to our filter device object. We also need to copy DO_DIRECT_IO,
; DO_BUFFERED_IO, and DO_POWER_PAGABLE flags. This guarantees that the filter
; device object looks the same as the target device object.
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
; IoCreateDevice sets the DO_DEVICE_INITIALIZING flag in the device object.
; While this flag is set, the I/O Manager will refuse to attach other device
; objects to us or to open a handle to our device. So we have to clear
; this flag because now we are ready to filter.
;
; Note: It is not necessary to clear the DO_DEVICE_INITIALIZING flag on device
; objects that are created in DriverEntry, because this is done automatically
; by the I/O Manager.
and [ecx].Flags, not DO_DEVICE_INITIALIZING
assume edx:nothing
assume ecx:nothing
mov status, STATUS_SUCCESS
.else ; IoAttachDeviceToDeviceStack failed
; We have failed to attach
invoke ObDereferenceObject, pTargetFileObject
invoke IoDeleteDevice, g_pFilterDeviceObject
and g_pFilterDeviceObject, NULL
; Let the driver to be unloaded
mov eax, g_pDriverObject
mov (DRIVER_OBJECT PTR [eax]).DriverUnload, offset DriverUnload
invoke DbgPrint, $CTA0("MouSpy: Couldn't attach to target device\n")
mov status, STATUS_NO_SUCH_DEVICE
.endif
.else ; IoGetDeviceObjectPointer failed
invoke IoDeleteDevice, g_pFilterDeviceObject
and g_pFilterDeviceObject, NULL
invoke DbgPrint, $CTA0("MouSpy: Couldn't get target device object pointer\n")
.endif
.else
invoke DbgPrint, $CTA0("MouSpy: Couldn't create filter device\n")
.endif
.endif
mov eax, status
ret
MouseAttach endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; MouseDetach
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
MouseDetach proc
local status:NTSTATUS
local pTopmostDeviceObject:PDEVICE_OBJECT
invoke DbgPrint, $CTA0("MouSpy: Entering MouseDetach\n")
mov status, STATUS_UNSUCCESSFUL
.if g_pFilterDeviceObject != NULL
; Lets see if there is someone above us.
; Temporary set the DO_DEVICE_INITIALIZING flag in filter device object.
; So no one can attach while we check the stack.
mov eax, g_pFilterDeviceObject
or (DEVICE_OBJECT ptr [eax]).Flags, DO_DEVICE_INITIALIZING
invoke IoGetAttachedDeviceReference, g_pFilterDeviceObject
mov pTopmostDeviceObject, eax
.if eax != g_pFilterDeviceObject
; Someone sits on the top of us. Do nothing except restoring
; Flags field in the filter device object
mov eax, g_pFilterDeviceObject
and (DEVICE_OBJECT ptr [eax]).Flags, not DO_DEVICE_INITIALIZING
invoke DbgPrint, $CTA0("MouSpy: Couldn't detach. Someone sits over\n")
invoke DbgPrint, $CTA0("MouSpy: Filter device is still attached\n")
.else
mov eax, g_pFilterDeviceObject
mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
mov ecx, (FiDO_DEVICE_EXTENSION ptr [eax]).pTargetFileObject
fastcall ObfDereferenceObject, ecx
mov eax, g_pFilterDeviceObject
mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
mov eax, (FiDO_DEVICE_EXTENSION ptr [eax]).pNextLowerDeviceObject
invoke IoDetachDevice, eax
mov status, STATUS_SUCCESS
invoke DbgPrint, $CTA0("MouSpy: Filter device detached\n")
; Destroy filter device.
mov eax, g_pFilterDeviceObject
and g_pFilterDeviceObject, NULL
invoke IoDeleteDevice, eax
; Our driver is still not unloadable because we might have outstanding IRPs
.endif
; Dereference the device object pointer returned by IoGetAttachedDeviceReference
invoke ObDereferenceObject, pTopmostDeviceObject
.endif
mov eax, status
ret
MouseDetach endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; FiDO_DispatchPassThrough
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
FiDO_DispatchPassThrough proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
; The default dispatch routine. Our driver should send down all IRPs it deal not with
IoSkipCurrentIrpStackLocation pIrp
mov eax, pDeviceObject
mov eax, (DEVICE_OBJECT ptr [eax]).DeviceExtension
mov eax, (FiDO_DEVICE_EXTENSION ptr [eax]).pNextLowerDeviceObject
invoke IoCallDriver, eax, pIrp
ret
FiDO_DispatchPassThrough endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; CDO_DispatchCreate
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CDO_DispatchCreate proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
local status:NTSTATUS
local MouseData:MOUSE_DATA
invoke DbgPrint, $CTA0("MouSpy: Entering CDO_DispatchCreate\n")
; Drain g_MouseDataListHead. If someone have ran MouSpy previously
; but have failed to unload the driver because of not moving
; the mouse as recommended, we have at least one pending IRP. When
; someone move the mouse this pending IRP is completed and our
; completion routine will add one entry into g_MouseDataListHead.
; So if it's not a first time we are being created we may have
; some entr(ies)y in g_MouseDataListHead from previous sessions.
; So lets throw them away.
.while TRUE
invoke RemoveEntry, addr MouseData
.break .if eax == 0
.endw
MUTEX_ACQUIRE g_mtxCDO_State
.if g_fCDO_Opened
; Only one client at a time is allowed
mov status, STATUS_DEVICE_BUSY
.else
; No one else may open control device
mov g_fCDO_Opened, TRUE
mov status, STATUS_SUCCESS
.endif
MUTEX_RELEASE g_mtxCDO_State
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
ret
CDO_DispatchCreate endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; CDO_DispatchClose
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CDO_DispatchClose proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
invoke DbgPrint, $CTA0("MouSpy: Entering CDO_DispatchClose\n")
; Do not set completion routine any more
and g_fSpy, FALSE
and g_fInvertButtons, FALSE
and g_fInvertMovement, FALSE
MUTEX_ACQUIRE g_mtxCDO_State
.if ( g_pFilterDeviceObject == NULL )
.if g_dwPendingRequests == 0
; If we have datached from the mouse stack, and there is
; no outstanding IRPs it's safe to unload.
mov eax, g_pDriverObject
mov (DRIVER_OBJECT PTR [eax]).DriverUnload, offset DriverUnload
.endif
.endif
; Someone else may open control device
and g_fCDO_Opened, FALSE
MUTEX_RELEASE g_mtxCDO_State
mov eax, STATUS_SUCCESS
mov ecx, pIrp
and (_IRP PTR [ecx]).IoStatus.Information, 0
mov (_IRP PTR [ecx]).IoStatus.Status, eax
push eax
fastcall IofCompleteRequest, ecx, IO_NO_INCREMENT
pop eax
ret
CDO_DispatchClose endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; FillMouseData
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
FillMouseData proc uses edi ebx pBuffer:PVOID, cbBuffer:DWORD
local MouseData:MOUSE_DATA
local cbReturned:DWORD
and cbReturned, 0
; Lets see how many MOUSE_DATAs will fit into passed in buffer
mov eax, cbBuffer
mov ecx, sizeof MOUSE_DATA
xor edx, edx
div ecx
mov ebx, eax
mov edi, pBuffer
.while ebx
invoke RemoveEntry, edi
.break .if eax == 0
add cbReturned, eax
dec ebx
add edi, sizeof MOUSE_DATA
.endw
mov eax, cbReturned
ret
FillMouseData endp
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
; CDO_DispatchDeviceControl
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CDO_DispatchDeviceControl proc uses esi edi ebx pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
local status:NTSTATUS
local pEventObject:PKEVENT
local liDelayTime:LARGE_INTEGER
local MouseData:MOUSE_DATA
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].Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUSE_ATTACH
.if [edi].Parameters.DeviceIoControl.InputBufferLength == sizeof HANDLE
MUTEX_ACQUIRE g_mtxCDO_State
; The user-mode client wants us attach to the mouse device stack
mov edx, [esi].AssociatedIrp.SystemBuffer
mov edx, [edx] ; event handle from user-mode
mov ecx, ExEventObjectType
mov ecx, [ecx]
mov ecx, [ecx] ; PTR OBJECT_TYPE
invoke ObReferenceObjectByHandle, edx, EVENT_MODIFY_STATE, ecx, \
UserMode, addr pEventObject, NULL
.if eax == STATUS_SUCCESS
; If passed event handle is valid, attach to mouse
.if !g_fFiDO_Attached
invoke MouseAttach
mov [esi].IoStatus.Status, eax
.if eax == STATUS_SUCCESS
mov eax, pEventObject
mov g_pEventObject, eax ; No need to lock, since mov is atomic
mov g_fFiDO_Attached, TRUE
mov g_fSpy, TRUE ; Set completion routine.
.else
; Failed to attach
invoke ObDereferenceObject, pEventObject
.endif
.else
; We was attached
LOCK_ACQUIRE g_EventSpinLock
mov bl, al ; old IRQL
mov eax, g_pEventObject
.if eax != NULL
and g_pEventObject, NULL
invoke ObDereferenceObject, eax
.endif
mov eax, pEventObject
mov g_pEventObject, eax
LOCK_RELEASE g_EventSpinLock, bl
mov g_fSpy, TRUE ; Set completion routine.
mov [esi].IoStatus.Status, STATUS_SUCCESS
.endif
.else
mov [esi].IoStatus.Status, STATUS_INVALID_PARAMETER
.endif
MUTEX_RELEASE g_mtxCDO_State
.else
mov [esi].IoStatus.Status, STATUS_INFO_LENGTH_MISMATCH
.endif
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUSE_DETACH
MUTEX_ACQUIRE g_mtxCDO_State
; The user-mode client wants us to detach from the mouse device stack
.if g_fFiDO_Attached
; Do not set completion routine any more no matter will we detach or not
and g_fSpy, FALSE
and g_fInvertButtons, FALSE
and g_fInvertMovement, FALSE
invoke MouseDetach
mov [esi].IoStatus.Status, eax
.if eax == STATUS_SUCCESS
mov g_fFiDO_Attached, FALSE
.endif
LOCK_ACQUIRE g_EventSpinLock
mov bl, al ; old IRQL
mov eax, g_pEventObject
.if eax != NULL
and g_pEventObject, NULL
invoke ObDereferenceObject, eax
.endif
LOCK_RELEASE g_EventSpinLock, bl
.endif
MUTEX_RELEASE g_mtxCDO_State
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_MOUSE_DATA
.if [edi].Parameters.DeviceIoControl.OutputBufferLength >= sizeof MOUSE_DATA
invoke FillMouseData, [esi].AssociatedIrp.SystemBuffer, \
[edi].Parameters.DeviceIoControl.OutputBufferLength
mov [esi].IoStatus.Information, eax
mov [esi].IoStatus.Status, STATUS_SUCCESS
.else
mov [esi].IoStatus.Status, STATUS_BUFFER_TOO_SMALL
.endif
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_INVERT_BUTTONS
.if [edi].Parameters.DeviceIoControl.InputBufferLength == sizeof BOOL
mov eax, [esi].AssociatedIrp.SystemBuffer
mov eax, [eax]
mov g_fInvertButtons, eax
and [esi].IoStatus.Information, 0
mov [esi].IoStatus.Status, STATUS_SUCCESS
.else
mov [esi].IoStatus.Status, STATUS_INFO_LENGTH_MISMATCH
.endif
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -