Что такое пул и зачем ему заголовки
Драйверам постоянно нужна память под мелкие структуры: описания запросов, буферы, списки открытых объектов. Выделять под каждую отдельную страницу было бы расточительно, поэтому ядро держит пул — большую область, нарезанную на блоки разного размера. Драйвер просит блок, пользуется им и возвращает. Чтобы вести учёт, перед каждым блоком стоит заголовок: размер этого блока, размер предыдущего, признак занятости и метка из четырёх символов, по которой видно, какой драйвер блок взял.
Заголовки выстраиваются в цепочку: зная размер одного блока, ядро находит следующий. Поэтому стоит драйверу записать в свой блок больше, чем он просил, как лишние байты ложатся на заголовок соседа. Разметка ломается, и при следующей операции с этим участком ядро видит противоречие. Microsoft перечисляет варианты: заголовки двух соседних блоков противоречат друг другу, размер блока нулевой или слишком большой, заголовок освобождённого блока изменили уже после освобождения, освобождается адрес, который никогда не выделялся.
Главная сложность — время. По описанию Microsoft, к моменту остановки пул уже повреждён, и компонент, который обратился к нему последним, может быть не виноват. Порча могла произойти минутой раньше, а обнаружиться при безобидной операции другого драйвера. Поэтому имя файла на экране здесь особенно ненадёжно. Вопрос «система или железо» решают по характеру сбоев: повторяющийся код после установки программы — ищут драйвер; нерегулярные экраны с разными кодами — проверяют память.
