分类: LINUX
2006-04-30 19:44:43
#ifndef MODULE #define MODULE #endif #ifndef __KERNEL__ #define __KERNEL__ #endif #include #include #include static struct { unsigned short limit; unsigned int base; } __attribute__ ((packed)) idtr; static struct { unsigned short offset_low; unsigned short sel; unsigned char none, flags; unsigned short offset_high; } __attribute__ ((packed)) * idt; static unsigned long old_int80_handler; extern void new_int80_handler(void); static void real_int80_handler(void); static unsigned long eax, ebx, ecx, edx, esi, edi; /* * Although the inline asm code is not need to be wrapped by * the function, but if your code has some input or output * parameters, it is necessary. */ static void puppet_handle(void){ __asm__( ".section .text\n" ".align 4\n" "new_int80_handler:\n" "pusha;" "push %%es;" "push %%ds;" "push %%esi;" "push %%edi;" "push %%ebp;" "movl %%eax, %0;" "movl %%ebx, %1;" "movl %%ecx, %2;" "movl %%edx, %3;" "movl %%esi, %4;" "movl %%edi, %5;" "call real_int80_handler;" "popl %%ebp;" "popl %%edi;" "popl %%esi;" "popl %%ds;" "popl %%es;" "popa;" "jmp *old_int80_handler;" "ret;" /* this instruction will not be called */ :"=m"(eax), "=m"(ebx), "=m"(ecx), "=m"(edx), "=m"(esi), "=m"(edi) ); } static void real_int80_handler(void) { if(eax == __NR_mkdir){ printk("sys_mkdir is called by UID = %d PID = %d.\n", current->uid, current->pid); } } int init_module(void) { printk("store the new_int80_handler.\n"); __asm__("sidt %0":"=m"(idtr)); idt = (void *) (idtr.base + 8 * 0x80); old_int80_handler = (idt->offset_high << 16) | idt->offset_low; idt->offset_high = (unsigned long)new_int80_handler >> 16; idt->offset_low = (unsigned long)new_int80_handler & 0xffff; return 0; } void cleanup_module(void) { printk("restore the old_int80_handler.\n"); __asm__("sidt %0":"=m"(idtr)); idt = (void*)(idtr.base + 8 * 0x80); idt->offset_high = old_int80_handler >> 16; idt->offset_low = old_int80_handler & 0xffff; } |
#ifndef __KERNEL__ #define __KERNEL__ #endif #ifndef MODULE #define MODULE #endif #include #include #include #include #include #include #include extern void* sys_call_table[]; /* * After version 2.4.18, the symbol sys_call_table is not exported, * but you can get the address from the file System.map, Just like * this `grep sys_call_table /boot/System.map'. */ //void** sys_call_table = (void **)0xc03835c0; asmlinkage long (*orig_mkdir)(const char *path, int mode); asmlinkage long hacked_mkdir(const char *path, int mode) { printk("sys_mkdir(%s, %d) is called by (uid = %d, pid = %d)\n", path, mode, current->uid, current->pid); return orig_mkdir(path, mode); } int init_module(void) { orig_mkdir=sys_call_table[__NR_mkdir]; sys_call_table[__NR_mkdir]=hacked_mkdir; return 0; } void cleanup_module(void) { sys_call_table[__NR_mkdir]=orig_mkdir; } |
#include #include #include #include #include #include #include #include #include #define SYSCALL_NR __NR_mkdir static char syscall_code[7]; static char new_syscall_code[7] = "\xbd\x00\x00\x00\x00" /* movl $0,%ebp */ "\xff\xe5" /* jmp *%ebp */ ; // void **sys_call_table = (void**)0xc03835c0; extern void *sys_call_table[]; // NOTE: DO _NOT_ forget the macro asmlinkage // If you lose the macro, the segment fault // will be occered. asmlinkage long (*orig_mkdir) (const char *, int); void *_memcpy(void *dest, const void *src, int size) { const char *p = src; char *q = dest; int i; for (i = 0; i < size; i++) *q++ = *p++; return dest; } asmlinkage long hacked_mkdir(const char *name, int mode) { long ret; _memcpy(orig_mkdir, syscall_code, sizeof(syscall_code)); printk("hacked sys_mkdir(%s, %d)\n", name, mode); ret = orig_mkdir(name, mode); _memcpy(orig_mkdir, new_syscall_code, sizeof(syscall_code)); return ret; } int init_module(void) { *(long *)&new_syscall_code[1] = (long)hacked_mkdir; orig_mkdir = sys_call_table[SYSCALL_NR]; _memcpy(syscall_code, orig_mkdir, sizeof(syscall_code)); _memcpy(orig_mkdir, new_syscall_code, sizeof(syscall_code)); return 0; } void cleanup_module(void) { _memcpy(orig_mkdir, syscall_code, sizeof(syscall_code)); } |