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

📄 vxdmon.asm

📁 VxDMon_系统驱动监视器,对感兴趣的人会有帮助的。
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;****************************************************************************
;                                                                           *
; VXDMHLP								    *
;								  	    *
; Copyright (c) 1996 Bryce Cogswell and Mark Russinovich		    *
; All rights reserved                                                       *
;									    *
;****************************************************************************
;									    *
; VXDMHLP: Monitors entry and exit of VxDs.				    *
;                                                                           *
;****************************************************************************

;===========================================================================
	page	,132
	title	VXDMHLP - VXDMHLP VxD
	name	VXDMHLP.vxd
;===========================================================================
;
;   Module:
;	Contains everything
;
;===========================================================================
;
;   Functional Description: - 
;
;
;			
;============================================================================

;============================================================================
;				I N C L U D E S
;============================================================================
.386p
	.xlist
	include	vmm.inc
	include vwin32.inc
	include debug.inc
	; for message box
	include shell.inc
	; for testing
	include vcache.inc
.list

	include VXDMON.inc

;============================================================================
;	 	   		MACROS
;============================================================================

;============================================================================
; 			  P U B L I C   D A T A
;============================================================================

VXD_LOCKED_DATA_SEG

; flags for stats operations
UPDATESTATS	EQU		1
ZEROSTATS	EQU		2
UPDATEZEROSTATS	EQU		3


myRDTSC	MACRO
	db	0Fh, 31h	; rdtsc
	nop			; pad to 4 bytes long
	nop			; pad to 4 bytes long
	ENDM

; -------------------------------------------------------------------------
; Jump table for commands initiated by Devmon Windows program
; -------------------------------------------------------------------------
Service_Table	label	dword
	dd	offset32	ioctl_closehandle
	dd	offset32	ioctl_getversion
	dd	offset32	ioctl_getstats
	dd	offset32	ioctl_getzerostats
	dd	offset32	ioctl_zerostats
	dd	offset32	ioctl_hookservice
	dd	offset32	ioctl_unhookservice
	dd	offset32	ioctl_getoverhead
Service_Table_Size	EQU	($ - Service_Table) / 4


; -------------------------------------------------------------------------
; This points to the most recently called service.
; -------------------------------------------------------------------------
; max call stack depth
MRUMaxStack		EQU	32
; max amount by which we expect stack to grow during VxD calls
MRUMaxLocalStack	EQU	512

; size of this structure must be power of 2
MRUService	STRUC
MRU_Ordinal	DD	?
MRU_SP		DD	?
MRUService	ENDS

; call stack
MRUStack	MRUService	 MRUMaxStack dup (<?>)
; current call stack pointer
MRUStackPtr	DD	0

; indicates if error on exit
FixRetErr	DD	0

; -------------------------------------------------------------------------
; Use this to track error conditions
; -------------------------------------------------------------------------
IoctlError	DD	0



; -------------------------------------------------------------------------
; This template defines the structure we allocate for each hooked service.
; It is customized for a particular service upon creation.
;
; We provide labels for all relocatable addresses so that we can adjust
; them when the template is instantiated.
; -------------------------------------------------------------------------

HookTemplate:
	ServiceStats	<0,0,0,0,0,0,0>
HookTemplatePrevHooker	dd	?
HookTemplatePrevPtr	EQU offset32 $ + 4 - offset32 HookTemplate
BeginProc HookTemplateProc, Hook_Proc HookTemplatePrevHooker
	call	MonEnter
HookTemplateMonEnter	EQU offset32 $ - offset32 HookTemplate - 4
	jmp	[HookTemplatePrevHooker]
HookTemplatePrevHookerJmp EQU offset32 $ - offset32 HookTemplate - 4
EndProc HookTemplateProc
	align	4
HookTemplateEnd:

HookTemplateLen	EQU	(offset32 HookTemplateEnd - offset32 HookTemplate)
MaxHooks	EQU	2000
MaxPages	EQU	((HookTemplateLen * MaxHooks + 4095) / 4096)
HookTable	dd	0
HookFree	dd	0
HookUsed	dd	0


; -------------------------------------------------------------------------
; This template defines the structure we allocate to capture when a service
; returns.  It is customized for a particular service at the time the
; service is invoked.
; -------------------------------------------------------------------------
RetTemplate:
	call	MonExit
RetTemplateHooker EQU	(offset32 $ - offset32 RetTemplate)
	dd	0	; pointer to hooker structure
RetTemplateOrigAddr  EQU  (offset32 $ - offset32 RetTemplate)
	dd	0	; original return address
RetTemplateSP	EQU	(offset32 $ - offset32 RetTemplate)
	dd	0	; pointer to return address on stack
RetTemplateTime EQU	(offset32 $ - offset32 RetTemplate)
	dd	0
	dd	0
