суббота, 31 марта 2012 г.

NtPlugPlayControl

This poorly documented function can serves as silently communication channel between UM & KM. Let see how it works (code was borrowed from w8 dev preview 64bit)

  cmp     r15d, 17h ; check
PnPControlClass
  jnb     loc_1405C73D5 ; return STATUS_INVALID_PARAMETER_1
  mov     r14, r15
  lea     rcx, PlugPlayHandlerTable ; located in writable PAGEDATA section
  shl     r14, 4        ; PnPControlClass << 4
  add     r14, rcx      ; get record describing this
PnPControlClass
  cmp     [r14], r15d   ; field at offset 0 - PnPControlClass
  jnz     loc_1405C73CB ; return STATUS_INTERNAL_ERROR
  test    r14, r14      ; I don`t know for what this paranoid check
  jz      loc_1405C73D5 ; return STATUS_INVALID_PARAMETER_1
  cmp     qword ptr [r14+8], 0 ; Gotcha ! This is pointer to function
  jz      loc_1405C7304 ; return STATUS_NOT_IMPLEMENTED
  cmp     [r14+4], ebp    ; field at offset 4 - PnPControlDataLength
  jnz     loc_1405C730E ; return STATUS_INVALID_PARAMETER_MIX
  ...
  mov     r8d, ebp  ; PnPControlDataLength
  mov     rdx, rbx  ; PnPControlData
  mov     ecx, r15d ; PnPControlClass
  call    qword ptr [r14+8] ; call handler by pointer


The main problem with this code is that it calls function by pointer which located in writable PAGEDATA section. Also this section is not checking by PatchGuard. So you can rewrite some unused handler (and perhaps length of PnPControlDataLength) and call PnPControlClass with patched PnPControlClass to pass some data to code in KM.
Actually there is a lot of unused entries in PlugPlayHandlerTable - on w8 dev preview it contains only 8 handlers:
  • PiControlStartDevice for code 4
  • PiControlQueryAndRemoveDevice for code 6
  • PiControlGetPropertyData for code 0xA
  • PiControlGetRelatedDevice for code 0xC
  • PiControlGetSetDeviceStatus for code 0xE
  • PiControlGetDeviceDepth for code 0xF
  • PiControlQueryDeviceRelations for code 0x10
  • PiControlQueryConflictList for code 0x12
Only drawback of this hole - your usermode code must held SeTcbPrivilege before calling NtPlugPlayControl

Комментариев нет:

Отправить комментарий