2010-11-25 3 views
1

Я столкнулся с (возможной) проблемой с DDK (довольно старая версия: 3590) для WinXP 32 бит. Мой драйвер содержит некоторые статические переменные, которые не инициализированы (они должны быть назначены в .bss-раздел, я полагаю) и некоторые функции в разделе кода страницы (помечены #pragma alloc_page (PAGE, func)). Код для просмотра в отдельном объектном файле. Я обнаружил, что компоновщик, по-видимому, назначает статику и код для страницы на одну и ту же страницу в адресном пространстве ядра (т. Е. Переменная имеет значение 0xEFFCB0A0, а функция находится в 0xEFFCB600 - проверена с помощью windbg). Статические переменные используются в среде прерывания, поэтому их страницы должны быть заблокированы в памяти. Но если на той же странице есть код с возможностью замены, я боюсь, что переменные могут внезапно исчезнуть. Карта компоновщика корректно сообщает, что код для страницы находится в другом разделе («PAGE»), но смещение («Rva + Base») находится посередине страницы, содержащей статику.#pragma alloc_text (PAGE) код не выровнен по странице

Как я могу заставить компоновщик/загрузчик назначить отдельные страницы для кода, доступного для просмотра? Есть ли какая-то «# прагма» для принудительного выравнивания сечения? Я делаю что-то неправильно?

PS: Погрузчик с драйверами, несомненно, достаточно умен, чтобы переместить страницу из переменных и кода из выгружаемого пула, но поскольку страница содержит переменные, она должна быть доступна для записи. Я бы предпочел, чтобы исполняемый код находился на странице только для чтения. Неправильный доступ к массиву в режиме ядра еще так сложно отлаживать ...

PPS: Добавлена ​​4096 «nop» s до и после моей функции ... нормально, это работает ... ничего лучше предложить?

+0

Эй, этот вопрос наверняка висел здесь долго. Действительно ли исполняемый код драйвера обычно является только для чтения? В конце концов, сделать код readonly кажется довольно недавним «трендом». – Ilya 2011-02-06 19:24:52

ответ

1

Разместите ваши Глобал в своем собственном сегменте данных:

#pragma data_seg("NONPAGE") 
// declare your globals here 
#pragma data_seg() 

Источник: MSDN link on data_seg

По умолчанию вашего раздела будет создаваться с помощью чтения/записи, а не выгружаемых флагов.

Вы можете указать дополнительные параметры раздел:

#pragma comment(linker, "/section:NONPAGE,ERW") 

Источник: MSDN link on /SECTION

или вы можете разместить свои варианты компоновщика в SOURCES файле:

LINKER_FLAGS = $(LINKER_FLAGS) /SECTION:NONPAGE,ERW 

Примечание: если вы строите библиотека, используйте LIBRARIAN_FLAGS вместо

0

Честно говоря, я не знаю о DDK (или сборке ОС) с этим номером сборки, поэтому я предполагаю, что мы говорим о 3790 или 3790.1830.

Извините, похоже, я не совсем понял. Независимо от того, доступна ли запись для записи, полностью зависит от MDL, через который происходит доступ, не так ли?

В противном случае вы обнаружите, что в OSR (в частности, NTDEV) у нас гораздо более оживленная дискуссия по этим конкретным темам. Это не то, что вы ожидали бы увидеть в форуме с общими вопросами программирования;)

+0

Моя «проблема» (на самом деле это не настоящая проблема, а проблема) заключается в том, что кодовые страницы драйвера обычно доступны только для чтения (проверены с помощью windbg), если они не содержат также статических переменных.Если бы переменные были помещены на другую страницу, то не было бы записываемого кода. Код только для чтения в целом хорош, потому что плохие указатели или неправильные индексы массивов не могут повредить его. До свидания! – 2011-02-13 18:17:54