文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>sys_call_table的问题(转)

sys_call_table的问题(转)

时间:2010-07-28  来源:chenye2865

CSDN上linux内核这板块人貌似不是很多嘛。。。

经过上网搜索,终于知道为什么程序会出现段错误,原来系统调用的函数地址是只读的,所以当向其赋我们自己写的hack_mkdir的时候就好报错。解决此问题需要将cr0寄存器的写保护去掉。具体可参见此贴http://linux.chinaunix.net/bbs/thread-909712-1-1.html

网上关于截获系统调用的文章一搜一大堆,不过一看就是你抄我我吵呢,有的标榜调试通过,可是还不是自己调时就会出现段错误。真不知道那些人是怎么调的。下面我贴出一段代码是我刚刚调试通过的,加载模块后mkdir命令就形同虚设了

C/C++ code

#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/unistd.h>
#include <linux/sched.h>

unsigned long *sys_call_table = NULL;
static unsigned int origcr0 = 0;

asmlinkage int (*orig_mkdir)(const char*,int mode);

unsigned long orig_mkdir_address  = 0;

struct idt_tag
{
    unsigned short offset_low,segment_select;
    unsigned char reserved,flags;
    unsigned short offset_high;
};

unsigned int clear_and_return_origCR0(void)
{
    unsigned int cr0 = 0;
    unsigned int ret = -1;
    
    __asm__ __volatile__ (
        "movl %%cr0,%%eax"
        :"=a"(cr0)
    );
    ret = cr0;
    cr0 = cr0 & 0xfffeffff;

    __asm__ __volatile__ (
        "movl %%eax,%%cr0"
        ::"a"(cr0)
    );
    return ret;
}

void setbackCR0(unsigned int pCR0)
{
    __asm__ __volatile__ (
        "movl %%eax,%%cr0"
        ::"a"(pCR0)
    );
}

static unsigned long getSyscallTable(void)
{
    unsigned char idtr[6],*shell,*sort;
    struct idt_tag *idt;
    unsigned long system_call,sct;
    unsigned short offset_low,offset_high;
    char *p;
    int i;
    __asm__("sidt %0":"=m"(idtr));
    idt = (struct idt_tag*)((*(unsigned long*)&idtr[2]) + 8 * 0x80);
    offset_low = idt->offset_low;
    offset_high = idt->offset_high;
    system_call = (offset_high)<<16 | offset_low;    
    shell = (char*)system_call;
    sort = "\xff\x14\x85";

    for(i = 0;i < 100-2;i++)
        if(shell [ i ] == sort[0] && shell[i+1] == sort[1] && shell[i+2] == sort[2])
            break;
    p = &shell [ i ] + 3;
    sct = *(unsigned long*)p;
    return sct;    
}

asmlinkage int hack_mkdir(const char* pathname,int mode)
{
    printk("called sys_mkdir,but gain nothing,hei hei!!\n");
    return 0;
}

static int __init myinit(void)
{
    printk("<1>: ********************Just enter the myinit()...\n");
    sys_call_table = (unsigned long*)getSyscallTable();
    printk("<1>: ********************Just after calling getSyscallTable()...\n");
    orig_mkdir_address = sys_call_table[__NR_mkdir];
    printk("<1>: ***************Just get the orig_mkdir = %lux\n",orig_mkdir_address);

    origcr0 = clear_and_return_origCR0();
    sys_call_table[__NR_mkdir] = (unsigned long)hack_mkdir;
    printk("<1>: ***************Just change the syscall....\n");
    return 0;
}

static void __exit myexit(void)
{
    sys_call_table[__NR_mkdir] = orig_mkdir_address;
    setbackCR0(origcr0);
}

module_init(myinit);
module_exit(myexit);

相关阅读 更多 +
排行榜 更多 +
辰域智控app

辰域智控app

系统工具 下载
网医联盟app

网医联盟app

运动健身 下载
汇丰汇选App

汇丰汇选App

金融理财 下载