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

📄 settimer.asm

📁 使用98 DDK 编写虚拟设备驱动程序
💻 ASM
字号:
.386p
     .xlist
     include vmm.inc
     include shell.inc;利用外壳进行消息输出使用(类似于MessageBox)
     include VKD.Inc;键盘服务过程
     include Debug.inc;调试信息输出
     include vwin32.inc
.list
;============================================================================
;                         常量定义
;============================================================================
SETTIMERName              EQU     <'SETTIMER VXD    '> ;必须为16个字符串
SETTIMERRev               EQU     00H
SETTIMER_MAJOR_VERSION    EQU     1
SETTIMER_MINOR_VERSION    EQU     0
ErrorCode               EQU 0FFFFFFFFh
;============================================================================
; 公有数据---在vxd运行期间始终有效
;============================================================================
VXD_LOCKED_DATA_SEG
FLAGS   dd 0
SYS_VM  dd 0
LDT     dd 0
; Ctrl +加速、Ctrl -减速、Ctrl *超速、Ctrl /刹车、Ctrl 0恢复
; + - *键均为小键盘区按键 / 为键盘区按键
hHotKey_0 dd ?
hHotKey_Multiply dd ?
hHotKey_Add dd ?
hHotKey_Devide dd ?
hHotKey_Subtract dd ?
VK_NUMPAD0      equ      52H ;NumBoard 0
VK_MULTIPLY     equ      37h ;NumBoard *
VK_ADD          equ      4eh ;NumBoard +
VK_SUBTRACT     equ      4ah ;NumBoard -
VK_DIVIDE       equ      35h ;Main KeyBoard / 因为不知道小键盘区的/扫描码
refdata_NUMPAD0 dw 1770h;默认值
;==============================================================
;下面的值可以根据需要修改
;==============================================================
refdata_Add dw 019bh ;稍快
refdata_Subtract dw 4a7eh;稍慢
refdata_Multiply dw 0046h;更快
refdata_Divide dw 0d9c6h;更慢
DOS_INT EQU 21h
ORIG_PM_INT_SEL dd ? ;保护模式原来的中断的选择符和偏移量
ORIG_PM_INT_OFF dd ?
VXD_LOCKED_DATA_ENDS
;============================================================================
; 公有代码段---在vxd运行期间始终有效
;============================================================================
VXD_LOCKED_CODE_SEG
DECLARE_VIRTUAL_DEVICE SETTIMER,SETTIMER_MAJOR_VERSION,SETTIMER_MINOR_VERSION,\
        SETTIMER_Control, ,UNDEFINED_INIT_ORDER
;========================================================================
;入口:eax控制调用标识
;出口:成功清carry
;否则置carry
;========================================================================
public SETTIMER_Control
SETTIMER_Control PROC NEAR
        Control_Dispatch DEVICE_INIT,                   SETTIMER_Device_Init
        Control_Dispatch SYS_DYNAMIC_DEVICE_INIT,       SETTIMER_Device_Init
        Control_Dispatch SYS_DYNAMIC_DEVICE_EXIT,       SETTIMER_Device_Exit
        Control_Dispatch W32_DEVICEIOCONTROL,           SETTIMER_ioctl
	Clc ;不能忘记这两行
        Ret ;
SETTIMER_Control ENDP
;============================================================================
; Win32 DeviceIoControl 接口
; 入口:esi 只想一个DIOCPARAMETERS结构
;出口:成功时,EAX 为零,清Carry 标志
;     失败时,EAX 为错误码,置Carry 标志
;仅提供一个框架
;============================================================================
Public SETTIMER_ioctl
BeginProc SETTIMER_ioctl
		mov	ecx,[esi].dwIoControlCode	; 获得IO控制码
        cmp     ecx,1
        je      Function1
        cmp     ecx,2
        je      Function2
        jmp     RetSuccess
Function1: ;接口1
     jmp     RetSuccess
Function2: ;接口2
         jmp     RetSuccess 
RetSuccess:
        xor     eax, eax     ;返回0成功
	clc
		ret