RetTemplateEnd:

MaxReturn	EQU	400
RetTemplateLen	EQU	(offset32 RetTemplateEnd - offset32 RetTemplate)
RetTableSize	EQU	(MaxReturn * RetTemplateLen)

ReturnTable	db	(MaxReturn * RetTemplateLen) dup (?)
ReturnFree	dd	offset32 ReturnTable



VXD_LOCKED_DATA_ENDS


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

VXD_LOCKED_CODE_SEG

DECLARE_VIRTUAL_DEVICE VXDMHLP,	\
	VXDMHLP_MAJOR_VERSION, 	\
	VXDMHLP_MINOR_VERSION,	\
	VXDMHLP_Control, ,	\
	UNDEFINED_INIT_ORDER


;============================================================================
;			    M A I N   C O D E
;============================================================================


; -------------------------------------------------------------------------
; Called each time a service is invoked.
; -------------------------------------------------------------------------
BeginProc MonEnter
	pushfd

	; disable interrupts so our timing computations aren't corrupted
	cli

	push	esi
	push	edi
	push	eax
	push	edx

	; get pointer to hook structure
	mov	esi, [esp+20]		; get return address
	sub	esi, HookTemplateMonEnter + 4

	; increment entry count
	inc	[esi].SS_Enter

	; allocate a return structure to replace original return with
	mov	eax, [ReturnFree]	; get location of return function
	mov	edi, [eax].RetTemplateHooker	; get location of next on list
	mov	[ReturnFree], edi	; update pointer to first on list

	; change return address to point to us, fetch original return address
	mov	edi, eax		; copy pointer to return structure
	xchg	[esp+24], eax		; store new return address, fetch old

	; save original return address
	mov	[edi].RetTemplateOrigAddr, eax

	; store service hooker address
	mov	[edi].RetTemplateHooker, esi

	; save address of return address on stack
	lea	eax, [esp+24]
	mov	[edi].RetTemplateSP, eax

	; do stuff for recording callers/callees
	call	MRUEnter

	; update time spent in function (do as late as possible)
rdts1:	myRDTSC					; edx:eax = rdtsc
	mov	[edi].RetTemplateTime, eax	; store time low
	mov	[edi].RetTemplateTime+4, edx	; store time high

	pop	edx
	pop	eax
	pop	edi
	pop	esi
	popfd
	ret
EndProc	MonEnter



; -------------------------------------------------------------------------
; Called each time a service returns from invocation.
; -------------------------------------------------------------------------
BeginProc MonExit
	pushfd
	push	esi
	push	edi
	push	eax
	push	edx

	; disable interrupts so our timing computations aren't corrupted
	cli

	; get pointer to original structure
	mov	edi, [esp+20]			; return address
	sub	edi, RetTemplateHooker		; point to front of return template
	mov	esi, [edi].RetTemplateHooker	; get hooker structure pointer

	; update time spent in function (do as early as possible)
rdts2:	myRDTSC					; edx:eax = rdtsc
	sub	eax, [edi].RetTemplateTime
	sbb	edx, [edi].RetTemplateTime+4
	add	[esi].SS_TimeLo, eax		; add time low
	adc	[esi].SS_TimeHi, edx		; add time high

	; replace our return address with original
	mov	edx, [edi].RetTemplateOrigAddr
	mov	[esp+20], edx			; replace return address

	; increment exit count
	inc	[esi].SS_Exit

	; make return address structure available to someone else
	xor	edx, edx
	mov	[edi].RetTemplateSP, edx	; mark as unused
	mov	edx, [ReturnFree]		; get base list pointer
	mov	[edi].RetTemplateHooker, edx	; set link pointer to base

	; now finalize freeing the structure
	mov	[ReturnFree], edi		; set base list pointer to ours

	; do stuff for recording callers/callees
	call	MRUExit

	pop	edx
	pop	eax
	pop	edi
	pop	esi
	popfd
	ret
EndProc	MonExit



BeginProc	MRUEnter
	; if stack is currently empty, only put us on it
	mov	eax, MRUStackPtr
	or	eax, eax
	jz	mru_enter_reset

	; ensure we're using same stack as MRU
	; check if esp is larger than last
	add	eax, offset32 MRUStack - size MRUService
	mov	edx, [eax].MRU_SP
	sub	edx, esp
	je	mru_enter_reset
	; check if esp is much smaller than last
	cmp	edx, MRUMaxLocalStack
	jg	mru_enter_reset

	; indicate that we were called by MRU service
	mov	edx, [esi].SS_CallerPtr		; get position to save caller
	push	[eax].MRU_Ordinal		; get last called service
	pop	[esi+edx*4].SS_Caller		; save caller
	inc	edx
	and	edx, CALLER_CNT-1
	mov	[esi].SS_CallerPtr, edx		; update caller pointer

	; update MRU call stack
	mov	edx, [esi].SS_Ordinal
	mov	[eax+size MRUService].MRU_Ordinal, edx
	mov	[eax+size MRUService].MRU_SP, esp

	; update stack pointer location
	sub	eax, offset32 MRUStack - 2 * size MRUService
	and	eax, (MRUMaxStack-1) * size MRUService
	mov	MRUStackPtr, eax

	; all done
	ret

