BSOD: Как работать с системой после перехвата KeBugCheckEx?

Тема в разделе "WASM.NT.KERNEL", создана пользователем deshiko, 11 фев 2009.

  1. deshiko

    deshiko New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2009
    Сообщения:
    42
    Код (Text):
    1. PKBUGCHECK_CALLBACK_RECORD BugCheckData;  /*Указатель на BugCheck запись*/
    2. BugCheckData = (PKBUGCHECK_CALLBACK_RECORD)ExAllocatePool(NonPagedPool, 1024); /*выделяем под нее память*/
    3. KeInitializeCallbackRecord(BugCheckData); /*инициируем запись*/
    4. KeRegisterBugCheckCallback(BugCheckData, BugCheckCallback, 0, 0, "BUGCHECK");  /*регистрируем callback-функцию*/
    5.  
    6. /*Сама функция*/
    7. VOID BugCheckCallback(IN PVOID Buffer, IN ULONG Length)
    8. {
    9.  HalDisplayString("\n\nHello World!\n\n");   /*выводим на экран строчку*/
    10.  return;
    11. }
    В умной книжке Руссиновича прочитал, что при данной ситуации мы попадаем на HAL-уровень.

    Соответственно сами вопросы: Каким образом можно выполнить очистку экрана и вывести на экран новое, так сказать отредактированное сообщение?
    И второй - как при данной ситуации добавить ключ в реестр или записать что-то на диск (чтобы после перезагрузки можно было это считать)?

    Думаю что решение в использование прямого обращения, с помощью ассемблера в режиме VGA (так как при BSOD именно в этом режиме выводиться информация), к видио, но не знаю как это реализовать?

    Помогите, если кто-то знает, как решить данные трудности.
     
  2. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Неверно думаешь. Вывод производится с помощью InbvDisplayString(), а очистить можно, к примеру, с помощью InbvResetDisplay().

    А как ты делаешь это до BSOD'a?

    Вот кодес, писал когда-то для одной девочки. Очищает экран и выводит в одну строчку на синем фоне счёт от одного до десяти:
    Код (Text):
    1. DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
    2.     local Status: NTSTATUS
    3.     local buf[100]: CHAR
    4.      
    5.     mov        Status, STATUS_DEVICE_CONFIGURATION_ERROR
    6.     push    esi
    7.      
    8.     call    InbvIsBootDriverInstalled
    9.     test    al, al
    10.     jz        _fail
    11.     call    InbvAcquireDisplayOwnership
    12.     call    InbvResetDisplay
    13.     xor        esi, esi
    14.     push    4
    15.     push    1DFh
    16.     mov        ebx, 27Fh
    17.     push    ebx
    18.     push    esi
    19.     push    esi
    20.     call    InbvSolidColorFill
    21.     push    0Fh
    22.     call    InbvSetTextColor
    23.     push    esi
    24.     call    InbvInstallDisplayStringFilter
    25.     inc        esi
    26.     push    esi
    27.     dec        esi
    28.     call    InbvEnableDisplayString
    29.     push    1DBh
    30.     push    ebx
    31.     push    esi
    32.     push    esi
    33.     call    InbvSetScrollRegion
    34.     invoke    InbvDisplayString, $CTA0("\n\n\n\n\n\n\n\n\n")
    35.     push    10
    36.     pop        ecx
    37.   _loop:
    38.     push    ecx
    39.     invoke    sprintf, addr buf, $CTA0("Final coundown: %d \r"), ecx
    40.     invoke    InbvDisplayString, addr buf
    41.     pop        ecx
    42.     loop    _loop
    43.     jmp        $
    44.  
    45.     pop        esi
    46.     mov        eax, Status
    47.     ret
    48.  
    49.   _fail:
    50.       invoke    DbgPrint, $CTA0("Error\n")
    51.       mov        eax, Status
    52.       ret
    53. DriverEntry endp
     
  3. deshiko

    deshiko New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2009
    Сообщения:
    42
    Спасибо с выводом на экран оказалось решилось все просто, после вашего объяснения!
    Вот только мой вывод идет за системным выводом, а мне бы хотелось, чтобы системный вывод замещался немедленно.

    А как ты делаешь это до BSOD'a?

    примерно так
    Код (Text):
    1. NTSTATUS write_reg(VOID)
    2. {
    3.     HANDLE hkey=NULL;
    4.     OBJECT_ATTRIBUTES oa1;
    5.     UNICODE_STRING RegistryKey;
    6.     UNICODE_STRING valname;
    7.     NTSTATUS status;
    8.    
    9.     ULONG value1=2;
    10.     RtlInitUnicodeString(&valname, L"Start");
    11.  
    12.    
    13.  
    14.  
    15.     RtlInitUnicodeString(&RegistryKey, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
    16.     InitializeObjectAttributes(&oa1, &RegistryKey, OBJ_CASE_INSENSITIVE, NULL, NULL);
    17.     status = ZwCreateKey(&hkey,KEY_WRITE, &oa1, 0, NULL,REG_OPTION_NON_VOLATILE,NULL);
    18.    
    19.     ZwSetValueKey(hkey, &valname, 0, REG_DWORD,          &value1, sizeof(ULONG));
    20.     ZwClose(hkey);
    21.     return status;
    22. }
    В любом случае спасибо!
     
  4. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Перехвати KeBugCheck2() (именно её вызывают KeBugCheck() и KeBugCheckEx()) сплайсом и выводи что хочешь - ни чего толкового, кроме вывода информации об ошибке и записи крэш-дампа она не делает, да и возврата из функции не происходит.

    Ну вот так и делай. Только я бы не рискнул писать что-то куда-то после возникновения ошибки - чревато порчей информации. Хотя и этот вопрос спорный - система же пишет данные дампа в файл...
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    почитай в msdn'e про KeRegisterBugCheckCallback.
    Там описаны накладываемые ограничения.
     
  6. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Легче заглянуть в WRK. Сразу видно, что калбаки вызываются в самом конце (KiScanBugCheckCallbackList()), уже после того, как информация об ошибке выведена на экран, что по условию не подходит автору.
     
  7. VENOM4X

    VENOM4X New Member

    Публикаций:
    0
    Регистрация:
    18 мар 2008
    Сообщения:
    29
    AFAIK она пишет в начало свопа, и уже при загрузке "вытаскивает" дамп в отдельный файл.
     
  8. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    А своп не на диске находится? ;) Другое дело, что запись осуществляется не с помощью IoWriteFile, что естественно.
     
  9. deshiko

    deshiko New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2009
    Сообщения:
    42
    Все это тоже пробовал - данный способ описан в статье great-а "Жизнь после смерти" http://gr8.cih.ms/bsodhandling.cpp - там исходник.
    Но что в первом случает с регистрацией callback, что, во-втором, с использованием сплайс-hook-а ничего не выходит.
    То есть в файл и в реестр ничего не записываться!

    Немного помогли функции Inbv*** но с их помощью вывод на экран осуществляться после машинного BSOD, а мне нужно до или вместо.

    По поводу KiScanBugCheckCallbackList
    нашел интересную ссылку http://www.virustech.org/f/viewtopic.php?pid=58 - перехват исключений в ядре.
    Так вот там описана система BSOD, в которой осуществляется перехват KeStallExecutionProcessor - эта функция исполняется до вывода синего экрана.

    Но честно я пока не представляю как это реализовать!

    А с помощью чего?