⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vxdmon.asm

📁 VxDMon_系统驱动监视器,对感兴趣的人会有帮助的。
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	Control_Dispatch W32_DEVICEIOCONTROL,		VXDMHLP_ioctl
	clc
	ret

VXDMHLP_Control ENDP


;============================================================================
;
; VXDMHLP_ioctl - Respond to IOcontrol messages sent by Win32 program.
;
; Entry: esi -> DIOC block
; 
; Exit:
;
;============================================================================

Public VXDMHLP_ioctl
BeginProc VXDMHLP_ioctl

	mov	IoctlError, VXDMHLP_ERROR_NOSUCHSERVICE
	mov	ecx,[esi].dwIoControlCode	; get ioctl code
	inc	ecx				; base is -1
	cmp	ecx, Service_Table_Size		; out of bounds ?
	jae	ioctl_failure			; y: bad code, exit
	jmp	Service_Table[4*ecx]		; index into table

; -------------------------------------------------------------------------
; -------------------------------------------------------------------------
ioctl_closehandle:
	; Nothing to do for this
	jmp	ioctl_success		; exit successfully

; -------------------------------------------------------------------------
; -------------------------------------------------------------------------
ioctl_getversion:
	; Nothing to do for this
	jmp	ioctl_success		; exit successfully

; -------------------------------------------------------------------------
; Get the statistics we've collected for all hooked services
; -------------------------------------------------------------------------

ioctl_zerostats:
	mov	ebx, ZEROSTATS			; zero the stats, no update
	mov	edx, [HookUsed]
	cld
ioctl_dozero:
	; check for end of list
	cmp	edx, 0
	je	ioctl_success

	; zero volatile statistics
	cli
	push	esi
	lea	esi, [edx]			; get stats pointer
	xor	eax, eax
	mov	[esi].SS_Enter,  eax
	mov	[esi].SS_Exit,   eax
	mov	[esi].SS_TimeLo, eax
	mov	[esi].SS_TimeHi, eax
	sti
	pop	esi
	; move to next service
	mov	edx, [edx].SS_Next
	jmp	ioctl_dozero

; get stats with no zero

ioctl_getstats:
	mov	ebx, UPDATESTATS		; update with no clear
	jmp	ioctl_scanstats

; get stats and reset

ioctl_getzerostats:
	mov	ebx, UPDATEZEROSTATS		; update and zero stats

ioctl_scanstats:
	; zero current output size
	xor	eax, eax
	mov	ecx, [esi].lpcbBytesReturned
	mov	[ecx], eax
	; get pointer to source and destination buffers
	mov	edx, [HookUsed]
	mov	edi, [esi].lpvOutBuffer
	; iterate over structures in use, copying
	cld
ioctl_docopy:
	; check for end of list
	cmp	edx, 0
	je	ioctl_success

	; update size of output and exit if buffer full
	mov	ecx, [esi].lpcbBytesReturned	; get output size pointer
	mov	eax, [ecx]			; get current output size
	add	eax, size ServiceStats		; update total size
	cmp	eax, [esi].cbOutBuffer		; less than max output size ?
	jg	ioctl_success
	mov	[ecx], eax			; update output size
	; copy stats to output buffer
	push	esi
	mov	ecx, size ServiceStats / 4
	lea	esi, [edx]			; get stats pointer
	cli
	rep movsd

	test	ebx, ZEROSTATS
	je	nozero

	; zero volatile statistics
	xor	eax, eax
	mov	[esi - size ServiceStats].SS_Enter,  eax
	mov	[esi - size ServiceStats].SS_Exit,   eax
	mov	[esi - size ServiceStats].SS_TimeLo, eax
	mov	[esi - size ServiceStats].SS_TimeHi, eax
nozero:
	sti
	pop	esi
	; move to next service
	mov	edx, [edx].SS_Next
	jmp	ioctl_docopy

; -------------------------------------------------------------------------
; Hook a new service
; -------------------------------------------------------------------------
ioctl_hookservice:
	; get ordinal of interest
	mov	eax, [esi].lpvInBuffer
	mov	eax, [eax]