mru_enter_reset:
	; reset mru stack to be empty
	mov	eax, size MRUService
	mov	MRUStackPtr, eax
	; make us the only thing on the stack
	mov	edx, [esi].SS_Ordinal
	mov	MRUStack.MRU_Ordinal, edx
	mov	MRUStack.MRU_SP, esp
	; all done
	ret
EndProc	MRUEnter


BeginProc	MRUExit
	; get pointer to top item on call stack
	mov	eax, MRUStackPtr		; eax = last stack entry
	or	eax, eax
	jz	mru_exit_empty			; stack is empty
	; ensure that it is us
	sub	eax, size MRUService		; back down to previous item
	mov	edx, [MRUStack+eax].MRU_Ordinal
	cmp	[esi].SS_Ordinal, edx
	jne	mru_exit_reset			; who knows how we got here?
	; update stack pointer location
	mov	MRUStackPtr, eax
	; all done
	ret
mru_exit_reset:
	xor	eax, eax
	mov	MRUStackPtr, eax
mru_exit_empty:
	; all done
	ret
EndProc	MRUExit



; -------------------------------------------------------------------------
; Initialize the linked list of hooks for hooked services.
; These are created using the HookTemplate.
; -------------------------------------------------------------------------
BeginProc InitHookTable
	; Allocate space for hook functions and statistics.
	; We initialize enough memory to hook tons of services, but
	; lock only the portion we need, allowing most to be paged out.
	VMMcall	_PageAllocate, <MaxPages, PG_SYS, 0, 0, 0, 0, 0, PAGEZEROINIT>
	mov	[HookTable], eax		; save table pointer
	mov	edi, eax
	mov	[HookFree], edi			; set pointer to first
	lea	esi, HookTemplate
	mov	ecx, MaxHooks
	sub	eax, esi
	cld
init_hook_loop:
	mov	edx, ecx
	; Copy template
	mov	ecx, HookTemplateLen
	rep movsb
	sub	esi, HookTemplateLen
	; Fix up relocatable items
	mov	[edi-HookTemplateLen].SS_Next, edi	; set pointer to next
	sub	[edi-HookTemplateLen].HookTemplateMonEnter, eax
	add	[edi-HookTemplateLen].HookTemplatePrevHookerJmp, eax
	add	[edi-HookTemplateLen].HookTemplatePrevPtr, eax

	add	eax, HookTemplateLen
	mov	ecx, edx
	loop	init_hook_loop
	xor	ecx, ecx
	mov	[edi-HookTemplateLen].SS_Next, ecx	; set pointer to next
	ret
EndProc InitHookTable


; -------------------------------------------------------------------------
; Initialize the linked list of return points for invoked functions.
; These are created using the RetTemplate.
; -------------------------------------------------------------------------
BeginProc InitReturnTable
	lea	edi, ReturnTable
	mov	[ReturnFree], edi		; set pointer to first
	lea	esi, RetTemplate
	mov	ecx, MaxReturn
	mov	eax, offset32 ReturnTable - offset32 RetTemplate
	cld
init_return_loop:
	mov	edx, ecx
	mov	ecx, RetTemplateLen
	rep movsb
	sub	esi, RetTemplateLen
	mov	[edi-RetTemplateLen+RetTemplateHooker], edi	; set pointer to next
	sub	[edi-RetTemplateLen+RetTemplateHooker-4], eax	; adjust call address
	add	eax, RetTemplateLen
	mov	ecx, edx
	loop	init_return_loop
	xor	ecx, ecx
	mov	[edi-RetTemplateLen+RetTemplateHooker], ecx	; set pointer to next
	ret
EndProc InitReturnTable



;============================================================================
;
; VXDMHLP_Control - Device control procedure for the VxD. Dispatches all
;                  Windows VxD messages.
;
; Exit:	If carry clear then
;	    Successful
;	else
;	    Control call failed
;
; Destroys: EAX, EBX, ECX, EDX, ESI, EDI, Flags
;
;============================================================================

public VXDMHLP_Control
VXDMHLP_Control PROC NEAR

	Control_Dispatch SYS_DYNAMIC_DEVICE_INIT,	VXDMHLP_Device_Init
	Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT,	VXDMHLP_Device_Exit

⌨️ 快捷键说明

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