免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2484 | 回复: 9
打印 上一主题 下一主题

[内核模块] [求助]获取system_call地址造成系统重启的问题(个人崩溃中) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-05-28 22:54 |只看该作者 |倒序浏览
本帖最后由 做酷 于 2014-05-28 22:55 编辑

最近在学习hook系统调用,但是在获取system_call地址的时候,遇到一个自己无法理解的问题,还请各位帮忙看一看:

一、环境信息[VMware虚拟机]
[root@localhost ~]#  lsb_release -a
LSB Version:    :core-3.1-ia32:core-3.1-noarch:graphics-3.1-ia32:graphics-3.1-noarch
Distributor ID: RedHatEnterpriseServer
Description:    Red Hat Enterprise Linux Server release 5.2 (Tikanga)
Release:        5.2
Codename:       Tikanga

[root@localhost ~]# uname -a
Linux localhost.localdomain 2.6.18-92.el5xen #1 SMP Tue Apr 29 13:45:57 EDT 2008 i686 i686 i386 GNU/Linux

二、测试代码
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/in.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <linux/dirent.h>
#include <asm/processor.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
#include <linux/proc_fs.h>   

struct idt_descriptor
{
    unsigned short off_low;

    unsigned short sel;  

    unsigned char none, flags;  

    unsigned short off_high;  

};   

void *get_system_call(void)
{  

        unsigned char idtr[6];

        unsigned long base;

        struct idt_descriptor desc;   

        asm ("sidt %0" : "=m" (idtr));  

        base = *((unsigned long *) &idtr[2]);  

        //中断描述符表的第0x80项是system_call函数的  

        memcpy(&desc, (void *) (base + (0x80* 8 )), sizeof(desc));

        return        (void *)base;


/***********************************************************************************

*insmod 模块后
*在此之上的代码执行是没有问题的,可以打印相应的值

*如果将上面的return语句去除,执行下面的语句,都会造成系统直接重启,即任何对desc成员的读取操作都会造成关机重启

*问题就是,struct idt_descriptor desc这个局部变量,为什么可写而不可读,这是什么原因造成的?该如何解决?好像类似的文章都没有提到这种现象

************************************************************************************/
         
        //base=(unsigned long )desc.off_low;
        //return        (void *)base;

        //printk(KERN_EMERG"hight %x\n", desc.off_high);
        //printk(KERN_EMERG"low %x\n", desc.off_low);


        //return ((void *) ((desc.off_high << 16) + desc.off_low));  

}  


static int __init init_hook(void)  
{
    void *system_call;

    system_call = get_system_call();  

    printk(KERN_EMERG"Address of system_call: %x\n", (unsigned int)system_call);

    return 0;
}

static void __exit exit_hook(void)
{
}  

module_init(init_hook);
module_exit(exit_hook);

MODULE_LICENSE("GPL" ) ;

论坛徽章:
0
2 [报告]
发表于 2014-05-28 23:04 |只看该作者
void *get_system_call(void)
{
    unsigned char idtr[6];
    unsigned long base;
    struct idt_descriptor desc={0};
    return        desc.off_high;
}
将函数替换为上述内容,也是可以正常打印的
localhost kernel: Address of system_call: 0

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
3 [报告]
发表于 2014-05-29 14:00 |只看该作者
base = *((unsigned long *) &idtr[2]);  
...
//base=(unsigned long )desc.off_low;
base指针两次赋值?

论坛徽章:
0
4 [报告]
发表于 2014-05-29 17:50 |只看该作者
本帖最后由 做酷 于 2014-05-29 18:31 编辑

回复 3# humjb_1983


   在代码说明里已经说清楚了,base赋值只是为了函数返回测试!
问题的实质是无法对struct idt_descriptor desc这个局部变量的成员进行读取,跟base赋几次值没有关系!

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
5 [报告]
发表于 2014-05-29 19:18 |只看该作者
做酷 发表于 2014-05-29 17:50
回复 3# humjb_1983

出问题是第一条没执行,还是第二条没执行?为何确认是读取时出错?

论坛徽章:
0
6 [报告]
发表于 2014-05-29 22:25 |只看该作者
可能没有下面那段的时候,那个memcpy也被优化掉了?没有实际执行。要查看一下编译出来的汇编看看。
你要看看系统崩溃时的oops打印的错误地址是什么,对应代码的哪一行。

论坛徽章:
0
7 [报告]
发表于 2014-05-29 23:53 |只看该作者
回复 5# humjb_1983

        unsigned char idtr[6];

        unsigned long base;

        struct idt_descriptor desc;    

        asm ("sidt %0" : "=m" (idtr));  

        base = *((unsigned long *) &idtr[2]);  

        //中断描述符表的第0x80项是system_call函数的  

        memcpy(&desc, (void *) (base + (0x80*), sizeof(desc));

        printk(KERN_EMERG"hight %x\n", desc.off_high);
        printk(KERN_EMERG"low %x\n", desc.off_low);


这样也是重启的!

论坛徽章:
0
8 [报告]
发表于 2014-05-29 23:55 |只看该作者
回复 6# hmsghnh


   好的,我再看看!

论坛徽章:
0
9 [报告]
发表于 2014-05-30 00:18 |只看该作者
对各位关注表示感谢!)

再把几个测试代码贴出来说明一下:

1、
void *get_system_call(void)
{
        unsigned char idtr[6];
        unsigned long base;
        struct idt_descriptor desc={0};

        return        desc.off_high;
}
结果:localhost kernel: Address of system_call: 0

2、
void *get_system_call(void)
{  
        unsigned char idtr[6];
        unsigned long base;
        struct idt_descriptor desc={0};

        asm ("sidt %0" : "=m" (idtr));
        base = *((unsigned long *) &idtr[2]);  
        // 中断描述符表的第0x80项是system_call函数的
        memcpy(&desc, (void *) (base + (0x80* 8 )), sizeof(desc));
        return        (void *)base;
}
结果:localhost kernel: Address of system_call: ff1fc860

3、
void *get_system_call(void)
{
    unsigned char idtr[6];
    unsigned long base;
    struct idt_descriptor desc={0};

    asm ("sidt %0" : "=m" (idtr));
    base = *((unsigned long *) &idtr[2]);

    // 中断描述符表的第0x80项是system_call函数的
    memcpy(&desc, (void *) (base + (0x80* 8 )), sizeof(desc));

    return        (void *)desc.off_low;
}  
结果:关机重启

论坛徽章:
15
射手座
日期:2014-02-26 13:45:082015年迎新春徽章
日期:2015-03-04 09:54:452015年辞旧岁徽章
日期:2015-03-03 16:54:15羊年新春福章
日期:2015-02-26 08:47:552015年亚洲杯之卡塔尔
日期:2015-02-03 08:33:45射手座
日期:2014-12-31 08:36:51水瓶座
日期:2014-06-04 08:33:52天蝎座
日期:2014-05-14 14:30:41天秤座
日期:2014-04-21 08:37:08处女座
日期:2014-04-18 16:57:05戌狗
日期:2014-04-04 12:21:33技术图书徽章
日期:2014-03-25 09:00:29
10 [报告]
发表于 2014-05-30 09:42 |只看该作者
还是需要看看具体错误的指令对应到哪行代码。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP