Посимвольное чтение клавиатуры

Тема в разделе "WASM.BEGINNERS", создана пользователем Коцит, 27 апр 2017.

  1. Коцит

    Коцит Active Member

    Публикаций:
    0
    Регистрация:
    31 янв 2017
    Сообщения:
    130
    Всем привет! Столкнулся в ассемблере с такой проблемой..
    В виндовой консоли нужно обработать каждое нажатие клавиш. Возможно-ли такое средствами API ? Задача: зашифровать на-лету каждый символ юзерского ввода (пароль).

    Испробовал несколько стандартных функций типа "WriteConsole/Scanf/_lread", но они/все пишут в буфер и ждут маркера конца "Enter". Причём если передать им в качестве параметра счётчик макс.символов например(8), то при вводе бОльшего кол-ва символов - хвост символов остаётся в буфере клавиатуры, и при повторном вызове этой-же функции, записывается в указанный буфер функции.

    Например в досе можно выставить СХ=8 и сервисом DOS AH=1 про'LOOP'ить ввод, и благополучно выйти из цикла. Как такое организовать под виндой? Считать один символ с клавы в регистр, и закончить ввод без "Enter".
    Был-бы признателен..
     
  2. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    631
    Адрес:
    Russia
    вот сорец кейлоггера, посмотри как в нем реализовано.

    ( в винде сразу много задач выполняется, поэтому работа с клавиатурой реализуется иначе. into the rabbit hole -> http://opensecuritytraining.info/Keylogging_files/The Adventures of a Keystroke.pdf )
     

    Вложения:

    Последнее редактирование: 27 апр 2017
    Коцит нравится это.
  3. Коцит

    Коцит Active Member

    Публикаций:
    0
    Регистрация:
    31 янв 2017
    Сообщения:
    130
    _edge спасибо! Но чёт не получается заточить код под себя
    Делаю так. Подправь, если не в лом..
    Код (ASM):
    1.  
    2. format PE console
    3. include 'win32ax.inc'
    4.  
    5. .code
    6. start: mov esi,7
    7. @go: invoke Sleep,
    8. cmp   esi,255
    9. je start
    10. inc esi
    11. invoke GetAsyncKeyState,esi
    12. or eax,eax
    13. jnz @jop
    14. jmp @go
    15.  
    16. @jop: invoke MapVirtualKey,esi,2
    17. ; mov bl,al
    18. ; sub bl,30h
    19. ; cmp bl,9
    20. ; ja @go
    21. xor al,[key]
    22. add [pass],al
    23. dec byte[key]
    24. dec byte[len]
    25. jnz @go
    26.  
    27. ; cinvoke printf, form, pass
    28. ; cinvoke scanf
    29. invoke ExitProcess,0
    30. ;**********************************************
    31. .data
    32. key db 0DAh
    33. pass db 9 dup(0)
    34. len db 8
    35. form db '%c',0
    36. ;**********************************************
    37. section '.idata' import data readable writeable
    38. library kernel, 'KERNEL32.DLL',\
    39. user, 'USER32.DLL',\
    40. msvcrt, 'msvcrt.dll'
    41.  
    42. import kernel,\
    43. Sleep, 'Sleep',\
    44. ExitProcess, 'ExitProcess'
    45.  
    46. import user,\
    47. GetAsyncKeyState, 'GetAsyncKeyState',\
    48. MapVirtualKey, 'MapVirtualKeyA'
    49.  
    50. import msvcrt,\
    51. printf, 'printf',\
    52. scanf, 'scanf'
    53.  
     
  4. renibowot

    renibowot New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2017
    Сообщения:
    4
    1. go: invoke Sleep,
     
    _edge нравится это.
  5. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    631
    Адрес:
    Russia
    renibowot, у вас отняли клавиатуру? ) напишите ответ нормально пжл.
     
    Aiks нравится это.
  6. renibowot

    renibowot New Member

    Публикаций:
    0
    Регистрация:
    19 апр 2017
    Сообщения:
    4
    я хз, мож он ошибочно как то запостил но в "invoke Sleep," явно чего не хватает
     
    _edge нравится это.
  7. _edge

    _edge Well-Known Member

    Публикаций:
    1
    Регистрация:
    29 окт 2004
    Сообщения:
    631
    Адрес:
    Russia
    Коцит, к сожалению, пока не могу помочь работающим кодом, но вот что обнаружил - вызов, к примеру, printf портит регистры. Это может изменять поведение программы, если printf используется где-нибудь в цикле. То есть имеет смысл обрамлять вызовы printf командами pusha / popa.
     
    Последнее редактирование: 5 май 2017
  8. Orbit

    Orbit Member

    Публикаций:
    0
    Регистрация:
    13 дек 2016
    Сообщения:
    110
    Адрес:
    г. Москва
    Возьми готовую корпоративную совтину
     
  9. Коцит

    Коцит Active Member

    Публикаций:
    0
    Регистрация:
    31 янв 2017
    Сообщения:
    130
    renibowot, там единичка не скопировалась с исходника в пост.

    _edge, >> printf портит регистры.
    'printf' я туда добавил чисто для наглядности, чтоб видеть результат.
    Поэтому я его закоментировал, и результат тот-же. Цикл организовал через переменную, но код возвращает или несколько нажатий за одну итерацию цикла, или вообще тупо тормозит.

    И вообще, от куда внутри цикла попадает в ESI код клавиши?
    При вызове 'MapVirtualKey' в мл.байте ESI уже лежит код нажатой клавиши,
    и думаю это API вообще в моём случае не нужна.

    Правда отлаживал код в "Оле", а она не возвращает нажатие, пока не сравняешь/нажмёшь клавишу, которая в данный момент равна счётчику(ESI). Например, если нажать в Оле на пробел, когда ESI внутри цикла станет 20h, то срабатывает 'GetAsyncKeyState' и EAX становится единицей. В этот момент в ESI уже лежит код нажатой клавиши, который передаётся в 'MapVirtualKey'. Здесь я и забуксовал..

    Orbit, мне не нужна готовая софтина, т.к. это чисто в багаж личных знаний, на будующее.
     
  10. Orbit

    Orbit Member

    Публикаций:
    0
    Регистрация:
    13 дек 2016
    Сообщения:
    110
    Адрес:
    г. Москва
    На бедующее мне казалось всегда что лучше криптор написать
     
  11. Argogo

    Argogo New Member

    Публикаций:
    0
    Регистрация:
    15 сен 2008
    Сообщения:
    5
    Адрес:
    Республика Крым
    Коцит нравится это.
  12. Коцит

    Коцит Active Member

    Публикаций:
    0
    Регистрация:
    31 янв 2017
    Сообщения:
    130
    Argogo,
    чёто у меня не получается задать режим со-сброшеным флагом "ENABLE_LINE_INPUT"
    Оля выдаёт ошибку: "ERROR_INVALID_PARAMETER (00000057)"
    может я неправильно что-то делаю? Был-бы рад примеру на FASM'e..
    Пытаюсь сделать так:
    Код (ASM):
    1.  
    2. ;....
    3. section '.text' code readable executable
    4.  
    5. start:  invoke  GetStdHandle, -11  ; дескрипторы консоли
    6.   mov  [stdOut], eax  ; монитор
    7.   invoke  GetStdHandle, -10  ;  ..и клава
    8.   mov  [stdIn], eax  ;
    9.  
    10.   invoke  SetConsoleMode,[stdIn],0F5h
    11. ;....
    12.  
    И почему-то мой Фасм в упор не воспринимает параметры в текстовом виде.
    Если задаю константы, то всё компилит нормально.

    Сначала считал режим через "GetConsoleMode", который вернул мне моду со-значением(F7h).
    Опытным путём в окне отладчика получил такие значения флагов:
    Код (Text):
    1.  
    2. Mode(FF) = 1111 1111
    3. -----------------------------
    4. ENABLE_PROCESSED_INPUT/OUTPUT  = бит(0)
    5. ENABLE_LINE_INPUT/WRAP_AT_EOL  = бит(1)
    6. ENABLE_ECHO_INPUT  = бит(2)
    7. ENABLE_WINDOW_INPUT  = бит(3)
    8. ENABLE_MOUSE_INPUT |E0  = бит(4)
    9.  
    По сути, старшие 3-бита погоду не делают, и 1Fh возвращает такую-же моду.
    Теперь, сбрасываю биты(1-3) и Ольга показывает, что "ENABLE_LINE_INPUT" исчез из списка, но 'SetConsoleMode' возвращает ошибку:
    Код (Text):
    1.  
    2. Mode(F5) = 1111 0101
    3. -----------------------------
    4. ENABLE_PROCESSED_INPUT/OUTPUT  = бит(0)
    5. ENABLE_ECHO_INPUT  = бит(2)
    6. ENABLE_MOUSE_INPUT |E0  = бит(4)
    7.  
    Остальные все флаги сбрасываются без ошибки, только 'Line_Input' глючит.
    И вообще подозреваю, что эта функция тоже будет писАть в буфер (а не в регистр), только по одному символу за-раз. Хотя, нужно проверить.. Спасибо за идею!
     
  13. Argogo

    Argogo New Member

    Публикаций:
    0
    Регистрация:
    15 сен 2008
    Сообщения:
    5
    Адрес:
    Республика Крым
    Коцит, в FASM'е я не копенгаген, вот мой пример для MASM'а, ожидание нажатия клавиши:
    Код (Text):
    1.  
    2. ;================================\
    3. ConsolePause    PROC    NEAR
    4.                 push    ebp
    5.                 mov     ebp, esp
    6.                
    7.                 push    STD_INPUT_HANDLE
    8.                 call    GetStdHandle
    9.                 push    eax
    10. @@dHinp         equ     [ebp-1*4]
    11.                 push    0
    12.                 push    @@dHinp
    13.                 call    SetConsoleMode
    14.                 push    @@dHinp
    15.                 call    FlushConsoleInputBuffer
    16.                
    17.                 push    0
    18. @@dReaded       equ     [ebp-2*4]
    19.                 push    0
    20. @@bBuffer       equ     [ebp-3*4]
    21.                
    22.                 push    0
    23.                 lea     eax, @@dReaded
    24.                 push    eax
    25.                 push    1
    26.                 lea     eax, @@bBuffer
    27.                 push    eax
    28.                 push    @@dHinp
    29.                 call    ReadConsoleA
    30.                 leave
    31.                 ret
    32.                 nop
    33. ConsolePause    ENDP
    34. ;================================\
    35.