RetFail:mov     eax,ErrorCode
        stc
        ret
EndProc SETTIMER_ioctl
;========================================================================
;Ctrl+ 0热键处理程序
; 入口:
;AL   : 键的扫描码
; AH  : 0 热键按下
      ; 1 热键释放
      ; 2 热键重复
      ; 3 热键完成
;EBX    热键句柄
;ECX    全局shift 状态
;EDX    指向参考数据
;EDI    以毫秒为单位指示延迟通知时间
;回调函数可以修改寄存器值及标志寄存器
;========================================================================
;SendData 过程 入口 bx=输入数据
;================================================================
SendData macro
mov al,34h;请参考有关微机原理书籍
out 43h,al
mov ax,bx
out 40h,al
mov al,ah
out 40h,al
ret
    EndM
BeginProc HotKeyProc_NUMPAD0
mov bx,word ptr refdata_NUMPAD0;
SendData
VMMCall Get_Cur_VM_Handle;获得当前的虚拟机句柄
mov     eax, hHotKey_0 ;把热键反映给指定的虚拟机,取消热键状态
VxDCall VKD_Reflect_Hot_Key
ret
EndProc HotKeyProc_NUMPAD0
BeginProc HotKeyProc_Add;Ctrl + 热键处理程序
mov bx,word ptr refdata_Add;[edx]
SendData 
VMMCall Get_Cur_VM_Handle
mov     eax, hHotKey_Add
VxDCall VKD_Reflect_Hot_Key
ret
EndProc HotKeyProc_Add
BeginProc HotKeyProc_Subtract;Ctrl -热键处理程序
mov bx,word ptr refdata_Subtract;[edx]
SendData
VMMCall Get_Cur_VM_Handle
mov     eax, hHotKey_Subtract
VxDCall VKD_Reflect_Hot_Key
ret
EndProc HotKeyProc_Subtract
BeginProc HotKeyProc_Multiply
mov bx,word ptr refdata_Multiply;[edx]
SendData
VMMCall Get_Cur_VM_Handle
mov     eax, hHotKey_Multiply
VxDCall VKD_Reflect_Hot_Key
ret
EndProc HotKeyProc_Multiply
BeginProc HotKeyProc_Divide
mov bx,word ptr refdata_Divide ;[edx]
SendData
VMMCall Get_Cur_VM_Handle
mov     eax, hHotKey_Devide
VxDCall VKD_Reflect_Hot_Key
ret
EndProc HotKeyProc_Divide
;=====================================================================
;v86 模式的 21h中断处理程序
;入口:eax 为中断号码
;	  ebx 为当前虚拟机句柄
;      ebp 指向Client_Reg_Struc结构
;出口:置carry 标志传递中断到下一个钩子过程
;如果钩子过程服务了这个中断,它必须清除carry 标志防止系统把中断;递到下一个钩子过程,
;不管系统安装了几个虚拟设备,系统总是最先调用最后一个钩子过程。一个钩子过程要么服务
;这个中断,要么把控制直接传递给下一个钩子过程。如果这个中断没有安装任何钩子过程,系
;统就会把这个中断反映给虚拟机
;=====================================================================
BeginProc Our_Int_Handler
       pushad
        mov     eax,[ebp.Client_EAX]
        cmp     ax,2A00h                ;获得时间功能调用
        jne     Let_DOS_Work            ;非,转下一个钩子过程 
        xor     eax,eax
        mov     FLAGS,eax
        VxDCall VWIN32_GetCurrentProcessHandle;获得当前进程句柄
        mov     eax,[eax+38h]
        or      al,7
        mov     LDT,eax    
        VmmCall Get_Sys_VM_Handle
        mov     SYS_VM,ebx
        VmmCall _SelectorMapFlat <SYS_VM,LDT,FLAGS>
        add     eax,0F2h        ;eax 指向调用进程的名字首字母大写,其余小写
        mov     ebx,[eax]
        cmp     ebx,'dnuR'      ;Rundll32TD 系统调用 
        je     Let_DOS_Work
        cmp     ebx,'lpxE'      ;ExplorerTD系统调用
        je     Let_DOS_Work
        cmp     ebx,'zniW'      ;Winzip 无法实现
        je     Let_DOS_Work
        ;mov ecx,eax;           下面的注释代码主要说明如何输出信息,以便调试
        ;mov ecx, OFFSET32 MessageOk   ; 窗口消息文本
       ; mov edi,eax
        ;mov edi, OFFSET32 Caption   ; 窗口标题
       ; mov esi, 0      ; 回调地址
       ; mov edx, 0      ; 回调参考数据指针
      ;  mov eax, 0      ; 消息框标志, MB_OK
       ; mov ebx,SYS_VM  ;虚拟机句柄
       ; VxDcall SHELL_Message
        popad			;返回虚假日期均为BCD码
        mov     [ebp.Client_AX],1      ;星期
        mov     [ebp.Client_CX],1999   ;年
        mov     [ebp.Client_DX],0101h  ;日 月
        clc			;不再传递中断到下一个钩子过程
        ret
