Saturday, October 8, 2011

Learn and study Rootkit Specials 6: kernel hook - SSDT hook(2)

  ; Example: ImageName: windows\system32\ndis.sys, So ModuleNameOffset is 0x11 
  movzx  eax, word ptr [esi+1Ah] ;SYSTEM_MODULE_INFORMATION.ModuleNameOffset ,Point offset of name
  lea  eax, [eax+esi+1Ch]  ;SYSTEM_MODULE_INFORMATION.ImageName + SYSTEM_MODULE_INFORMATION.ModuleNameOffset
  push  eax   ;don't clude path name
  call  _stricmp
  pop  ecx             ;出栈
  pop  ecx
  test  eax, eax
  jnz  ContinueLoop
  mov  eax, [esi+8]    ;return SYSTEM_MODULE_INFORMATION.Base
  mov  [ebp-24h], eax  ;return save on [ebp-24h]
 
ReleaseMemory:
  push  edi
  call  ExFreePool
  jmp      ERRORRET
 
ContinueLoop:
  inc  dword ptr [ebp-20h] ;Loop variable increas
  add  esi, 11Ch           ;Take next element of SYSTEM_MODULE_INFORMATION type
  mov  [ebp-2Ch], esi      ;Temporary save current SYSTEM_MODULE_INFORMATION element
  jmp  FORLOOP


SehFunction     proc near              
    mov     esp, [ebp-18h]
ERRORRET::                                                              
    or      dword ptr [ebp-4], 0FFFFFFFFh
    mov     eax, [ebp-24h]
ErrAllocMem::                            
    ret
SehFunction    endp


;********************************************************************************************
; Equivalent to GetProcessAddress function, hModule point ntoskrnl.exe module, Find the PE export table,
; Find function address of pFunctionName.
; Operating principle: Traverse export table's AddressOfFunctions, Every take one function address, In line with it index of AddressOfFunctions中的
;Traverse whole AddressOfNames table and AddressOfNameOrdinals table, Find sequence number to matched function with AddressOfFunctions
;contrast function name and import paramter 2 whether identical, The same return current function address from AddressOfFunctions,
;Different continue find ...
;********************************************************************************************
GetProcessFromNtoskrnl proc hModule:dword,FunctionName:dword

  LOCAL AddressOfNameOrdinals:dword;Function name index talbe
  LOCAL AddressOfNames:dword       ;Function name address talbe
  LOCAL OutputTable:dword          ;Export table address
  LOCAL AddressOfFunctions:dword   ;Point export function address table point
  LOCAL pFunctionName:dword        ;function name
  LOCAL i:dword                    ;loop variable
  LOCAL CurAddressOfNameOrdinals:dword ;Current function name serial number
  LOCAL CurAddressOfNames:dword        ;Current function address
  LOCAL nIndex:dword                   ;loop variable
  LOCAL myFoundOutFunctionName:dword   ;Function pointer is found from function address table
  LOCAL InputFunctionName:dword         ;input function name pointer, point paramter 2
  LOCAL SecondCharacterOfFunctionName:byte
  LOCAL FirstCharacterOfFunctionName:byte
 
  mov  edx, hModule
  mov  eax, [edx+3Ch]
  add  eax, edx           ; point PEHeader
  cmp  word ptr [edx],  5A4Dh ; 'MZ'
  jnz  Quit
  cmp  dword ptr [eax], 4550h ;'PE'
  jnz  Quit
  mov  eax, [eax+78h]
  add  eax, edx          ;point export
  mov  OutputTable, eax
 
  mov  edi, [eax+20h] ; IMAGE_EXPORT_DIRECTORY.AddressOfNames
  add  edi, edx
  mov  AddressOfNames, edi
 
  mov  esi, [eax+1Ch] ;IMAGE_EXPORT_DIRECTORY.AddressOfFunctions
  add  esi, edx
  mov  AddressOfFunctions, esi
 
  mov  ecx, [eax+24h] ;IMAGE_EXPORT_DIRECTORY.AddressOfNameOrdinals
  add  ecx, edx
  mov  AddressOfNameOrdinals, ecx
 
  and  nIndex, 0
  mov  edx, pFunctionName
 
StartSearch:
  mov  ebx, nIndex
  cmp  ebx, [eax+14h] ;IMAGE_EXPORT_DIRECTORY.NumberOfFunctions
  jnb  Quit
 
  cmp  dword ptr [esi], 0 ;First function addresws judge whether null on AddressOfFunctions
  jz  NextAddressOfFunction          ;If null, Take next function on IMAGE_EXPORT_DIRECTORY.AddressOfFunctions table
 
  mov  CurAddressOfNames, edi
  mov  CurAddressOfNameOrdinals, ecx
  and  i, 0
 
StartFindFunctionFromAddressOfNames:
  mov  ebx, i
  cmp  ebx, [eax+18h]   ;IMAGE_EXPORT_DIRECTORY.NumberOfNames
  jnb  OutOfRange
  mov  ebx, CurAddressOfNameOrdinals
  movzx  ebx, word ptr [ebx]
  cmp  ebx, nIndex      ;Judge index from AddressOfFunctions to get whether fit  AddressOfNameOrdinals get index
  jnz  NextAddressOfNameOrdinals
  mov  edx, CurAddressOfNames
  mov  edx, [edx]
  add  edx, hModule
  mov  pFunctionName, edx   ;Take function name
 
OutOfRange:
  test  edx, edx        ;Judge whether null
  jz  ContinueWork
 
  mov  myFoundOutFunctionName, edx    ;TS function name
  mov  edx, FunctionName
  mov  InputFunctionName, edx         ;TS imput function name
 
CompareFunctionName:
  mov  edx, InputFunctionName
  mov  dl, [edx]
  mov  FirstCharacterOfFunctionName, dl
  mov  ebx, myFoundOutFunctionName
  cmp  dl, [ebx]
  jnz  Different     ;disaffinity
  test dl, dl       ;Judge InputFunctionName whether null, if null, return first function address table
  jz  RetCurrentFunctionAddress
 
  mov  edx, InputFunctionName  ;Contrast function name next character
  mov  dl, [edx+1]
  mov  SecondCharacterOfFunctionName, dl
  cmp  dl, [ebx+1]
  jnz  Different
 
  add  InputFunctionName, 2
  add  myFoundOutFunctionName, 2
  test  dl, dl
  jnz   CompareFunctionName
 
RetCurrentFunctionAddress:
  xor  edx, edx           ;edx = 0,mean find correspond function
  jmp  GetFunctionAddress
 
NextAddressOfNameOrdinals:
  add  CurAddressOfNames, 4
  add  CurAddressOfNameOrdinals, 2
  inc  i
  jmp  StartFindFunctionFromAddressOfNames
 
Different:
  sbb  edx, edx
  sbb  edx, 0FFFFFFFFh  ;edx = 1,表示没有找到对应的函数,继续找
 
GetFunctionAddress:
  test  edx, edx
  jnz  ContinueWork
 
  mov  esi, [esi]
  add  esi, hModule
  mov  eax, esi      ;return function address
  jmp  Founded
 
ContinueWork:
  xor  edx, edx
  mov  pFunctionName, edx
 
NextAddressOfFunction:
  add  esi, 4
  mov  AddressOfFunctions, esi
  inc  nIndex
  jmp  StartSearch
 
Quit:
  xor  eax, eax 
Founded:
  ret
GetProcessFromNtoskrnl endp


No comments:

Post a Comment