реверс hal, спинблокировки

Discussion in 'Реверсинг' started by yeti, 17 Jul 2007.

Thread Status:
Not open for further replies.
  1. yeti

    yeti Elder - Старейшина

    Joined:
    27 Dec 2006
    Messages:
    179
    Likes Received:
    234
    Reputations:
    346
    Реверсила я вчера ядрышко винды. Точнее, hal.dll
    Ну вообщем стало интересно по поводу захвата спинблокировок. Открыла в IDA Pro hal.dll, KfAcquireSpinLock.
    Не поможете девушке разобраться с тем, как повышается IRQL там через PKRCB?

    Code:
    .text:800126E0 KfAcquireSpinLock proc near             ; CODE XREF: sub_80013F0C+Ep
    .text:800126E0                                         ; IoFreeAdapterChannel+54p ...
    .text:800126E0                 mov     edx, ds:0FFFE0080h
    .text:800126E6                 mov     dword ptr ds:0FFFE0080h, 41h
    .text:800126F0                 shr     edx, 4
    .text:800126F3                 movzx   eax, ds:byte_8001D088[edx]
    .text:800126FA                 retn
    .text:800126FA KfAcquireSpinLock endp
    Если первая команда еще ясна - получение там адреса, кажется PKRCB, но остальное я понять не смогла.
     
    3 people like this.
  2. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,119
    Reputations:
    1,139
    Вопрос нормальный между прочим. Флейм потерт
     
    1 person likes this.
  3. iv.

    iv. Elder - Старейшина

    Joined:
    21 Mar 2007
    Messages:
    1,183
    Likes Received:
    438
    Reputations:
    107
    На досуге почитываю литературу про драйверы, вот случайно наткнулся на твою тему..
    Если честно, я немного не понял, для однопроцессорных или многопроцессорных систем в данном случае происходит захват (т.к. в этой функции нету цикла для захвата, что обязательно для многопроцессорных систем, но сама функция в точности повторяет начало примера, рассмотренного на васме для многопроцессорных систем, но как-то цикл куда-то делся), хотя вполне возможно этот цикл как-то реализован в смежной функции.
    Вообще, читай пачку статей про драйвера на васме, цитирую оттуда как в общих чертах происходит захват:

    На однопроцессорной машине захват спин-блокировки заключается в простом повышении IRQL до DISPATCH_LEVEL. Как известно, на этом IRQL не происходит планирования потоков, и поток, владеющий процессором, будет выполняться до тех пор, пока IRQL не понизится. Поскольку IRQL является атрибутом процессора, на многопроцессорной машине простого повышения IRQL не достаточно, т.к. это не блокирует потоки, выполняющиеся другими процессорами. Поэтому в многопроцессорных HAL спин-блокировка реализована несколько сложнее и является спин-блокировкой в истинном смысле этого слова (spin - крутить, вертеть; пускать волчок). Т.е. если блокировка занята, поток крутит бесконечный цикл, пытаясь её захватить. При этом т.к. цикл выполняется на IRQL = DISPATCH_LEVEL, планирования потоков на этом процессоре не происходит и процессор не может заняться полезной работой. Именно поэтому спин-блокировки гораздо более критичны ко времени. Т.е. освободить спин-блокировку нужно как можно быстрее. DDK даже определяет максимальный временной интервал в 25 микросекунд, в течении которого можно держать спин-блокировку. В этом смысле мьютексы и другие объекты ожидания менее требовательны, т.к. поток, ожидающий занятый объект, просто исключается из планирования, и процессор получает другой, готовый к выполнению поток.

    Но пытаться при этом понять листинг ИДЫ это конечно пажощ. Структуру KPRCB ниасилил, очень уж она здоровая..где прочитала что IRQL через неё повышается, а не через KPCR? Я например в KPRCB не нашел полей, напрямую связанных с IRQL, только DebuggerSavedIRQL, но это скорее всего к делу мало отношения имеет. А вот в KPCR явно есть поле Irql.
    В общем, это темное дело ещё мне предстоит изучить - в этом году курс программирования драйверов ;)
     
    2 people like this.
  4. _Great_

    _Great_ Elder - Старейшина

    Joined:
    27 Dec 2005
    Messages:
    2,032
    Likes Received:
    1,119
    Reputations:
    1,139
    iv., процитировал руссиновича, молодец.

    По делу я могу уже ответить, я разобрался.

    FFFE0000 - базовый адрес маппинга регистров APIC в виртуальное адресное пространство. По смещению 80h там находится регистр Task Priority Register (TPR)
    Значение 41 маскирует все прерывания выше 0, то есть аналогично IRQL=DISPATCH_LEVEL

    Вообщем APIC[TPR]=41h тоже самое что и KfRaiseIrql( DISPATCH_LEVEL )

    movzx eax, ds:byte_8001D088[edx] - это таблица HalpIRQLtoTPR, устанавливающая соответствие между уровнями IRQL и соотв. значениями регистра TPR. Эта инструкция возвращает старый иркл по сохраненному значению TPR

    Тема закрыта
     
Thread Status:
Not open for further replies.