Let_DOS_Work:
        popad
        stc   ; 传递中断到下一个钩子过程
        ret
EndProc Our_Int_Handler
;=====================================================================
;保护模式的 21h中断处理程序
;入口:eax 为中断号码
;	  ebx 为当前虚拟机句柄
;      ebp 指向Client_Reg_Struc结构
;出口: 
;如果钩子过程服务了这个中断,它必须模拟中断
; 否则它必须把控制跳转到原来的中断
;=====================================================================
BeginProc Our_PM_Int_Handler
       pushad
       mov     eax,[ebp.Client_EAX]
       cmp     ax,2A00h                 ;获得时间功能调用
       jne     Let_PM_Work
       xor     eax,eax
       mov     FLAGS,eax
       VxDCall VWIN32_GetCurrentProcessHandle
        mov     eax,[eax+38h]
        or      al,7
        mov     LDT,eax    
        VmmCall Get_Sys_VM_Handle
        mov     SYS_VM,ebx
        VmmCall _SelectorMapFlat <SYS_VM,LDT,FLAGS>
        add     eax,0F2h        
        mov     ebx,[eax]
        cmp     ebx,'dnuR'      
        je     Let_PM_Work
        cmp     ebx,'lpxE'      
        je     Let_PM_Work
        cmp     ebx,'zniW'       
   je     Let_PM_Work
        popad
        mov     [ebp.Client_AX],1      
        mov     [ebp.Client_CX],1999  
        mov     [ebp.Client_DX],0101h  
        VmmCall Simulate_Iret  ;模拟中断返回
        ret
Let_PM_Work:
        popad
        mov ecx ,[Orig_PM_INT_Sel]
        mov edx ,[Orig_PM_INT_Off]
        Vmmjmp Simulate_Far_Jmp
EndProc Our_PM_Int_Handler
;===============================================================
;恢复原来中断处理程序
;===============================================================
Public SETTIMER_Device_Exit
BeginProc SETTIMER_Device_Exit
mov     eax, hHotKey_0
VxDCall VKD_Remove_Hot_Key
mov     eax, hHotKey_Add
VxDCall VKD_Remove_Hot_Key
mov     eax, hHotKey_Multiply
VxDCall VKD_Remove_Hot_Key
mov     eax, hHotKey_Devide
VxDCall VKD_Remove_Hot_Key
mov     eax, hHotKey_Subtract
VxDCall VKD_Remove_Hot_Key
mov     eax, DOS_INT
mov     esi, OFFSET32 Our_Int_Handler
VMMCall UnHook_V86_Int_Chain
mov Ecx,ORIG_PM_INT_SEL
mov edx,ORIG_PM_INT_OFF
mov eax,DOS_INT
VMMCall Set_PM_Int_Vector
Clc;置成功标志
ret
EndProc SETTIMER_Device_Exit
VXD_LOCKED_CODE_ENDS

