sprintf, memcpy и IRQL в ядре

Тема в разделе "WASM.WIN32", создана пользователем SteelRat, 8 сен 2005.

  1. SteelRat

    SteelRat New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2004
    Сообщения:
    409
    На каких уровнях IRQL, в ядре можно вызывать эти ф-ции ? Делаю лог-журнал для firewall. Один поток (главный) считывает данные и помещает в очередь (с двумя сетевухами DISPATH_LEVEL) Другой поток (PASSIVE_LEVEL) берёт из очереди данные и пишет в файл. Работает так некоторое время и вываливается BSOD

    Bug Check 0x7F: UNEXPECTED_KERNEL_MODE_TRAP

    Адреса нету (This signifies that a trap was generated by the Intel CPU which the kernel did not catch.) Сначала избавился от memcpy - не помогло, теперь грешу на sprintf, но свою ф-цию писать накладно :dntknw: В MSDN даётся только для юзермод :dntknw: Есть мысли, пожелания, предположения ? Ж:)

    P.S. Очередь - неподкачиваемый пул
     
  2. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"


    Если память неподкачиваемая, то на любом IRQL, если подкачиваемая, то < DISPATH_LEVEL







    А как дела обстоят с синхронизацией?

    Вот код, который я использовал для ведения лога на высоких IRQL, и вроде он всегда нормально работает:
    Код (Text):
    1. void AddLog(PCHAR Message)
    2. {
    3.     KIRQL OldIrql;
    4.  
    5.     KeAcquireSpinLock(&LogSpinLock, &OldIrql);
    6.  
    7.     if (MSG_BUFF_SIZE - strlen(SendMsgs) > strlen(Message) + 3)
    8.     {
    9.         strcat(SendMsgs, Message);
    10.         strcat(SendMsgs, "\x0D\x0A");
    11.     }
    12.  
    13.     KeReleaseSpinLock(&LogSpinLock, OldIrql);
    14. }
    15.  
    16. LogPrint(PCH Format, ...)
    17. {
    18.    CHAR Buffer[1024];
    19.  
    20.    va_list ap;
    21.  
    22.    va_start (ap, Format);
    23.  
    24.    _vsnprintf (Buffer, sizeof( Buffer ), Format, ap);
    25.  
    26.    va_end (ap);
    27.  
    28.    AddLog(Buffer);
    29. }
     
  3. SteelRat

    SteelRat New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2004
    Сообщения:
    409
    Ms Rem Технология именно такая же :) Есть у меня жестокое подозрение, что это деление на 0, т.к. уровень диспетчера, то BugCheck может "пролетать мимо кассы".

    Делается очередь на 100 структур есть счётчик tail(хвоста) и head(головы) при совпадении - очередь пуста. При помещении в очередь вычисляется новый head=head+1 с помощью целочисленного деления на длину очереди (берётся остаток) усножаем на sizeof(Structra) и прибавляем указатель на начало очереди :) Т.о. добиваемся заполнения по кругу
    Код (Text):
    1.  
    2.   |--->|
    3. -----  |
    4. |   |  |
    5. |   |  |
    6. |   |  |
    7. |   |  |
    8. -----  |
    9.   |<---|
    10.  


    Деление на 0 при уровне диспетчера BugCheck-м перехватывается ?
     
  4. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"




    По моему в ядре такое исключение вообще нельзя обработать. По любому бсод будет.
     
  5. SteelRat

    SteelRat New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2004
    Сообщения:
    409
    The first parameter displayed on the blue screen specifies the trap number.

    ....

    0x00000008, or Double Fault, is when an exception occurs while trying to call the handler for a prior exception. Normally, the two exceptions can be handled serially. However, there are several exceptions that cannot be handled serially, and in this situation the processor signals a double fault. This is almost always caused by hardware problems.

    У меня именно это :dntknw:( Это в WMVare конечно, придётся на живой машине пробовать :dntknw:
     
  6. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    memcpy можно звать на любом IRQL, лишь бы помять, к которой она обращается, была неподкачиваема. Про sprintf точно не скажу, но, например, DbgPrint можно звать только на PASSIVE_LEVEL, если в спецификаторе используется unicode (%C, %S, %lc, %ls, %wc, %ws, %wZ). RtlCompareUnicodeString можно звать только на PASSIVE_LEVEL, по той причине, что она обращается к таблицам национальных раскладок, а они загружены в подкачиваемую память. Если DbgPrint работает с юникодом, то, видимо, тоже к ним обращается. Возможно то же самое делает и swprintf и sprintf, если форматируют юникод.
     
  7. SteelRat

    SteelRat New Member

    Публикаций:
    0
    Регистрация:
    26 авг 2004
    Сообщения:
    409
    Проблема была найдена, только в другом месте :)

    Прототип ф-ции

    KeReleaseSpinLock PROTO STDCALL :lol: WORD, :lol: WORD



    Вызываем
    Код (Text):
    1. LogPrintf proc uses esi edi edx Fmt:PCHAR, Arg:UINT
    2.     ;
    3. ......
    4. local entry  :QUEUE_ENTRY
    5. local irql   :KIRQL; определён как BYTE
    6. ......
    7.   invoke KeAcquireSpinLock, offset Queue.guard, addr irql
    8. ......
    9.   invoke KeReleaseSpinLock offset Queue.guard, irql
    10.  


    Что получаем при дизассемблировании 8-( )
    Код (Text):
    1.   mov         al,[ebp][-0000009D]
    2.   movzx       ax,al
    3.   push        ax; <- почему WORD ?
    4.   push        0000136F4
    5.   call        KeReleaseSpinLock
    6.  


    А получаем ДЫРУ В СТЭКЕ В 2 БАЙТА >8-( ) В ядре это BSOD. Интересно что это MASM криво асмит или прототип в другом месте по другому описан ? Если прототип, то MASM обычно ругается :dntknw:
     
  8. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    У меня такая же фигня была с WRITE_PORT_UCHAR и т.п. Проишлось делать так:
    Код (Text):
    1. mov eax, XXXXXXXX
    2. and eax, 0FFh
    3. invoke WRITE_PORT_UCHAR, 42h, eax


    Уже не помню, но кажется это именно масм косячит.