发新话题
打印

[转载]动态HOOKAPI函数

[转载]动态HOOKAPI函数

题 目: 动态HOOKAPI函数
类 型: 原创
作 者: Wowocock
来 源: 水色银光
引用:
  众所周知有很多病毒和木马可以无任何提示的情况下直接关闭防火墙,之所以会这样主要是利用的微软提供的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&#39;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 &#39;Kernel32.dll&#39;,0
  aUser32      db &#39;User32.dll&#39;,0
  AddrKernel32    dd ?
  aTerminateProcess db &#39;TerminateProcess&#39;,0
  AddrTerminate   dd ?

  aMessageboxA    db &#39;MessageBoxA&#39;,0
  AddrMessage    dd ?
  aExitProcess    db &#39;ExitProcess&#39;,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&#39;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 &#39;Caution&#39;,0
     Text   db &#39;One of your Process is going to be Terminated,&#39;,0dh,0ah
          db &#39;do you want to continue?&#39;,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

TOP

发新话题