井研移动网站建设,用wordpress做个,wordpress获取页面链接,微信哪家公司开发的Linux内核版本2.6中已经不再导出系统调用符号表了。因此#xff0c;如果想实现劫持系统调用#xff0c;就得想办法找到系统调用表的地址。网上应该可以搜到相关的实现。我这里找到了albcamus兄的精华文章#xff0c;并在内核版本2.6.18.3上实践了其中的代码。这里总结一下。…Linux内核版本2.6中已经不再导出系统调用符号表了。因此如果想实现劫持系统调用就得想办法找到系统调用表的地址。网上应该可以搜到相关的实现。我这里找到了albcamus兄的精华文章并在内核版本2.6.18.3上实践了其中的代码。这里总结一下。本文欢迎自由转载但请标明出处和本文链接并保持本文的完整性。Dec 2, 2009一、代码及实现(一) 劫持open系统调用的代码内核态实现劫持系统调用的代码如下来自参考链接1即albcamus兄提供的代码。我这里屏蔽了一些代码仅实现了劫持open系统调用。#include#include#include#include#include#include#include#include#include#include#include#include#include#include#includeMODULE_DESCRIPTION(Intercept the systemcall table in Linux);MODULE_AUTHOR(alert7 (alert7xfocus.org)\n\t\talbcamus );MODULE_LICENSE(GPL);/* comment the following line to shut me up */#define INTERCEPT_DEBUG#ifdef INTERCEPT_DEBUG#define dbgprint(format,args...) \printk(intercept: function:%s-L%d: format, __FUNCTION__,__LINE__, ##args);#else#define dbgprint(format,args...)do {} while(0);#endif/*** the system call table*/void **my_table;unsigned int orig_cr0;/*** the original syscall functions*/asmlinkage long (*old_open) (char __user*filename, int flags, int mode);asmlinkage int(*old_execve) (struct pt_regs regs);/** do_execve and do_fork */unsigned int can_exec_fork 0;int(*new_do_execve) (char * filename,char __user *__user *argv,char __user *__user *envp,struct pt_regs * regs);struct idtr {unsigned short limit;unsigned int base;} __attribute__ ((packed));struct idt {unsigned short off1;unsigned short sel;unsigned char none, flags;unsigned short off2;} __attribute__ ((packed));#if 0/***checkif we can intercept fork/vfork/clone/execve or not**return: 0 for no, 1 for yes*/struct kprobe kp_exec;unsigned int can_intercept_fork_exec(void){intret 0;#ifndef CONFIG_KPROBESreturn ret;#endifkp_exec.symbol_name do_execve;ret register_kprobe(kp_exec);if(ret ! 0 ) {dbgprint(cannot find do_execve by kprobe.\n);return 0;}new_do_execve ( int (*)(char *,char __user * __user *,char __user * __user *,struct pt_regs *)) kp_exec.addr;dbgprint(do_execve at %p\n, (void *)kp_exec.addr);unregister_kprobe(kp_exec);return 1;}#endif/*** clear WP bit of CR0, and return the originalvalue*/unsigned int clear_and_return_cr0(void){unsigned int cr0 0;unsignedint ret;asmvolatile (movl %%cr0, %%eax: a(cr0));ret cr0;/*clear the 20 bit of CR0, a.k.a WP bit */cr0 0xfffeffff;asmvolatile (movl %%eax, %%cr0:: a(cr0));return ret;}/** set CR0 with new value** val : new value to set in cr0*/void setback_cr0(unsigned int val){asmvolatile (movl %%eax, %%cr0:: a(val));}/*** Return the first appearence of NEEDLE inHAYSTACK.* */static void *memmem(const void *haystack,size_t haystack_len,const void *needle, size_t needle_len){/*{{{*/constchar *begin;constchar *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 atthe beginning of the string.*/return (void *) haystack;/*Sanity check, otherwise the loop might search through the wholememory.*/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;}/*}}}*//*** Find the location of sys_call_table*/static unsigned long get_sys_call_table(void){/*{{{*//* well read first 100 bytes of int $0x80 */#define OFFSET_SYSCALL 100struct idtr idtr;struct idt idt;unsigned sys_call_off;unsigned retval;charsc_asm[OFFSET_SYSCALL], *p;/*well, lets read IDTR */asm(sidt %0:m(idtr)::memory );dbgprint(idtr base at 0x%X, limit at 0x%X\n, (unsignedint)idtr.base,(unsigned short)idtr.limit);/*Read in IDT for vector 0x80 (syscall) */memcpy(idt, (char *) idtr.base 8 * 0x80, sizeof(idt));sys_call_off (idt.off2 16) | idt.off1;dbgprint(idt80: flags%X sel%X off%X\n,(unsigned) idt.flags, (unsigned) idt.sel, sys_call_off);/* wehave syscall routine address now, look for syscall tabledispatch (indirect call) */memcpy(sc_asm, (void *)sys_call_off, OFFSET_SYSCALL);/***Search opcode of call sys_call_table(,eax,4)*/p (char *) memmem(sc_asm, OFFSET_SYSCALL, \xff\x14\x85, 3);if (p NULL)return 0;retval *(unsigned *) (p 3);if(p) {dbgprint(sys_call_table at 0x%x, call dispatch at 0x%x\n,retval, (unsigned int) p);}returnretval;#undef OFFSET_SYSCALL}/*}}}*//*** new_open - replace the original sys_open wheninitilazing,*as well as be got rid of when removed*/asmlinkage long new_open(char *filename, intflags, int mode){dbgprint(call open()\n);return old_open (filename, flags, mode);}/*** new_execve - you should change this functionwhenever the kernels sys_execve()* changes*/asmlinkage int new_execve(struct pt_regs regs){interror;char*filename;dbgprint(Hello\n);filename getname( (char __user *) regs.ebx );error PTR_ERR(filename);if (IS_ERR(filename) )goto out;dbgprint(file to execve: %s\n, filename);error new_do_execve(filename,(char __user * __user *)regs.ecx,(char __user * __user *)regs.edx,regs);if(error 0) {task_lock(current);current-ptrace ~PT_DTRACE;task_unlock(current);set_thread_flag(TIF_IRET);}putname (filename);out:return error;}static int intercept_init(void){my_table (void **)get_sys_call_table();if(my_table NULL)return -1;dbgprint(sys call table address %p\n, (void *) my_table);#define REPLACE(x) old_##x my_table[__NR_##x];\my_table[__NR_##x] new_##xREPLACE(open);#if 0can_exec_fork can_intercept_fork_exec();if(can_exec_fork 1)REPLACE(execve);#endif#undef REPLACEreturn 0;}static int __init this_init(void){intret;printk(syscall intercept: Hi, poor linux!\n);orig_cr0 clear_and_return_cr0();ret intercept_init();setback_cr0(orig_cr0);return ret;}static void __exit this_fini(void){printk(syscall intercept: bye, poor linux!\n);#define RESTORE(x) my_table[__NR_##x] old_##xorig_cr0 clear_and_return_cr0();RESTORE(open);#if 0if(can_exec_fork 1)RESTORE(execve);#endifsetback_cr0(orig_cr0);#undef RESTORE}module_init(this_init);module_exit(this_fini);(二) 编译及实践Makefile如下obj-m:hack_open.oEXTRA_CFLAGS :-Dsymnamesys_call_tableKDIR: /lib/modules/$(shell uname -r)/buildPWD: $(shell pwd)default:make -C $(KDIR) SUBDIRS$(PWD) modulesclean:rm -rf .*.cmd *.mod.c *.o *.ko .tmp**.symvers编译之后加载模块然后查看日志信息Sep 24 19:06:49localhost kernel: intercept: function:get_sys_call_table-L220: sys_call_tableat 0xc11f14e0, calldispatch at 0xcebeceaaSep 24 19:06:49 localhost kernel: intercept: function:intercept_init-L276: syscall table address c11f14e0Sep 24 19:06:50 localhost kernel: intercept: function:new_open-L234: helloSep 24 19:07:00 localhost last message repeated 460 times可见open系统调用执行次数之频繁。--未完待续