Код (Text): PKBUGCHECK_CALLBACK_RECORD BugCheckData; /*Указатель на BugCheck запись*/ BugCheckData = (PKBUGCHECK_CALLBACK_RECORD)ExAllocatePool(NonPagedPool, 1024); /*выделяем под нее память*/ KeInitializeCallbackRecord(BugCheckData); /*инициируем запись*/ KeRegisterBugCheckCallback(BugCheckData, BugCheckCallback, 0, 0, "BUGCHECK"); /*регистрируем callback-функцию*/ /*Сама функция*/ VOID BugCheckCallback(IN PVOID Buffer, IN ULONG Length) { HalDisplayString("\n\nHello World!\n\n"); /*выводим на экран строчку*/ return; } В умной книжке Руссиновича прочитал, что при данной ситуации мы попадаем на HAL-уровень. Соответственно сами вопросы: Каким образом можно выполнить очистку экрана и вывести на экран новое, так сказать отредактированное сообщение? И второй - как при данной ситуации добавить ключ в реестр или записать что-то на диск (чтобы после перезагрузки можно было это считать)? Думаю что решение в использование прямого обращения, с помощью ассемблера в режиме VGA (так как при BSOD именно в этом режиме выводиться информация), к видио, но не знаю как это реализовать? Помогите, если кто-то знает, как решить данные трудности.
Неверно думаешь. Вывод производится с помощью InbvDisplayString(), а очистить можно, к примеру, с помощью InbvResetDisplay(). А как ты делаешь это до BSOD'a? Вот кодес, писал когда-то для одной девочки. Очищает экран и выводит в одну строчку на синем фоне счёт от одного до десяти: Код (Text): DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING local Status: NTSTATUS local buf[100]: CHAR mov Status, STATUS_DEVICE_CONFIGURATION_ERROR push esi call InbvIsBootDriverInstalled test al, al jz _fail call InbvAcquireDisplayOwnership call InbvResetDisplay xor esi, esi push 4 push 1DFh mov ebx, 27Fh push ebx push esi push esi call InbvSolidColorFill push 0Fh call InbvSetTextColor push esi call InbvInstallDisplayStringFilter inc esi push esi dec esi call InbvEnableDisplayString push 1DBh push ebx push esi push esi call InbvSetScrollRegion invoke InbvDisplayString, $CTA0("\n\n\n\n\n\n\n\n\n") push 10 pop ecx _loop: push ecx invoke sprintf, addr buf, $CTA0("Final coundown: %d \r"), ecx invoke InbvDisplayString, addr buf pop ecx loop _loop jmp $ pop esi mov eax, Status ret _fail: invoke DbgPrint, $CTA0("Error\n") mov eax, Status ret DriverEntry endp
Спасибо с выводом на экран оказалось решилось все просто, после вашего объяснения! Вот только мой вывод идет за системным выводом, а мне бы хотелось, чтобы системный вывод замещался немедленно. А как ты делаешь это до BSOD'a? примерно так Код (Text): NTSTATUS write_reg(VOID) { HANDLE hkey=NULL; OBJECT_ATTRIBUTES oa1; UNICODE_STRING RegistryKey; UNICODE_STRING valname; NTSTATUS status; ULONG value1=2; RtlInitUnicodeString(&valname, L"Start"); RtlInitUnicodeString(&RegistryKey, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"); InitializeObjectAttributes(&oa1, &RegistryKey, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwCreateKey(&hkey,KEY_WRITE, &oa1, 0, NULL,REG_OPTION_NON_VOLATILE,NULL); ZwSetValueKey(hkey, &valname, 0, REG_DWORD, &value1, sizeof(ULONG)); ZwClose(hkey); return status; } В любом случае спасибо!
Перехвати KeBugCheck2() (именно её вызывают KeBugCheck() и KeBugCheckEx()) сплайсом и выводи что хочешь - ни чего толкового, кроме вывода информации об ошибке и записи крэш-дампа она не делает, да и возврата из функции не происходит. Ну вот так и делай. Только я бы не рискнул писать что-то куда-то после возникновения ошибки - чревато порчей информации. Хотя и этот вопрос спорный - система же пишет данные дампа в файл...
Легче заглянуть в WRK. Сразу видно, что калбаки вызываются в самом конце (KiScanBugCheckCallbackList()), уже после того, как информация об ошибке выведена на экран, что по условию не подходит автору.
А своп не на диске находится? Другое дело, что запись осуществляется не с помощью IoWriteFile, что естественно.
Все это тоже пробовал - данный способ описан в статье great-а "Жизнь после смерти" http://gr8.cih.ms/bsodhandling.cpp - там исходник. Но что в первом случает с регистрацией callback, что, во-втором, с использованием сплайс-hook-а ничего не выходит. То есть в файл и в реестр ничего не записываться! Немного помогли функции Inbv*** но с их помощью вывод на экран осуществляться после машинного BSOD, а мне нужно до или вместо. По поводу KiScanBugCheckCallbackList нашел интересную ссылку http://www.virustech.org/f/viewtopic.php?pid=58 - перехват исключений в ядре. Так вот там описана система BSOD, в которой осуществляется перехват KeStallExecutionProcessor - эта функция исполняется до вывода синего экрана. Но честно я пока не представляю как это реализовать! А с помощью чего?