📄 int.asm
字号:
;***************************
;文件:int.asm *
;功能:演示如何在Win9x下改 *
; 变IDT表 *
;***************************
.386p
locals
.model flat,stdcall
include win32.inc
extrn MessageBoxA:proc
extrn ExitProcess:proc
extrn DialogBoxParamA:proc
extrn EndDialog:Proc
extrn GetDlgItemTextA:proc
extrn SetDlgItemTextA:proc
extrn GetModuleHandleA:proc
extrn _wsprintfA:PROC
IDC_TIMES = 100
HookInt = 51H
.data
DialogName db 'MyDialog',0
CaptionFail db '失败!',0
TextFail db 'API:DialogBoxParamA调用失败!',0
Addr dd ?
CallAddr dd 0
dw 07h
Temp dd ?,?
OldIntGate dd ?,?
TIMES db 100 dup ('A'),0
Param db '共接到按键消息%d次。最后的扫描码是:%x。[Hook 地址是%x ]',0
.code
WinMain:
;**********************************
push offset InstallHook ;改变IDT表
call ToRing0Code
mov [Addr],eax
;**********************************
call GetModuleHandleA,0
call DialogBoxParamA,eax,offset DialogName,0,offset DialogProc,0
cmp eax,0
jnz Exit
mov eax,offset TextFail
call MessageBoxA,0,eax,offset CaptionFail,MB_OK
Exit:
;**********************************
push offset UnInstallHook ;把IDT表改回原来的值
call ToRing0Code
call ExitProcess,0
;**********************************
;主窗口消息处理
DialogProc proc uses ebx edi esi, hWnd:DWORD, wMsg:DWORD, wParam:DWORD, lParam:DWORD
cmp wMsg,WM_INITDIALOG
jz WmInitDialog
cmp wMsg,WM_CLOSE
jz WmClose
cmp wMsg,WM_COMMAND
jz WmCommand
jmp ExitProc
WmInitDialog:
call _wsprintfA,offset TIMES,offset Param,0,0,[Addr]
add esp,20
call SetDlgItemTextA,hWnd,IDC_TIMES,offset TIMES
jmp ExitProc
WmClose:
call EndDialog,hWnd,1
jmp ExitProc
WmCommand:
mov ebx,wParam
cmp bx,IDOK ;按了“刷新”按钮?
jnz ExitProc
mov ebx,[Addr]
lea esi,[ebx+Begin-IntProc-8]
lea edi,[ebx+Begin-IntProc-4]
call _wsprintfA,offset TIMES,offset Param,dword ptr[esi],dword ptr[edi],[Addr]
add esp,20
call SetDlgItemTextA,hWnd,IDC_TIMES,offset TIMES
jmp ExitProc
ExitProc:
xor eax,eax
ret
DialogProc endp
;********************************************************************
ToRing0Code:
push ebp
mov ebp,esp
call GetLdtAddress
mov ecx,[eax] ;Save old Descriptor
mov [Temp],ecx
mov ecx,[eax+4]
mov [Temp+4],ecx
mov edx,[ebp+8]
mov [eax],dx
mov word ptr [eax+2],28h
mov word ptr [eax+4],0ec00h
shr edx,16
mov [eax+6],dx
push eax
call fword ptr[CallAddr];call Ring0 program
pop ebx
mov edx,[Temp] ;Load old descriptor
mov [ebx],edx
mov edx,[Temp+4]
mov [ebx+4],edx
pop ebp
ret 4
UnInstallHook:
cli
call GetHookIntAddrInIdt
push eax
mov ebx,[eax+4]
mov bx,[eax]
push 1
push ebx
int 20H
dd 10055H ;VxdCall __PageFree
add esp,2*4
pop eax
mov ebx,OldIntGate
mov [eax],ebx
mov ebx,[OldIntGate+4]
mov [eax+4],ebx
sti
retf
InstallHook:
cli
xor eax,eax
push dword ptr 0fH
push eax
push dword ptr 0ffffffffH
push eax
push eax
push eax
push dword ptr 1
push dword ptr 2
int 20H ;VxDCall _pageAllocate
dd 10053H
add esp,8*4
push eax ;Save New Interrupt Address
mov edi,eax
mov esi,offset IntProc
mov ecx,OldIntRelativeAddress-IntProc
cld
rep movsb
push ebx
sidt [esp-2]
pop ebx
add ebx,HookInt*8
mov eax,[ebx+4]
mov ax,[ebx]
sub eax,edi
sub eax,4
stosd
call GetHookIntAddrInIdt
mov ebx,eax
mov eax,[ebx]
mov OldIntGate,eax
mov eax,[ebx+4]
mov [OldIntGate+4],eax
pop eax ;Load New Interrupt Process address
mov [ebx],ax
ror eax,16
mov [ebx+6],ax
ror eax,16
sti
retf
GetLdtAddress: ;取LDT地址
push ebx
sgdt [esp-2]
pop ebx
sldt ax
and eax,0fff8H
add ebx,eax
mov eax,[ebx+2]
mov dl,[ebx+7]
shl edx,24
and eax,0ffffffh
or eax,edx
ret
GetHookIntAddrInIdt:
push eax
sidt [esp-2]
pop eax
add eax,HookInt*8
ret
IntProc : ;中断处理
pushf
push eax
push ebx
push ds
mov bx,30H
mov ds,bx
call Begin
dd 0
dd 0
Begin:
pop ebx
inc dword ptr[ebx] ;按中断次数加一
in al,60H
mov byte ptr[ebx+4],al ;记下扫描码
pop ds
pop ebx
pop eax
popf
db 0e9H ;跳回原中断处理程序处
OldIntRelativeAddress:
db 4 dup (?)
;************************************************************
end WinMain
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -