Реферат: Кейлоггер под MS-DOS

}

int main()

{

oldhdl=getvect(0x09); //Запоминаем старый обработчик прерывания нумбер 0x09 (т.е. от клавы)

setvect(0x09, newhdl); //Ставим новый обработчик (на то же прерывание)

keep(0, _SS+(_SP/16)-_psp);

return 0;

}

Как видишь, изменились 3 строки: я добавил глобальное объявление двух очень важных переменных, ну и саму функцию keep(). Переменные эти определяют, сколько памяти резервировать для проги (куча и стек соответственно). Необходимо ставить как можно меньше, но так, что бы прога не глючила и работала. Дело в том, что резиденты лежат в памяти всегда, и если они сожрут её слишком много, ничего будет не запустить (возможно, что и command.com). Я поставил 1024. Далее мы видим функцию keep(). Первый её параметр - код разв... возврата. У меня, как и у вас, это - ноль. Затем идут strange letters, которые всего-лишь говорят, сколько памяти должно быть зарезервировано: _psp (Program Sement Prefix) - адрес начала нашей программы, _SS (Stack Segment) - сегмент стека, _SP (Stack Pointer) - указатель вершины стека. Конец нашей программы - это адрес вершины стека. На самом деле такое вычисление может оказаться не точным. Можно попробовать такой вариант: _SS + (_SP + запас_памяти) / 16 - _psp. Вот теперь половина готова. В общем-то прога уже будет работать, а для проверки можно вместо "//..." написать что-нибудь вроде sound(2600); delay(50); nosound();. Надеюсь, все поняли, что я имею в виду. При каждом срабатывании прерывания 0x09 будет короткий сигнал в спикере компа. Кстати, девятое прерывание срабатывает не только тогда, когда клавишу нажимают, но и когда её отпускают.

Пишим. Компилируем. Выходим из Borland C. Запускаем прогу. Если ничего не получилось, попробуйте ещё раз. Если опять не получилось, возможны варианты: 1) вы допустили ошибку, и 2) настройки компилятора не позволяют откомпилить прогу. В любом случае, читайте мануалы. И ещё одна вещь - не пытайтесь запускать подобные проги прямо из компилятора (Ctrl+F9), он всё равно вернёт все изменения в системе назад (в т.ч. и обработчики прерываний).

ЧАСТЬ 3. Мутим кейлоггер

Хорошо. Большую часть сделали. Теперь превратим это в нормальный кейлоггер. Для начала нам необходимо определить, какая именно клавиша была нажата. Результаты будут соответствовать не обычным кодам в соответствии с кодовой страницей (т.е. 'A'=65, 'B'=66...) а специальным, которые возвращает нам система, и которые уже потом переводятся в обычные. Например, код нажатой клавиши Esc будет равен единице. Почему я сказал именно "нажатой"? Потому, что если клавиша не нажата, то мы определяем последнюю нажатую. Код Esc в отпущенном состоянии равен 128 (если ничего не перепутал). Коды эти мы узнаём ассемблерской инструкцией in. В стандартных библиотеках С можно найти функции inport() и inportb(), которые реализуют эту инструкцию. Выглядит это так:

char symbol;

symbol = inportb(0x60); //0x60 - номер порта для считывания нажатых клавиш

Теперь, в переменной symbol будет лежать значение кода клавиши на момент выполнения inportb(). Остаётся только взять, и записать эту ботву в файл. Но не всё так просто...

ЧАСТЬ 4. Пишем в файл

Если вы думаете, что fwrite(&symbol, sizeof(symbol), 1, outfile) и всё в шоколаде, то вы заблуждаетесь. Нет, в принципе, иногда это будет работать (в консольке в виндах, например). Но в реальном режиме процессора и MS-DOSа мало вероятно. Где же здесь собака порылась? Я, в поисках той собаки, решил порыться в мануалах... Есть тут такая мутная штука, под названием "двадцать восьмое прерывание". Вычитал я такую вещь, что из некоторых обработчиков прерываний нельзя производить, например, запись на диск, чего не скажешь о 0x28. Вот почему: дело в том, что при попытке записи вызывается прерывание 0x21. Может быть вариант, что мы вызовем 0x21 находясь в нём же, что не есть хорошо (это называется нереентерабельностью). А из двадцать восьмого и на диск писать можно, и читать, и всё, что угодно. Вызывается оно нашим MS-DOSом в благоприятные для него времена. Тем не менее, для полной уверенности, что мы находимся в безопасной секции, можно ещё использовать недокументированную функцию DOS AH=0x34 и определение флага занятости ДОС. Флаг будет находиться по адресу ES:BX и принимать значение 1 если секция нереентерабельна. Истина где-то рядом... Пишем ещё один обработчик для 0x28. В нашем обработчике 0x09 ставим флаг в единичку, если нам надо записать symbol. Каждый раз, при вызове DOSом нашего обработчика 0x28, он будет проверять флаг. Если последний равен 1, то, если флаг занятости позволяет, пишем наш symbol в файл и ставим флаг обратно в ноль. Вот и всё.

void interrupt far newhdl_28(...) // Новый обработчик для прерывания 0x28

{

if(flag == 1) // Если флаг равен 1, тогда нужно писать в файл

{

// ... (пишем в файл, при этом можем ещё и флаг занятости ДОСа проверить, на всякий пожарный)

flag = 0; // ясен пень - флаг снова надо сбросить

// (но только если нам удалось записать символ)

}

oldhdl_28(); // Вызываем следующий обработчик 0x28

}

void interrupt far newhdl(...) // Новый обработчик для прерывания 0x09 (клава)

{

symbol = inportb(0x60); // Читаем символ

flag = 1; // Ставим флаг в единицу (то есть даём "двадцать восьмому"

К-во Просмотров: 446
Бесплатно скачать Реферат: Кейлоггер под MS-DOS