Снова проблемы с имитацией ввода[NtUserSendInput]

Тема в разделе "WASM.WIN32", создана пользователем punxer, 30 сен 2010.

  1. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Доброго времени суток. Имеется код, написанный не без помощи форумчан:

    Код (Text):
    1. void GenerateKeyService ( WORD vk)
    2. {
    3.  
    4.     INPUT       inpt[1];
    5.     DWORD64     tmpXMM0;
    6.     int         ret;
    7.  
    8.     __asm movq [tmpXMM0], xmm0;
    9.  
    10.     inpt[0].type=INPUT_KEYBOARD;
    11.     inpt[0].ki.wVk=vk;
    12.     inpt[0].ki.time=NULL;
    13.     inpt[0].ki.dwExtraInfo=GetMessageExtraInfo();
    14.     inpt[0].ki.wScan=   MapVirtualKey(vk, 0);
    15.     inpt[0].ki.dwFlags=NULL;
    16.  
    17.     inpt[1].type=INPUT_KEYBOARD;
    18.     inpt[1].ki.wVk=vk;
    19.     inpt[1].ki.time=NULL;
    20.     inpt[1].ki.dwExtraInfo=GetMessageExtraInfo();
    21.     inpt[1].ki.wScan=   MapVirtualKey(vk, 0);
    22.     inpt[1].ki.dwFlags=KEYEVENTF_KEYUP;
    23.  
    24.     ret=SendInputServiceCall_sysenter(2,&inpt[0],sizeof(inpt));
    25.     DebugPrintF("ret=SendInputServiceCall_sysenter=%x",ret);
    26.    
    27.  
    28.  
    29.    
    30.  
    31.  
    32.     __asm movq xmm0, [tmpXMM0];
    33.     return;
    34. }
    Код (Text):
    1. int SendInputServiceCall_sysenter (UINT Count, LPINPUT Input, int SizeInput)
    2. {
    3.     __asm
    4.     {
    5.         mov eax, NtUserSendInput
    6.         push SizeInput
    7.         push Input
    8.         push Count
    9.         push eax    ; просто заполнитель до -8
    10.         push aa
    11.         mov edx, esp
    12.         sysenter
    13. aa:
    14.         add esp, 16    ; очистка стека от временных переменных
    15.     }
    16. }
    Самое странное что вообще работает, так как размерность массива должна быть 2

    Код (Text):
    1. INPUT       inpt[2];
    Но отрабатывает только один раз с каждой кнопкой, второй раз послать VK_RETURN, например, не получится.
    Может кто нибудь подсказать в чем может быть проблема?

    как это понимать?

    Как напрямую работать с очередью ввода потока? Есть ли возможность привести ее в изначальное состояние из R3?

    P.S.
    Простите, знаю что достал уже, но вопреки всем мануалам и ковыряниям, всего, чего удалось добиться,-это однократного нажатия каждой из кнопок виртуальной клавы(
     
  2. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    punxer
    Дык чёткая постановка задачи - половина её решения :))
    Ты начал с того, что тебе нужно реверснуть SendInput, которая "работает но не стабильно в условиях чужого навороченного приложения", потом захотел написать к ней свой заменитель (хотя нет никакой разницы кем вызывается сервис, если он вызывается корректно)...
    И только теперь выясняется, что на самом деле тебе нужно не это, а разобраться в том как эту SendInput правильно применять :))

    Начни с того, чтобы понажимать кнопки в своей простейшей проге, просто выводящей на экран все действия с кнопками, сразу увидишь что доходит, а что теряется, потом понажимай _своё_ меню с горячими клавишами, потом переходи к стандартному win калькулятору, а уж там и в чужое грандиозное приложение наработанный код переноси ;)

    Имхо 99% что SendInput у тебя работает "не так" из-за какой-то очень мелкой и нелепой ошибки, которую ты быстро обнаружишь отладчиком в своей тестовой программе и все "суперзаменители", в том числе сбрасывающие очередь нажатий из R3 окажутся ненужны ;)
     
  3. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Y_Mur
    спасибо конечно, но раньше таких проблем не возникало и все что ты написал я успешно делал(
    сейчас вроде работает только так, ппц


    Код (Text):
    1. void GenerateKeyService ( WORD vk)
    2. {
    3.  
    4.     INPUT       inpt[1];
    5.     DWORD64     tmpXMM0;
    6.     int         ret;
    7.  
    8.     __asm movq [tmpXMM0], xmm0;
    9.  
    10.     inpt[0].type=INPUT_KEYBOARD;
    11.     inpt[0].ki.wVk=vk;
    12.     inpt[0].ki.time=NULL;
    13.     inpt[0].ki.dwExtraInfo=GetMessageExtraInfo();
    14.     inpt[0].ki.wScan=   MapVirtualKey(vk, 0);
    15.     inpt[0].ki.dwFlags=NULL;
    16.  
    17.     inpt[1].type=INPUT_KEYBOARD;
    18.     inpt[1].ki.wVk=vk;
    19.     inpt[1].ki.time=NULL;
    20.     inpt[1].ki.dwExtraInfo=GetMessageExtraInfo();
    21.     inpt[1].ki.wScan=   MapVirtualKey(vk, 0);
    22.     inpt[1].ki.dwFlags=KEYEVENTF_KEYUP;
    23.  
    24.     ret=SendInputServiceCall_sysenter(2,&inpt[0],sizeof(inpt));
    25.     DebugPrintF("ret=SendInputServiceCall_int2e=%x",ret);
    26.    
    27.     //kill me
    28.     keybd_event((BYTE)vk,NULL,NULL,NULL);
    29.     keybd_event((BYTE)vk,NULL,KEYEVENTF_KEYUP,NULL);
    30.    
    31.  
    32.  
    33.     __asm movq xmm0, [tmpXMM0];
    34.     return;
    35. }