Реверсила я вчера ядрышко винды. Точнее, 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, но остальное я понять не смогла.
На досуге почитываю литературу про драйверы, вот случайно наткнулся на твою тему.. Если честно, я немного не понял, для однопроцессорных или многопроцессорных систем в данном случае происходит захват (т.к. в этой функции нету цикла для захвата, что обязательно для многопроцессорных систем, но сама функция в точности повторяет начало примера, рассмотренного на васме для многопроцессорных систем, но как-то цикл куда-то делся), хотя вполне возможно этот цикл как-то реализован в смежной функции. Вообще, читай пачку статей про драйвера на васме, цитирую оттуда как в общих чертах происходит захват: На однопроцессорной машине захват спин-блокировки заключается в простом повышении IRQL до DISPATCH_LEVEL. Как известно, на этом IRQL не происходит планирования потоков, и поток, владеющий процессором, будет выполняться до тех пор, пока IRQL не понизится. Поскольку IRQL является атрибутом процессора, на многопроцессорной машине простого повышения IRQL не достаточно, т.к. это не блокирует потоки, выполняющиеся другими процессорами. Поэтому в многопроцессорных HAL спин-блокировка реализована несколько сложнее и является спин-блокировкой в истинном смысле этого слова (spin - крутить, вертеть; пускать волчок). Т.е. если блокировка занята, поток крутит бесконечный цикл, пытаясь её захватить. При этом т.к. цикл выполняется на IRQL = DISPATCH_LEVEL, планирования потоков на этом процессоре не происходит и процессор не может заняться полезной работой. Именно поэтому спин-блокировки гораздо более критичны ко времени. Т.е. освободить спин-блокировку нужно как можно быстрее. DDK даже определяет максимальный временной интервал в 25 микросекунд, в течении которого можно держать спин-блокировку. В этом смысле мьютексы и другие объекты ожидания менее требовательны, т.к. поток, ожидающий занятый объект, просто исключается из планирования, и процессор получает другой, готовый к выполнению поток. Но пытаться при этом понять листинг ИДЫ это конечно пажощ. Структуру KPRCB ниасилил, очень уж она здоровая..где прочитала что IRQL через неё повышается, а не через KPCR? Я например в KPRCB не нашел полей, напрямую связанных с IRQL, только DebuggerSavedIRQL, но это скорее всего к делу мало отношения имеет. А вот в KPCR явно есть поле Irql. В общем, это темное дело ещё мне предстоит изучить - в этом году курс программирования драйверов
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 Тема закрыта