internal_hookservice:
	; ensure that the vxd is loaded
	mov	IoctlError, VXDMHLP_ERROR_NOSUCHVXD
	mov	edx, eax		; save ordinal
	shr	eax, 16			; get device id
	jz	ioctl_failure		; if zero, we lose
	VMMCall	Get_DDB			; check for DDB
	or	ecx, ecx
	jz	ioctl_failure		; if result zero, we lose
	mov	eax, edx		; restore ordinal
	; get a hook structure
	mov	IoctlError, VXDMHLP_ERROR_OUTOFMEMORY
	mov	edi, [HookFree]
	cmp	edi, 0
	je	ioctl_failure	; no structures available
	; Ensure the page containing the structure is locked in memory.
	; We rely on the fact that a page can be locked multiple times.
	mov	IoctlError, VXDMHLP_ERROR_PAGELOCK
	push	eax
	mov	eax, edi
	shr	eax, 12
	VMMcall _LinPageLock, <eax, 1, 0>
	or	eax, eax	; nonzero if locked, zero if error
	pop	eax
	jz	ioctl_failure
	; fill in service-specific info in structure
	mov	[edi].SS_Ordinal, eax
	xor	edx, edx
	mov	[edi].SS_Enter,  edx
	mov	[edi].SS_Exit,   edx
	mov	[edi].SS_TimeLo, edx
	mov	[edi].SS_TimeHi, edx
	; hook the service
	mov	IoctlError, VXDMHLP_ERROR_HOOK
	push	esi
	lea	esi, [edi +(offset32 HookTemplateProc - offset32 HookTemplate)]
	VMMCall	Hook_Device_Service
	pop	esi
	jc	ioctl_failure
	; update pointer to next available structure
	mov	edx, [edi].SS_Next
	mov	[HookFree], edx
	; add to list of hooked services
	mov	eax, [HookUsed]
	mov	[edi].SS_Next, eax
	mov	[HookUsed], edi
	jmp	ioctl_success

; -------------------------------------------------------------------------
; Unhook a service
; -------------------------------------------------------------------------
ioctl_unhookservice:
	; get ordinal of interest
	mov	eax, [esi].lpvInBuffer
	mov	eax, [eax]
internal_unhookservice:
	; locate hook structure
	lea	edx, [HookUsed]
	mov	edi, [edx]
	mov	IoctlError, VXDMHLP_ERROR_NOTFOUND
unhooksearch:
	cmp	edi, 0
	je	ioctl_failure
	cmp	[edi].SS_Ordinal, eax
	je	unhookfound
	lea	edx, [edi].SS_Next
	mov	edi, [edx]
	jmp	unhooksearch
unhookfound:
	; unhook service
	mov	IoctlError, VXDMHLP_ERROR_UNHOOK
	push	esi
	lea	esi, [edi +(offset32 HookTemplateProc - offset32 HookTemplate)]
	VMMCall Unhook_Device_Service
	pop	esi
	jc	ioctl_failure
	; remove from list of used hook structures
	mov	eax, [edi].SS_Next
	mov	[edx], eax
	; add to list of free hook structures
	mov	eax, [HookFree]
	mov	[edi].SS_Next, eax
	mov	[HookFree], edi
	jmp	ioctl_success

; -------------------------------------------------------------------------
; Compute monitoring overhead
; -------------------------------------------------------------------------
ioctl_getoverhead:
	push	esi
	; save current time
rdts3:	myRDTSC				; edx:eax = rdtsc
	push	eax
	; call Get_VMM_Version 128 times
	mov	esi, 128
unhooked_time_loop:
	VxDCall	Get_VMM_Version
	dec	esi
	jnz	unhooked_time_loop
	; save current time
rdts4:	myRDTSC				; edx:eax = rdtsc
	push	eax
	; hook Get_VMM_Version.  This should always be possible.
	GetVxDServiceOrdinal eax, Get_VMM_Version
	call	internal_hookservice
	jc	ioctl_failure
	; call it 128 times
	mov	esi, 128
hooked_time_loop:
	VxDCall	Get_VMM_Version
	dec	esi
	jnz	hooked_time_loop
	; get the time we've recorded
	lea	edx, [HookUsed]
	mov	edi, [edx]
ovrsearch:
	cmp	[edi].SS_Ordinal, 10000h
	je	ovrfound
	lea	edx, [edi].SS_Next
	mov	edi, [edx]
	jmp	ovrsearch
ovrfound:	
	pushd	0
	mov	eax, [edi].SS_TimeLo
	push	eax
	; unhook it
	GetVxDServiceOrdinal eax, Get_VMM_Version
	call	internal_unhookservice
	; now compute the time difference, overhead = (t4-t3)-(t2-t1)
	mov	eax, [esp]
	sub	eax, [esp+4]
	sub	eax, [esp+8]
	add	eax, [esp+12]
	add	esp, 4*4
	; eax now contains the overhead for 128 calls
	shr	eax, 7
	; save overhead per call
	pop	esi
	mov	edx, [esi].lpvOutBuffer	
	mov	[edx], eax
	; set size of output buffer
	mov	edx, [esi].lpcbBytesReturned	; get output size pointer
	mov	eax, 4
	mov	[edx], eax
	jmp	ioctl_success

ioctl_success:
	xor	eax, eax			; return zero = success
	clc
	ret

ioctl_failure:
	mov	eax, IoctlError
	stc
	ret

EndProc	VXDMHLP_ioctl


;============================================================================
;
; VXDMHLP_Device_Exit - Cleans up any hooks that are still installed before
;		    exiting.
;
;============================================================================

