- 论坛徽章:
- 1
|
#include <linux/limits.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/moduleparam.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <net/sock.h>
#include <net/datalink.h>
#include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/types.h>
#include <linux/ctype.h>
#include <linux/netlink.h>
#include <linux/signal.h>
#include <linux/file.h>
#include <linux/utsname.h>
#include <linux/pid.h>
#include <linux/fs_struct.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/pagemap.h>
#include <linux/fs.h>
#include <linux/path.h>
#include <linux/tty.h>
#include <linux/completion.h>
void **syscall_table;
struct {
__u32 pid;
rwlock_t lock;
}user_proc;
static int g_var = 0;
static int test(char *p)
{
int i = 0, ret = 0, flag = 0 ;
char str[1 + 1] = {0};
strncpy(str, "1", 1);
while(i < g_var)
{
strncpy(str, "1", 1);
}
return 0;
}
asmlinkage int (*original_call_1)(const char*, const char*);
asmlinkage int my_rename(const char *oldname,const char *newname)
{
int ret = 0;
char filename[1 + 1] = {0};
ret = test(filename);
return original_call_1(oldname,newname);
}
asmlinkage int (*original_call)(unsigned int, const char*, size_t);
asmlinkage int my_write(unsigned int fd,const char *buf,size_t count)
{
char p[1 + 1] = {0};
int ret = 0;
ret = test(p);
if(-1 == ret )
{
if(0 == strcmp(current->comm, "cp"))
ret = 0;
return ret;
}
return original_call(fd,buf,count);
}
/**
* clear WP bit of CR0, and return the original value
*/
unsigned long clear_and_return_cr0(void)
{
unsigned long cr0 = 0;
unsigned long ret;
asm volatile ("movq %%cr0, %0"
: "=a"(cr0)
);
ret = cr0;
/* clear the 20 bit of CR0, a.k.a WP bit */
cr0 &= ~0x10000LL;
//cr0 &= 0xfffeffff;
asm volatile ("movq %0, %%cr0"
:
: "a"(cr0)
);
return ret;
}
/** set CR0 with new value
*
* @val : new value to set in cr0
*/
void setback_cr0(unsigned long val)
{
asm volatile ("movq %0, %%cr0"
:
: "a"(val)
);
}
/**
* Return the first appearence of NEEDLE in HAYSTACK. -- copied from PHRACK
* */
static void *memmem(const void *haystack, size_t haystack_len,
const void *needle, size_t needle_len)
{/*{{{*/
const char *begin;
const char *const last_possible
= (const char *) haystack + haystack_len - needle_len;
if (needle_len == 0)
/* The first occurrence of the empty string is deemed to occur at
the beginning of the string. */
return (void *) haystack;
/* Sanity check, otherwise the loop might search through the whole
memory. */
if (__builtin_expect(haystack_len < needle_len, 0))
return NULL;
for (begin = (const char *) haystack; begin <= last_possible;
++begin)
if (begin[0] == ((const char *) needle)[0]
&& !memcmp((const void *) &begin[1],
(const void *) ((const char *) needle + 1),
needle_len - 1))
return (void *) begin;
return NULL;
}/*}}}*/
static unsigned long get_syscall_table_long(void)
{/*{{{*/
#define OFFSET_SYSCALL 150
unsigned long syscall_long, retval;
char sc_asm[OFFSET_SYSCALL];
rdmsrl(MSR_LSTAR, syscall_long);
printk("long mode: system_call is at %p\n", (void *)syscall_long);
memcpy(sc_asm, (char *)syscall_long, OFFSET_SYSCALL);
retval = (unsigned long) memmem(sc_asm, OFFSET_SYSCALL, "\xff\x14\xc5", 3);
if ( retval != 0 ) {
printk("long mode : sys_call_table is at %p\n",
(void *) (* (unsigned long *)(retval+3)) ) ;
retval = (unsigned long) ( * (unsigned long *)(retval+3) );
retval = retval | 0xffffffff00000000;
printk("sys_call_table is at %lu\n", retval);
} else {
printk("long mode : memmem found nothing, returning NULL \n");
retval = 0;
}
#undef OFFSET_SYSCALL
return retval;
}/*}}}*/
static int mymod_init(void)
{
unsigned long orig_cr0 = clear_and_return_cr0();
syscall_table = (void **)get_syscall_table_long();
original_call = (asmlinkage int(*)(unsigned int,const char*, size_t))syscall_table[__NR_write];
syscall_table[__NR_write] = (int*)my_write;
//original_call_1 = (asmlinkage int(*)(const char *, const char *))syscall_table[__NR_rename];
//syscall_table[__NR_rename] = (int*)my_rename;
setback_cr0(orig_cr0);
rwlock_init(&user_proc.lock);
return 0;
}
static void mymod_exit(void)
{
unsigned long orig_cr0 = clear_and_return_cr0();
syscall_table[__NR_write] = original_call;
//syscall_table[__NR_rename] = original_call_1;
setback_cr0(orig_cr0);
}
module_init(mymod_init);
module_exit(mymod_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("zzz");
MODULE_DESCRIPTION("hi");
|
|