хай всем такой вопрос выделяю вручную nonpaged память, и юзаю её как стек в драйвере. всё работало в прицнипе, но когда я включил verifier, при выгрузке драйвер начал вылетать с сообщением что worker thread завершён с irql=2 а не 0. я несколько дней долбался, пытаясь выяснить причину, проверял - в самом конце driverunload-а irql==0. остаётся одна возможная причина - где то я чтото запорол. сам код ничего особого не делает (треды не создаются), за исключением того что юзает вручную выделенный стек. роя гугл я гдето мельком прочитал что менять стек нельзя ни в коем случае, сейчас эту инфу найти не могу. кто-нить сталкивался с этим?
похоже дело было не в стеке а в том что забыл регистр восстановить при выходе из функции. но всё же вопрос остаётся открытым - кошерно ли юзать свой стек?
x64 Хм... Вполне возможно. Я так же как и Great, к примеру, с x64-based systems не шибко дружу - не приходилось. Но все равно, немного туманное высказывание. Ты мог бы привести нормальную ссылку на первоисточник? Хочется аргументов ADD: Это было оно?
Прочитал. Ну про модификацию SSDT и иже с ней и так ясно, а вот про стек не знал, спасибо. Вырисовалась очередная причина не юзать самопальный стек. Но мой вопрос к ТС остается открытым: а какие-такие причины заставили создавать свой стек?
скажем так, защита отдельной части кода драйвера, протектор вызывается периодически и стек драйвера ни в коем случае не должен изменять никаким образом.
vladqq Немного расплывчатое объяснение, не до конца ясна суть. Но все же попробую усомниться в том, что нормально спроектированный протектор кода от модификации или еще от чего-либо будет портить стеки каких-либо потоков. ЗЫ. Что в данном контексте есть "стек драйвера"? То, о чем я думаю?
Можно свой стек создать, только нужно должным образом его настроить в ETHREAD(InitialStack для трап-фреймов и пр.). Можно расширить имеющийся MmGrowKernelStack(). (x64 - не документировано, в мсдн нет.. так к слову :P).
vladqq Кстате знакомая ошибка. У меня падало, когда я изменял PreviousMode, сделав опечатку - писал вместо байта дворд, тоесть затерались следующие 3 байта(не помню что там).
Twister ну вот есть драйвер, скомпиленый. на него вешается протектор, который добавляет свой код в драйвер. код этот достаточно велик, это не одна функция на асме. соответственно коду этому нужен стек. стек драйвера я юзать не рискую, так как там можно чтото затереть не то, да и бывает надо данные в стеке сохранять между вызовами. ещё одну багу обнаружил - часть api-вызовов ядра, типа работы с мьютексами, портят содержимое регистров как хотят, я то думал что они сохраняют их. кто-нить в курсе где найти описание того какие из регистров ядро в праве портить ?
По общепринятому соглашению ebx, esi, edi, ebp функции должны сохранять, а ecx, eax, edx сохранять не обязаны. По тому же соглашению возвращаемое значение заносят в eax, а если оно 64битное - то в пару edx:eax. По тому же соглашению, аргументы в стек заносят в порядке справа налево (cdecl,stdcall), или по регистрам (ecx, edx, остальные на стек - fastcall), место под аргументы чистит вызывающая (cdecl) или вызываемая (stdcall, fastcall) функция.
Я повторюсь: нормальный код ничего не будет портить и затирать. Пересмотрите нюансы. Для этого существует секция данных. Расширьте для своих нужд имеющуюся / создайте свою / просто выделите память для хранения своих данных.
Twister я не совсем правильно выразился. данные, сохраняемые, это стековые переменные при ветвлениях типа: драйвер -> драйвер -> протектор -> драйвер -> протектор -> драйвер ......