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 ?
Видимо баг. Если KiTimerTableListHead не пустой, то для table entries с индексом > 255 не будет установлен infinity time(or [edi+KTIMER_TABLE_ENTRY.Time_HighPart], 0FFFFFFFFh). Правда я не разбирался, для чего он вобще устанавливается.
ОтветитьУдалитьзато он будет установлен не по делу для индексов < 256
ОтветитьУдалить