Wednesday, October 5, 2011

Learn and study Rootkit Specials 3: kernel hook - object hook(2)

;************************************************************************
; Take out resource imformation on third stage resource, if succeed, Return to take out resource length
;************************************************************************

SearchResourceByIDInThirdLayer proc  PEHeader:dword,ResourceAddr:dword,ChildResource:dword,pOutValue:dword
  LOCAL RetValue:dword 
  pusha
  xor  eax, eax
  mov  RetValue, eax
  mov  esi, ChildResource
  mov  cx, [esi+0Ch];Be named after entry count
  add  cx, [esi+0Eh];Entry count To ID named
  movzx  ecx, cx
  add  esi, 10h ;esi point back IMAGE_RESOURCE_DIRECTORY_ENTRY
 
  cmp  ecx, 0
  jbe  Quit
  mov  ebx, [esi+4] ;offsetToData directory entry pointer
  and  ebx, 7FFFFFFFh
  add  ebx, ResourceAddr ;ebx point IMAGE_RESOURCE_DATA_ENTRY structure
  mov  eax, [ebx]  ; Take out RVA of resource data, amount to first term of IMAGE_RESOURCE_DATA_ENTRY structure
  add  eax, PEHeader
  mov  ecx, pOutValue ;pOutValue point address of resource data
  mov  [ecx], eax
  mov  ecx, [ebx+4]
  mov  RetValue, ecx ;Return resource data length
 
Quit:
  popa
  mov  eax, RetValue
  retn
SearchResourceByIDInThirdLayer endp



;************************************************************************
; Find resource term for ID named after ChildResID on second stage resource
;************************************************************************
SearchResourceByIDInSecondLayer proc  PEHeader:dword,ResourceAddr:dword,ChildResource:dword,ChildResID:dword,pOutValue:dword
 
  LOCAL RetValue:dword
  pusha
  xor  eax, eax
  mov  RetValue, eax
  mov  esi, ChildResource
  mov  cx, [esi+0Ch] ;Be named after entry count
  add  cx, [esi+0Eh] ;Entry count To ID named
  movzx  ecx, cx
  add  esi, 10h      ;esi point back IMAGE_RESOURCE_DIRECTORY_ENTRY
  jmp  StartSearchChildDirectoryEntry
 
ContinueSearchChildDirectoryEntry:
  push  ecx
  mov  ebx, [esi+4] ;offsetToData directory entry pointer
  test  ebx, 80000000h
  jz  JumpOver ;; If highest 31bit is zero, Skip to continue next directory entry.
  and  ebx, 7FFFFFFFh
  add  ebx, ResourceAddr ;Otherwise take out next address
  mov  edx, [esi] ;Take out string pointer or ID of directory entry
  test  edx, 80000000h
  jnz  JumpOver  ;If highest 31bit is 1,[esi] oow order represent string pointer
  cmp  edx, ChildResID
  jnz  JumpOver
  push  pOutValue
  push  ebx
  push  ResourceAddr
  push  PEHeader
  call  SearchResourceByIDInThirdLayer
  mov  RetValue, eax
  or  eax, eax
  jz  JumpOver
  pop  ecx
  jmp  Quit
 
JumpOver:
  add  esi, 8
  pop  ecx
  dec  ecx
 
StartSearchChildDirectoryEntry:
  cmp  ecx, 0
  ja  ContinueSearchChildDirectoryEntry
 
Quit:
  popa
  mov  eax, RetValue
  retn
SearchResourceByIDInSecondLayer endp



;******************************************************************************************
; Find resource term for ID named after RESOURCEID on first stage resource
;******************************************************************************************

SearchResourceByIDInFirstLayer proc  PEHeader:dword,ChildResID:dword,RESOURCEID:dword,pOutValue:dword
    LOCAL retvalue:dword
  LOCAL ResourceAddr:dword
 
  pusha
  xor  eax, eax
  mov  retvalue, eax
  mov  edi, PEHeader
  mov  edi, [edi+3Ch]
  add  edi, PEHeader
  mov  ecx, [edi+8Ch] ;Resource table size
  or  ecx, ecx
  jz  QUIT
  mov  eax, [edi+88h] ;Resource table RVA
  add  eax, PEHeader
  mov  ResourceAddr, eax
  push  eax    ; VirtualAddress
  call  MmIsAddressValid
  or  eax, eax
  jnz  @F
  jmp  QUIT
 
@@:
  mov  esi, ResourceAddr
  mov  cx, [esi+0Ch];Be named after entry count
  add  cx, [esi+0Eh];Entry count To ID named
  movzx  ecx, cx
  add  esi, 10h     ;esi point back IMAGE_RESOURCE_DIRECTORY_ENTRY
  jmp  StartSearchDirectoryEntry
 
ContinueSearchDirectoryEntry:
  push  ecx
  mov  ebx, [esi+4]  ;offsetToData directory entry pointer
  test  ebx, 80000000h
  jz  JumpOver ; If highest 31bit is zero, Skip to continue next directory entry.
  and  ebx, 7FFFFFFFh
  add  ebx, ResourceAddr ;Save next address
  mov  eax, [esi];Take directory string pointer or ID
  test  eax, 80000000h
  jnz   JumpOver ;If highest 31bit is 1,[esi] oow order represent string pointer
  cmp  eax, RESOURCEID
  jnz  JumpOver
  push  pOutValue ;Find matched resource ID
  push  ChildResID
  push  ebx
  push  ResourceAddr
  push  PEHeader
  call  SearchResourceByIDInSecondLayer
  mov  retvalue, eax
  pop  ecx
  jmp  QUIT
 
JumpOver:
  add  esi, 8 ;Continue read next directory entry
  pop  ecx
  dec  ecx
 
StartSearchDirectoryEntry:
  cmp  ecx, 0 ;Judge directory entry whether ergodic finish
  ja  ContinueSearchDirectoryEntry
 
QUIT:
  popa
  mov  eax, retvalue
  retn
SearchResourceByIDInFirstLayer endp



; ************************************************************************
;  Get memory load place of current driver file, if can't find, Return zero
;*************************************************************************

GetPeHeader proc  near

  LOCAL PEStart:dword
  pusha
  mov  PEStart, 0
 
CURRENT_EIP:
  lea  ebx, CURRENT_EIP
  and  ebx, 0FFFFFC00h ; Low bit zero clearing
 
CHECKPEHEADER:    ; VirtualAddress
  push  ebx
  call  MmIsAddressValid  ;Judge current address whether valid
  or  eax, eax             
  jz  QUIT           ;unsuccess is jumped to exit
  cmp  ebx, 80000000h ;If current eip less than or equal to 80000000h, exit
  jbe  QUIT
  cmp  word ptr [ebx],  5A4Dh ; 'MZ'
  jnz  SEARCHDOSHEADER
  mov  edi, ebx
  add  edi, [ebx+3Ch]
  push  edi    ; VirtualAddress
  call  MmIsAddressValid
  or  eax, eax
  jz  SEARCHPEHEADER
  cmp  word ptr [edi],  4550h ;'PE'
  jnz  SEARCHPEHEADER
  mov  PEStart, ebx
  jmp  QUIT
 
SEARCHPEHEADER:
  sub  ebx, 400h
  jmp  CHECKPEHEADER
  jmp  QUIT
 
SEARCHDOSHEADER:
  sub  ebx, 400h
  jmp  CHECKPEHEADER
 
QUIT:
  popa
  mov  eax, PEStart
  retn
GetPeHeader endp



No comments:

Post a Comment