众所周知有很多病毒和木马可以无任何提示的情况下直接关闭防火墙,之所以会这样主要是利用的微软提供的API TerminateProcess,而且微软也没有提供PATCH的意思,所以只有靠自己了,自己HOOK ,API,然后当调用时跳出消息框询问是否要终止进程,当然HOOK的方法有很多,我下面的是看了关于研究变速齿轮的文章以后写的先申请2G以上空间,然后将TerminateProcess的前7个字节保存起来,然后修改其,使其指向2G以上空间,然后将驻留代码复制到该处,这样当调用TerminateProcess,时就会调用我的代码,跳出,MESSAGEBOX询问是否退出,NO则置失败标志(EAX=0),直接返回,CANCEL则先恢复原先的内容然后同NO,这样就解除了HOOK。
YES时先恢复原先的内容,然后压入TerminateProcess所需的参数,并压入返回的地址,即从API返回以后到我的代码中,然后再修改API,继续HOOK,并置成功标志(EAX=1)返回。
由于我所驻留的代码并不以任何进程形式存在,所以也不怕自己被TERMINATE掉,呵呵。
代码如下:复制内容到剪贴板
代码:
----------------------------------------------------------
;========================================
; WOWOCOCK 编写 ;
;========================================
.586
.model flat, stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
;-----------------------------------------
ddd MACRO Text
local name
.data
name db Text,0
.code
EXITM <addr name>
ENDM
;define data in .data section
;This and other can be used as: ddd("My god!")
;isn't cool?
;------------------------------------(上面的)--
CTEXT MACRO y:VARARG
LOCAL sym
CONST segment
IFIDNI <y>,<>
sym db 0
else
sym db y,0
endif
CONST ends
EXITM <offset sym>
ENDM
;This is a good macro
;------------------------------------(上面的)--
m2m MACRO M1, M2
push M2
pop M1
ENDM
;mov is too boring sometimes!
;------------------------------------(上面的)--
Call32 macro Selector,Offsetv
db 09ah
dd Offsetv
dw Selector
endm
Arp_Mem equ 1000h
;用到的宏
;------------------------------------(上面的)--
.data
sztit db "Tested by Wowocock",0
aKernel32 db 'Kernel32.dll',0
aUser32 db 'User32.dll',0
AddrKernel32 dd ?
aTerminateProcess db 'TerminateProcess',0
AddrTerminate dd ?
aMessageboxA db 'MessageBoxA',0
AddrMessage dd ?
aExitProcess db 'ExitProcess',0
AddrExitProcess dd ?
lpMappedObject dd ?
;;-----------------------------------------
.code
_Start:
invoke GetModuleHandle,addr aKernel32
mov AddrKernel32,eax
invoke GetProcAddress,eax,addr aTerminateProcess
mov AddrTerminate,eax
detect:
;---------------------------------------------
cmp word ptr[eax+5],90c3h
jz _ErrHooked
;判断是否已经HOOK
;------------------------------------(上面的)--
invoke GetProcAddress,AddrKernel32,addr aExitProcess
mov AddrExitProcess,eax
invoke GetModuleHandle,addr aUser32
invoke GetProcAddress,eax,addr aMessageboxA
mov AddrMessage,eax
;-----------------------------------------------
mov eax,080000000h-Arp_Mem
Try_next:
add eax,Arp_Mem
cmp eax,(-1-Arp_Mem)
jae _ErrCantAlloc
push eax
invoke VirtualAlloc,eax,Arp_Mem,MEM_COMMIT,PAGE_EXECUTE_READWRITE
test eax,eax
xchg eax,ebx
pop eax
je Try_next
mov lpMappedObject, eax
;分配2GB以上地址空间
;------------------------------------(上面的)--
push offset MyProc
call ToRing0Code
;进行地址的拷贝
;------------------------------------(上面的)--
cld
mov edi,lpMappedObject
mov esi,offset Addr0Proc
mov ecx,Addr0ProcLength+1
rep movsb
;将代码复制到申请到的地址空间
;------------------------------------(上面的)--
invoke MessageBox,0,CTEXT("TerminateProcess Probe..."),addr
sztit,MB_ICONWARNING
jmp Exit
_ErrCantAlloc:
invoke MessageBox,0,CTEXT("Can't Alloc Memory!"),CTEXT("ERROR"),0
jmp Exit
_ErrHooked:
invoke MessageBox,0,CTEXT("TerminateProcess is being
hooked!"),CTEXT("ERROR"),MB_ICONWARNING
Exit:
invoke ExitProcess,0
;-----------------------------------------
MyProc proc
push esi
push edi
lea esi,AddrMessage
lea edi,bAddrMessage
movsd
lea esi,AddrTerminate
lea edi,bTerminate
movsd
lea esi,lpMappedObject
lea edi,blpMappedObject
movsd
;----------------------------------------------
mov esi,AddrTerminate
lea edi,OldBytes
xor ecx,ecx
mov cl,7
rep movsb
;保存TerminateProcess 的前7个字节
;------------------------------------(上面的)--
mov eax,AddrTerminate
mov byte ptr[eax],68h
m2m dword ptr[eax+1],lpMappedObject
mov word ptr[eax+5],90c3h
;修改TerminateProcess 的前7个字节使其指向高端代码
;------------------------------------(上面的)--
pop edi
pop esi
retf
MyProc endp
;----------------------------------------------
;执行后驻留的代码
;------------------------------------(下面的)--
Addr0Proc:
push ebx
push esi
push edi
jmp next
align 4
Caution db 'Caution',0
Text db 'One of your Process is going to be Terminated,',0dh,0ah
db 'do you want to continue?',0
bAddrMessage dd ?
bTerminate dd ?
blpMappedObject dd ?
next:
call tmp
tmp:
;-----------------------------------------
pop esi
mov eax,offset tmp-offset Addr0Proc
sub esi,eax
;esi指向Addr0Proc
;------------------------------------(上面的)--
push MB_YESNOCANCEL or MB_ICONWARNING
mov ecx, offset Caution-offset Addr0Proc
add ecx,esi
push ecx
mov ecx, offset Text-offset Addr0Proc
add ecx,esi
push ecx
push dword ptr 0
mov ecx, offset bAddrMessage-offset Addr0Proc
add ecx,esi
call dword ptr[ecx]
;call MESSAGEBOX
;------------------------------------(上面的)--
.if eax==IDNO
pop edi
pop esi
pop ebx
mov eax,0
ret 8
.elseif eax==IDCANCEL
mov ecx,offset Restore-offset Addr0Proc
add ecx,esi
push ecx
mov ecx,offset ToRing0Code-offset Addr0Proc
add ecx,esi
call ecx
pop edi
pop esi
pop ebx
mov eax,0
ret 8
.endif
;直接返回 或 恢复原先内容,返回
;------------------------------------(上面的)--
mov ecx,offset Restore-offset Addr0Proc
add ecx,esi
push ecx
mov ecx,offset ToRing0Code-offset Addr0Proc
add ecx,esi
call ecx
;恢复原先内容
;------------------------------------(上面的)--
mov ecx,dword ptr[esp+5*4]
mov edx,dword ptr[esp+4*4]
push ecx
push edx
;压入传递来的参数
;------------------------------------(上面的)--
mov ecx,offset bTerminate-offset Addr0Proc
add ecx,esi
mov edx,offset Back-offset Addr0Proc
add edx,esi
push edx
push dword ptr[ecx]
ret
;压入返回地址,返回至驻留代码
;执行TermianteProcess
;------------------------------------(上面的)--
OldBytes db 7 dup(90h)
Back:
push eax
mov ecx,offset ReChange-offset Addr0Proc
add ecx,esi
push ecx
mov ecx,offset ToRing0Code-offset Addr0Proc
add ecx,esi
call ecx
pop eax
pop edi
pop esi
pop ebx
ret 8
;从TermianteProcess返回
;恢复对TermianteProcess的HOOK
;返回调用程序中
;------------------------------------(上面的)--
ReChange:
mov ecx,offset bTerminate-offset Addr0Proc
add ecx,esi
mov eax,[ecx]
mov byte ptr[eax],68h
mov ecx,offset blpMappedObject-offset Addr0Proc
add ecx,esi
m2m dword ptr[eax+1],[ecx]
mov word ptr[eax+5],90c3h
retf
Restore:
push esi
push edi
mov edi,offset bTerminate-offset Addr0Proc
add edi,esi
mov edi,dword ptr[edi]
mov ecx,offset OldBytes-offset Addr0Proc
add esi,ecx
mov ecx,7
cld
rep movsb
pop edi
pop esi
retf
;----------------------------------------------
;在LDT中的第0个描述符中生成调用门,进RING0
;------------------------------------(下面的)--
ToRing0Code proc Ring0Proc:dword
local temp1,temp2
push ebx
sgdt [esp-2]
pop ebx ;获得GDT地址
sldt ax
and eax,0fff8h
add ebx,eax
mov eax,[ebx+2]
and eax,0ffffffh
mov dl,[ebx+7]
shl edx,24
or eax,edx ;获得LDT地址
mov ecx,[eax]
mov temp1,ecx
mov ecx,[eax+4]
mov temp2,ecx
mov edx,Ring0Proc ;生成调用门
mov [eax],dx
mov cx,28h
mov [eax+2],cx
mov cx,0ec00h
mov [eax+4],cx
shr edx,16
mov [eax+6],dx
push eax
Call32 7,0 ;进RING0
pop ebx ;恢复LDT中第0个描述符(好象没什么用,保险点恢复吧)
mov edx,temp1
mov [ebx],edx
mov edx,temp2
mov [ebx+4],edx
ret
ToRing0Code endp
Addr0ProcLength =$-Addr0Proc
END _Start