среда, 30 ноября 2011 г.

размер KiTimerTableListHead

а вот например вижу я под vista sp2 примерно такой замечательный кусок кода в ф-ции KeSetTimerEx:

  movzx   edi, byte ptr [esi+2] ; KTIMER.Header.Hand
  mov     eax, large fs:20h ; KPCR.Prcb
  mov     ecx, edi
  and     ecx, 1Fh ;
KTIMER.Header.Hand & 0x1F
  lea     ebx, [eax+ecx*8+4A0h] ; somewhere inside KPRCB.LockQueue
  mov     ecx, ebx
  call    KeAcquireQueuedSpinLockAtDpcLevel
  mov     byte ptr [esi+3], 0
  mov     eax, [esi+18h]
  mov     ecx, [esi+1Ch]
  cmp     eax, ecx
  mov     [ecx], eax
  mov     [eax+4], ecx
  jnz     short loc_4ABC30
  shl     edi, 4 ;
KTIMER.Header.Hand * sizeof(KTIMER_TABLE_ENTRY)
  add     edi, offset _KiTimerTableListHead ;
KiTimerTableListHead[KTIMER.Header.Hand]
  cmp     edi, [edi]

Во всех источниках сказано что размер таблицы KiTimerTableListHead под vista равен 512 элементов. Собственно проверить это легко - адрес KiTimerTableListHead 0x4FCB80, адрес следующей за ней структуры AlpcpNPLookasides 0x4FEB80. Размер 0x2000 / 0x10 = 512 элементов. Еще одна проверка - ф-ция KiComputeTimerTableIndex возвращает результат как маску с 0x1FF
В приведенном же коде мы видим что в регистре edi хранится байт, взятый из KTIMER.Header.Hand и используется как индекс в KiTimerTableListHead для проверки всякого. В байте однако число 512 никак не может уместиться. Соотв-но wtf ?

2 комментария:

  1. Видимо баг. Если KiTimerTableListHead не пустой, то для table entries с индексом > 255 не будет установлен infinity time(or [edi+KTIMER_TABLE_ENTRY.Time_HighPart], 0FFFFFFFFh). Правда я не разбирался, для чего он вобще устанавливается.

    ОтветитьУдалить
  2. зато он будет установлен не по делу для индексов < 256

    ОтветитьУдалить