Многоядерные процессоры и проблемы ими порождаемые



             

Уровень драйверов - часть 6


Допустим, мы записываем 5ти байтовую команду JMP NEAR TARGET поверх 2х байтовой команды MOV EBP,ESP, естественно, затрагивая следующую за ней команду. Даже на однопроцессорных машинах существует вероятность, что какой-то из потоков был ранее прерван сразу же после выполнения MOV EBP,ESP и когда он возобновит свое выполнение, то… окажется _посередине_ команды JMP NEAR TARGET, что повлечет за собой непредсказуемое поведение системы.

Алгоритм безопасной модификации выглядит так: перехватываем INT 03h, запоминая адрес прежнего обработчика, внедряем в начало перехватываемой функции CCh (если только программная точка уже не установлена). При возникновении прерывания INT 03h мы сравниваем полученный адрес со списком адресов перехваченных функций и, если это, действительно, "наш" адрес, выполняем ранее сохраненную машинную инструкцию в своем буфере и передаем управление на вторую инструкцию перехваченной функции. Снимать CCh ни в коем случае нельзя! Поскольку в этот момент функцию может вызывать кто-то еще, но наш перехватчик "прозевает" этот факт!

Если же полученный адрес не "наш", мы передаем управление предыдущему обработчику INT 03h. Тоже самое мы делаем, если программная точка останова была установлена еще до перехвата. Тогда мы позволяем предыдущему обработчику INT 03h восстановить ее содержимое, а сами ставим CCh на следующую инструкцию. Конечно, такой способ перехвата _намного_ сложнее "общепринятого", зато он на 100% надежен и работает в любых конфигурациях — как одно- так и многопроцессорных.




Содержание  Назад  Вперед