Public VXDMHLP_Device_Exit
BeginProc VXDMHLP_Device_Exit

	; clear error condition
	mov	FixRetErr, 0

	; iterate until no more services are hooked
unhookall_loop:
	mov	edi, [HookUsed]
	; check for end of list
	cmp	edi, 0
	je	unhookall_done
	; unhook the service
	mov	eax, [edi].SS_Ordinal
	call	internal_unhookservice
	jnc	unhookall_loop
	cmp	IoctlError, VXDMHLP_ERROR_UNHOOK
	jne	unhookdel
	; major error - can't unload
	mov	FixRetErr, 1

unhookdel:
	; It wasn't found on the list.  Just delete it and move on.
	mov	eax, [HookUsed]
	mov	eax, [edi].SS_Next
	mov	[HookUsed], eax
	jmp	unhookall_loop
unhookall_done:

	; Locate all VxD calls that haven't yet returned, and change their
	; stack so they return to their original callers instead of MonExit.
	lea	edi, ReturnTable
	mov	ecx, MaxReturn
fixret_loop:
	; iterate over return structures
	mov	eax, [edi].RetTemplateSP	; fetch stack pointer
	or	eax, eax			; check if in use
	jz	fixret_continue
	; ensure stack is still in use (heuristic approach)
	shr	eax, 12
	push	ecx
	VMMcall	_PageCheckLinRange, <eax, 1, 0>
	pop	ecx
	or	eax, eax
	jz	fixret_continue
	cli
	mov	eax, [edi].RetTemplateSP	; fetch stack pointer

	; make sure it points at a return template
	mov	edx, [eax]			; get return address
	sub	edx, offset32 ReturnTable
	cmp 	edx, RetTableSize		; within return table?
	jb	fixret_okay
	mov	FixRetErr, 1
	jmp	fixret_continue
	
fixret_okay:
	; patch return address
	mov	edx, [edi].RetTemplateOrigAddr	; fetch original return addr
	mov	[eax], edx			; restore original return addr
fixret_continue:
	sti
	add	edi, RetTemplateLen
	loop	fixret_loop

	; Free the memory we were using if no errors
	stc
	cmp 	FixRetErr, 1			; clears carry???
	je	nofree
	VMMcall	_PageFree, <[HookTable], 0>
	clc
nofree:
	ret

EndProc VXDMHLP_Device_Exit

VXD_LOCKED_CODE_ENDS






;============================================================================
;	   D E V I C E   I N I T I A L I Z A T I O N   C O D E
;============================================================================

VXD_ICODE_SEG

;============================================================================
;									
; VXDMHLP_Device_Init - VXDMHLP Initialization 	
;									
;									
; Entry: ebx -> System VM handle (not used)
;        edx -> Reference data from real mode init portion
;
; Exit: If successful then
;           Carry flag is clear
;       else
;           Carry flag is set to indicate an error -- Device not initialized
;
;============================================================================

VXDMHLPCaption	db	"VxD Monitor",0
VXDMHLPMessage	db	"                                 Loading...",0

BeginProc VXDMHLP_Device_Init

if 0
	; Put up message box indicating we're loading
	VMMcall	Get_Cur_VM_Handle
	mov	eax, MB_OK
	mov	ecx, OFFSET32 VXDMHLPMessage
	mov	edi, OFFSET32 VXDMHLPCaption
	VxDcall	SHELL_SYSMODAL_Message
	int	3
endif
	; determine if we have cpuid instruction
	cli				; disable interrupts
	pushfd				; push flags
	pop	eax			; pop flags
	mov	edx, eax		; save original flags
	xor	eax, 200000h		; toggle bit 21
	push	eax			; push toggled flags
	popfd				; load toggled flags
	pushfd				; push toggled flags
	pop	eax			; pop toggled flags
	push	edx			; push orig flags
	popfd				; restore orig flags
	sti				; enable interrupts
	cmp	eax, edx		; did bit 21 change
	je	nonpentium		; can't change means no cpuid instr
	; we have cpuid
	mov	eax, 1			; request family id
	db	0Fh, 0A2h		; CPUID
	cmp	eax, 500h		; test for pentium family
	jae	pentium			; if so, we're OK
	; otherwise blot out the rdtsc instructions


	; have to zero all rdtsc instructions
nonpentium:
	mov	eax, 0C033D233h		; xor eax, eax	; xor edx, edx
	mov	dword ptr rdts1, eax
	mov	dword ptr rdts2, eax
	mov	dword ptr rdts3, eax
	mov	dword ptr rdts4, eax

pentium:
	; Initialize
	call	InitHookTable
	call	InitReturnTable

	; Ready to go
	clc
	ret
EndProc VXDMHLP_Device_Init

VXD_ICODE_ENDS

end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -