Модуль убит при записи в таблицу вызовов sys - PullRequest
0 голосов
/ 20 октября 2018

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

int init_module(void)
{
  // set rw/ro functions
  patch_set_memory_rw = (void *) kallsyms_lookup_name("set_memory_rw");
  patch_set_memory_ro = (void *) kallsyms_lookup_name("set_memory_ro");

  if( patch_set_memory_rw == NULL ||
      patch_set_memory_ro == NULL){
    // something went wrong
    printk(KERN_ALERT "ERROR WITH RW/RO!");
    return 1;
  }
  // Inform that module is staring
  //printk(KERN_INFO "Start Hook Read.");
  syscall_table_pu64 = (void **)kallsyms_lookup_name("sys_call_table");

  //for debugging
  //printk(KERN_ALERT "syscall addr is %llx", syscall_table_pu64);


  // swap read call with own read function
  orig_read_p = syscall_table_pu64[__NR_read];
  // set memory rw to change it
  patch_set_memory_rw((uint64_t)syscall_table_pu64, 1);
  syscall_table_pu64[__NR_read] = own_read_func;
  return 0;
}

Ошибка происходит в строке

syscall_table_pu64[__NR_read] = own_read_func;

Кто-нибудь знает, в чем моя проблема?Я не могу понять это.Сообщения об ошибках

RIP: init_module+0x76/0xa0 [hook_read] RSP: ffffa4ad46233c70

и

RIP: 0033:0x7f01920bb839
[ 3476.855557] RSP: 002b:00007fffcc925288 EFLAGS: 00000246 ORIG_RAX: 0000000000000139
[ 3476.857431] RAX: ffffffffffffffda RBX: 0000559daa9f6790 RCX: 00007f01920bb839
[ 3476.858902] RDX: 0000000000000000 RSI: 0000559daa012c2e RDI: 0000000000000003
[ 3476.860550] RBP: 0000559daa012c2e R08: 0000000000000000 R09: 00007f019238e000
[ 3476.861959] R10: 0000000000000003 R11: 0000000000000246 R12: 0000000000000000
[ 3476.863399] R13: 0000559daa9f6760 R14: 0000000000000000 R15: 0000000000000000
[ 3476.864747] Code: 89 05 d7 22 00 00 48 8b 10 48 89 c7 be 01 00 00 00 48 8b 05 d5 22 00 00 48 89 15 b6 22 00 00 e8 71 3f 26 e2 48 8b 05 b2 22 00 00 <48> c7 00 00 f0 59 c0 31 c0 5d c3 48 c7 c7 40 00 5a c0 e8 f3 f1 

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Таблица системных вызовов доступна только для чтения.Не пытайтесь изменить его.

Если вы хотите перехватить операции чтения / записи, вам нужно будет выбрать другой способ сделать это.Один из механизмов, который вы можете захотеть изучить, - это система kprobes .

0 голосов
/ 22 октября 2018

Я наконец понял свою проблему.Чтобы снять защиту от записи с системного вызова, вы (конечно) не можете использовать системный вызов Linux: D У меня ушло 3 часа, чтобы понять это.Вместо этого используйте

write_cr0 (read_cr0 () & (~ 0x10000));

, чтобы включить запись, и

write_cr0 (read_cr0 () | 0x10000);

, чтобы снова сделать вашу память доступной только для чтения.

...