;===============================================================
;初始化代码段,初始化完毕,该内存区域被释放
;===============================================================
VXD_ICODE_SEG
BeginProc SETTIMER_Device_Init
mov     eax, DOS_INT;安装v86 模式的21H中断
mov     esi, OFFSET32 Our_Int_Handler
VMMCall Hook_V86_Int_Chain
jnc hook_PM_int
;Debug_out 'Hook_v86_int_chain Failed' ;说明如何输出调试信息
jmp Error_Handler
hook_PM_int:        ;下面说明如何挂接保护模式中断
mov EAX,DOS_INT     ;中断号  
VMMCall Get_PM_Int_Vector;获得保护模式中断向量
mov [Orig_PM_Int_Sel],ecx
mov [Orig_PM_Int_Off],edx
mov Esi,Offset32 Our_PM_Int_Handler;分配保护模式的回调,es指向保护模式的中断程序
VMMCall Allocate_PM_Call_Back ;EDX指向参考数据
jnc Alloc_Ok
;Debug_Out 'Allocate_PM_Call_Back Failed'
jmp Error_Handler
Alloc_Ok:
     Mov Ecx,Eax ;eax为返回的sel :offset
     Movzx edx,cx ;dx: offset
shr ecx,16   ;cx: selector
mov eax,DOS_INT
VMMCall Set_PM_Int_Vector ;设置保护模式中断向量
mov     al, VK_NUMPAD0 ;键的扫描码
mov     ah, 0          ;类型为正常模式
mov     ebx, HKss_Ctrl ;CTRL键
mov     cl, CallOnPress ;检测到按下时执行回调
mov     esi, OFFSET32 HotKeyProc_NUMPAD0;热键处理回调函数地址
mov     edx, OFFSET32 refdata_NUMPAD0 ;参考数据
mov     edi, 0 ;以毫秒为单位最大通知延迟时间, 为零按键总被通知
VxDCall VKD_Define_Hot_Key
jnc      Next_1
jmp Error_Handler
Next_1:
mov hHotKey_0,eax
mov     al,VK_ADD
mov     ah, 00
mov     ebx, HKss_Ctrl 
mov     cl, CallOnPress 
mov     esi, OFFSET32 HotKeyProc_ADD
mov     edx, OFFSET32 refdata_ADD
mov     edi, 0
VxDCall VKD_Define_Hot_Key
jnc      Next_2
jmp Error_Handler
Next_2:
mov hHotKey_Add,eax
mov     al,VK_SUBTRACT
mov     ah, 00
mov     ebx, HKss_Ctrl 
mov     cl, CallOnPress 
mov     esi, OFFSET32 HotKeyProc_SUBTRACT
mov     edx, OFFSET32 refdata_SUBTRACT
mov     edi, 0
VxDCall VKD_Define_Hot_Key
jnc      Next_3
jmp Error_Handler
Next_3:
mov hHotKey_Subtract,eax
mov     al,VK_MULTIPLY
mov     ah, 00
mov     ebx, HKss_Ctrl 
mov     cl, CallOnPress 
mov     esi, OFFSET32 HotKeyProc_MULTIPLY
mov     edx, OFFSET32 refdata_MULTIPLY
mov     edi, 0
VxDCall VKD_Define_Hot_Key
jnc      Next_4
jmp Error_Handler
Next_4:
mov hHotKey_Multiply,eax
mov     al, VK_DIVIDE
mov     ah, 00
mov     ebx, HKss_Ctrl 
mov     cl, CallOnPress
mov     esi, OFFSET32 HotKeyProc_DIVIDE
mov     edx, OFFSET32 refdata_Divide
mov     edi, 0
VxDCall VKD_Define_Hot_Key
jnc      Next_OK
jmp Error_Handler
Next_OK:
mov hHotKey_Devide,eax
VMMCall Get_Cur_VM_Handle
Clc; 成功清Carry标志
ret
Error_Handler:
VMMCall Get_Cur_VM_Handle
         stc  ;失败置标志
         ret
EndProc SETTIMER_Device_Init
VXD_ICODE_ENDS
end

⌨️ 快捷键说明

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