Помогите с переводом кода Visual C++ на inline assembler

Тема в разделе "WASM.NT.KERNEL", создана пользователем Dron247, 24 янв 2010.

  1. Dron247

    Dron247 Андрей

    Публикаций:
    0
    Регистрация:
    24 янв 2010
    Сообщения:
    7
    Закнчиваю университет, вместо экзамена преподаватель предложил написать драйвер меняющий маппинг клавиатуры, сам фильтр вполне работоспособен, но при попытке вставить ассемблерный код (беру его из листинга генерируемого компилятором студии, видимо проблема в этом, так как sys беру тот, что выдается ddk build) система валится в bsod.
    C++ код:
    Код (Text):
    1.         KeyData = Irp->AssociatedIrp.SystemBuffer;
    2.         numKeys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
    получаемая вставка:
    Код (Text):
    1. __asm{
    2.             ; Line 411
    3.             mov edx, DWORD PTR Irp[ebp]
    4.             mov eax, DWORD PTR [edx+12]
    5.             mov DWORD PTR KeyData[ebp], eax
    6.             ; Line 412
    7.             mov ecx, DWORD PTR Irp[ebp]
    8.             mov eax, DWORD PTR [ecx+28]
    9.             xor edx, edx
    10.             mov ecx, 12                 ; 0000000cH
    11.             div ecx
    12.             mov DWORD PTR numKeys[ebp], eax
    13. }
    Полный код функции:
    Код (Text):
    1. NTSTATUS Ctrl2capReadComplete(
    2.     IN PDEVICE_OBJECT DeviceObject,
    3.     IN PIRP Irp,
    4.     IN PVOID Context
    5.     )
    6. {
    7.     PIO_STACK_LOCATION        IrpSp;
    8.     PKEYBOARD_INPUT_DATA      KeyData;
    9.     int                       numKeys, i;
    10.  
    11.     //
    12.     // Request completed - look at the result.
    13.     //
    14.     IrpSp = IoGetCurrentIrpStackLocation( Irp );
    15.     if( NT_SUCCESS( Irp->IoStatus.Status ) ) {
    16.  
    17.         //
    18.         // Do caps-lock down and caps-lock up. Note that
    19.         // just frobbing the MakeCode handles both the up-key
    20.         // and down-key cases since the up/down information is specified
    21.         // seperately in the Flags field of the keyboard input data
    22.         // (0 means key-down, 1 means key-up).
    23.         //
    24.         /*KeyData = Irp->AssociatedIrp.SystemBuffer;
    25.         numKeys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);*/
    26.         __asm{
    27.             ; Line 411
    28.             mov edx, DWORD PTR Irp[ebp]
    29.             mov eax, DWORD PTR [edx+12]
    30.             mov DWORD PTR KeyData[ebp], eax
    31.             ; Line 412
    32.             mov ecx, DWORD PTR Irp[ebp]
    33.             mov eax, DWORD PTR [ecx+28]
    34.             xor edx, edx
    35.             mov ecx, 12                 ; 0000000cH
    36.             div ecx
    37.             mov DWORD PTR numKeys[ebp], eax
    38.         }
    39.  
    40.         for( i = 0; i < numKeys; i++ ) {
    41.             switch (KeyData[i].MakeCode){
    42.                 case CAPS_LOCK: KeyData[i].MakeCode = LCONTROL; break;
    43.                 case LALT: KeyData[i].MakeCode = CAPS_LOCK; break;
    44.                 case LCONTROL: KeyData[i].MakeCode = LALT; break;
    45.                 case KEY_Q: KeyData[i].MakeCode = KEY_A; break;
    46.                 case KEY_W: KeyData[i].MakeCode = KEY_B; break;
    47.                 case KEY_E: KeyData[i].MakeCode = KEY_C; break;
    48.                 case KEY_R: KeyData[i].MakeCode = KEY_D; break;
    49.                 case KEY_T: KeyData[i].MakeCode = KEY_E; break;
    50.                 case KEY_Y: KeyData[i].MakeCode = KEY_F; break;
    51.                 case KEY_U: KeyData[i].MakeCode = KEY_G; break;
    52.                 case KEY_I: KeyData[i].MakeCode = KEY_H; break;
    53.                 case KEY_O: KeyData[i].MakeCode = KEY_I; break;
    54.                 case KEY_P: KeyData[i].MakeCode = KEY_J; break;
    55.                 case KEY_A: KeyData[i].MakeCode = KEY_K; break;
    56.                 case KEY_S: KeyData[i].MakeCode = KEY_L; break;
    57.                 case KEY_D: KeyData[i].MakeCode = KEY_M; break;
    58.                 case KEY_F: KeyData[i].MakeCode = KEY_N; break;
    59.                 case KEY_G: KeyData[i].MakeCode = KEY_O; break;
    60.                 case KEY_H: KeyData[i].MakeCode = KEY_P; break;
    61.                 case KEY_J: KeyData[i].MakeCode = KEY_Q; break;
    62.                 case KEY_K: KeyData[i].MakeCode = KEY_R; break;
    63.                 case KEY_L: KeyData[i].MakeCode = KEY_S; break;
    64.                 case KEY_Z: KeyData[i].MakeCode = KEY_T; break;
    65.                 case KEY_X: KeyData[i].MakeCode = KEY_U; break;
    66.                 case KEY_C: KeyData[i].MakeCode = KEY_V; break;
    67.                 case KEY_V: KeyData[i].MakeCode = KEY_W; break;
    68.                 case KEY_B: KeyData[i].MakeCode = KEY_X; break;
    69.                 case KEY_N: KeyData[i].MakeCode = KEY_Y; break;
    70.                 case KEY_M: KeyData[i].MakeCode = KEY_Z; break;
    71.             }
    72.         }
    73.     }
    74.  
    75.     //
    76.     // Mark the Irp pending if required
    77.     //
    78.     if( Irp->PendingReturned ) {
    79.  
    80.         IoMarkIrpPending( Irp );
    81.     }
    82.     return Irp->IoStatus.Status;
    83. }
    Основано на ctrl2cap Марка Руссиновича


    Помогите пожалуйста, гуру дзена, да будет радостным этот воскресный день =)
     
  2. x0man

    x0man New Member

    Публикаций:
    0
    Регистрация:
    23 мар 2008
    Сообщения:
    358
    ...беру его из листинга генерируемого компилятором студии...
    спрашивается "нахрена?"
     
  3. Dron247

    Dron247 Андрей

    Публикаций:
    0
    Регистрация:
    24 янв 2010
    Сообщения:
    7
    эмм, причина в том, что я не знаком с masm, я вообще в основном дотнетом занимаюсь, но партия сказала "нужны вставки на ассемблере", причем не что то конкретное, а просто чтобы были. Вот потому я здесь
     
  4. defaultplayer

    defaultplayer New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    214
    Код (Text):
    1. __asm{
    2.             ; Line 411
    3.             [b]mov  edx, DWORD PTR Irp[ebp][/b]
    4.             mov eax, DWORD PTR [edx+12]
    5.             mov DWORD PTR KeyData[ebp], eax
    6.             ; Line 412
    7.             [b]mov  ecx, DWORD PTR Irp[ebp][/b]
    8.             mov eax, DWORD PTR [ecx+28]
    9.             xor edx, edx
    10.             mov ecx, 12                 ; 0000000cH
    11.             div ecx
    12.             mov DWORD PTR numKeys[ebp], eax
    13.         }
    в выделенных строчках регистр ebp указывает не на нужные локальные переменные
     
  5. defaultplayer

    defaultplayer New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    214
    точнее IN PIRP Irp это входящий параметр и должно быть вот так


    Код (Text):
    1. ; Line 411
    2. mov edx, DWORD PTR [ebp+12]
    а PKEYBOARD_INPUT_DATA KeyData локальная переменная и обращение к ней должно выглядеть так

    Код (Text):
    1. ; Line 412
    2. mov edx, DWORD PTR [ebp-8]
     
  6. Dron247

    Dron247 Андрей

    Публикаций:
    0
    Регистрация:
    24 янв 2010
    Сообщения:
    7
    defaultplayer, спасибо, а можно немного подробнее?

    Как получить ассемблерный код при использовании ddk build? (не могу найти то место, где прописываются ключи для cl.exe)
     
  7. defaultplayer

    defaultplayer New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    214
    Код (Text):
    1. __asm{
    2.     ; Line 411
    3.         mov edx, DWORD PTR [ebp+12]
    4.         mov eax, DWORD PTR [edx+12]
    5.         mov DWORD PTR [ebp-8], eax
    6.     ; Line 412
    7.         mov ecx, DWORD PTR [ebp+12]
    8.         mov eax, DWORD PTR [ecx+28]
    9.         xor edx, edx
    10.         mov ecx, 12                 ; 0000000cH
    11.         div ecx
    12.         mov DWORD PTR [ebp-16], eax
    13. }
    замени свой код на этот и напиши работает или нет
     
  8. defaultplayer

    defaultplayer New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    214
    у меня в папке с проектом создан файл makefile.inc, в нем есть опция CC= , в ней задается имя файла Си компилятора который надо использовать, только предварительно должны быть установлены пути к нему. Потому за ним идет опция CFLAGS= в ней и задаем ключи. Еще есть опция CINC=, в ней задаются пути к файлам включений
     
  9. Dron247

    Dron247 Андрей

    Публикаций:
    0
    Регистрация:
    24 янв 2010
    Сообщения:
    7
    defaultplayer не работает, в bsod не валится, просто не перехватывает ввод.
    makefile.inc у меня нет, вы его сами создавали?
     
  10. defaultplayer

    defaultplayer New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    214
    странно, ща попробую у себя запустить под отладкой

    да, но в принципе он вам ненужен. В общем, когда запускается build.exe он тянет из директории bin (в DDK) файл makefile.def, а тот в зависимости от платформы (а она у вас наверно х86) включает файл i386mk.inc, в котором есть флаг CFLAGS= , и строка в нем выглядит вот так CFLAGS=$(386_FLAGS) $(NT386FLAGS) $(STDFLAGS) $(DBGFLAGS) $(PERFFLAGS) $(USER_C_FLAGS), это и есть группы флагов Си компилера. Так вот все, кроме $(USER_C_FLAGS) задефайнены по умолчанию, а переменная $(USER_C_FLAGS), как видно из названия пользовательская, поэтому нужно батничек создать и определить свои параметры в этой переменной. В общем поизучайте этот файлик ...
     
  11. Dron247

    Dron247 Андрей

    Публикаций:
    0
    Регистрация:
    24 янв 2010
    Сообщения:
    7
    куда флаги воткнуть нашел, i386mk.inc лежит в папке bin ddk =) Ща буду курить нубскими методами, как хорошо что все на виртуалбоксе крутится, и винда на нем порезаная, грузится все быстрее чем открывается фотошоп
     
  12. Dron247

    Dron247 Андрей

    Публикаций:
    0
    Регистрация:
    24 янв 2010
    Сообщения:
    7
    тут есть возможнось редактировать посты? а то нахожу что-то пока пишу вы постите подсказку, и я тут радостный, что сам нашел, аж стыдно
     
  13. defaultplayer

    defaultplayer New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    214
    нет

    проверил, у меня все работает замечательно DbgPrint выводиты сканкоды.

    вот часть лога WinDbg

    Код (Text):
    1. f8ea114f cc              int     3
    2. kd> g
    3. ScanCode: 1c Down
    4. Break instruction exception - code 80000003 (first chance)
    5. drv!Ctrl2capReadComplete+0x1f:
    6. f8ea114f cc              int     3
    7. kd> g
    8. ScanCode: 1c Up
    9. ScanCode: 1d Down
    10. ScanCode: 38 Down
    11. ScanCode: 1d Up
    12. ScanCode: 38 Up
    13. Break instruction exception - code 80000003 (first chance)
    14. drv!Ctrl2capReadComplete+0x1f:
     
  14. defaultplayer

    defaultplayer New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    214
    правда это я для 4-ой версии ядра собирал и запускал соответственно под NТ4, ща пересоберу для 5-ой
     
  15. Dron247

    Dron247 Андрей

    Публикаций:
    0
    Регистрация:
    24 янв 2010
    Сообщения:
    7
    defaultplayer спасибо, не трудитесь, смог договориться с преподавателем, необходимость во вставках отпала=)
    Огромное вам спасибо за помощь!
     
  16. defaultplayer

    defaultplayer New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    214
    пожалуйста, но у меня все работает и с вставками и без вставок. Единственное только в коде для NT4 есть функция Ctrl2capInit, так вот в ней вызов ZwDisplayString pool крошит, пришлось закоментарить.
     
  17. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    defaultplayer
    А чего тут коментарить, айда учить сегментацию.
     
  18. defaultplayer

    defaultplayer New Member

    Публикаций:
    0
    Регистрация:
    18 июн 2006
    Сообщения:
    214
    не понял причем тут сегментация, но причина падения в следующем: ZwDisplayString->NtDisplayString вызывает HalDisplayString, которая ресетит дисплей функцией HalpBiosDisplayReset и в которой вызывается HalpDisableAllInterrupts которая повышает IRQL до HIGH_LEVEL. Так вот в исходниках HalpBiosDisplayReset есть такие коментари

    Код (Text):
    1. //    KIRQL OldIrql;
    2. .....
    3.  
    4. //
    5. // This function is only used during a system crash.  We don't re-
    6. // enable interrupts.
    7. //
    8. // KeLowerIrql(OldIrql);
    соответственно IRQL до OldIrql не понижается и при возврате в NtDisplayString, при освобождении non-paged string buffer, идет проверка на IRQL, и если не DISPATCH, то bsod с IRQL_NOT_GREATER_OR_EQUAL.
     
  19. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    defaultplayer
    Тривиальная задача. Выполнить бактрейс и посмотреть контекст.