免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
1234下一页
最近访问板块 发新帖
查看: 4422 | 回复: 36

[内核模块] 进程挂住问题 [复制链接]

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-11-29 06:20:00
发表于 2016-03-08 16:25 |显示全部楼层
我写了一个内核模块,劫持了系统调用write,rename,很简单一般情况下运行都没有问题,但是有个别情况,有些命令在运行的时候会陷入死循环,不停的调用sys_write,但其实我在劫持write的代码里只是做了一些判断而已,并没有做任何实质行的操作,最令我疑惑的是我去掉某些毫无意义的代码之后,却反而又好了,看起来根本就摸不到头绪,到底是哪里导致的,请各位大侠看看,能否指点一二,非常感谢!

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
发表于 2016-03-08 16:32 |显示全部楼层
能把您的劫持部分的代码贴出来看看吗

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-11-29 06:20:00
发表于 2016-03-08 16:53 |显示全部楼层
#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");

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-11-29 06:20:00
发表于 2016-03-08 16:57 |显示全部楼层
我已经简化的很简单了,现在的问题就是,我删掉比如my_rename这个函数的定义,或者注释掉test函数里的一行strncpy代码,就好了,真是丈二和尚摸不着头脑。

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-11-29 06:20:00
发表于 2016-03-08 17:01 |显示全部楼层
还有就是我把test函数里的while(i < g_var)替换为while(i < ret), 也没问题了,明明ret是0,g_var也是0,真是搞不懂。

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-11-29 06:20:00
发表于 2016-03-08 17:11 |显示全部楼层
没人回答吗,

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
发表于 2016-03-08 17:28 |显示全部楼层
回复 6# sky__sea


   我在我的系统上做了测试,  您的 test() 函数里面并没有什么实质的东西,最多就那个 strncpy............

论坛徽章:
1
操作系统版块每日发帖之星
日期:2015-11-29 06:20:00
发表于 2016-03-08 17:35 |显示全部楼层
是啊,我的意思就是没有什么实质意义,但是就是会影响某些操作命令,导致个别命令进入死循环,所以我百思不得其解。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
发表于 2016-03-08 19:39 |显示全部楼层
估计跟stack的布局有关系 (跟没有回答一样

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
发表于 2016-03-08 19:41 |显示全部楼层
不停的调用sys_write
是怎么确定的?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP