Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5762296
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: LINUX

2008-11-20 20:57:19

项目中有两个module,其中一个module中需要另外一个module的符号,2.6.26之前的内核只要按照顺序进行加载就没有问题,但是在2.6.26里面就会出现"can not found symbol"的错误。

通过之前的一些rootkit的思想,在内核中通过读取/proc/kallsyms文件来获得相应符号的地址。
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include //for filp
#include
#include //for mmap

#define DRV_DEBUG

unsigned long read_kallsyms(char *symbol_name);
int init_module(void)
{
    read_kallsyms("sys_read");
    read_kallsyms("dum_check_wait_queue");
    read_kallsyms("cdrom_open");
    return -1;
}

void cleanup_module(void)
{
}
MODULE_LICENSE("GPL");

#define MAX_BUF_LEN 100
int kgetline(struct file *file, char *buf)
{
    int i = 0;
    char c = 0;
    int nbytes = 0;
    char temp[MAX_BUF_LEN] = {0};

    for(i=0; i    {
        nbytes = file->f_op->read(file, &c, 1,&file->f_pos);
        if(nbytes==0)
            break;
        temp[i] = c;
        buf[i] = c;
    }
    //printk("Line(%d): %s", i, temp);
    return i;
}

#define PROC_HOME    "/proc/kallsyms"
unsigned long read_kallsyms(char *symbol_name)
{
    mm_segment_t old_fs;
    ssize_t bytes;
    struct file *file = NULL;
    char *p;
    int i = 0;
    unsigned long addr = 0;

    char line[MAX_BUF_LEN] = {0};
    char new_symbol_name[MAX_BUF_LEN] = "T ";
    strcat(new_symbol_name, symbol_name);
    printk("new_symbol_name: %s\n", new_symbol_name);
    int len = strlen(new_symbol_name);

    file = filp_open(PROC_HOME,O_RDONLY,0);
    if (!file)
        return -1;

    if (!file->f_op->read)
        return -1;

    old_fs = get_fs();
    set_fs(get_ds());

    for(;;)
    {
       bytes = kgetline(file,line);
       if(bytes==0)
        break;
           if (( p = strstr(line, new_symbol_name)) != NULL)
       {
        /*
        NOTES: ' ' & '\t'
        c0123456 T sys_read
        e0654321 T cdrom_open    [cdrom]
        */
        if( (*(p+len) != '\n') && (*(p+len) != '\t') )
            continue;

        printk("line:%s\n", line);

        for(i=0; i        {
        if(line[i] == ' ')
            break;
        }
        line[i] = '\0';

            addr = simple_strtoul(line,NULL,16);
#ifdef DRV_DEBUG
            printk("addr(%s): %x\n", symbol_name, addr);
#endif
            break;
       }
       memset(line, 0, MAX_BUF_LEN);
    }

    filp_close(file,NULL);

    set_fs(old_fs);
    return addr;
}

参考:
http://blog.chinaunix.net/u/12592/showart_484879.html

%7Ekasperd/comp.os.linux.development.faq#filp_open

阅读(7262) | 评论(10) | 转发(2) |
给主人留下些什么吧!~~

CUDev2008-11-28 21:49:18

只是方便我在module中调用,直接由脚本查到后再作为module的参数也可以。

chinaunix网友2008-11-25 22:57:26

我还没玩过2.6.26。 我想问的是为什么导出符号的办法在这个版本里不行了? 谢谢

chinaunix网友2008-11-25 22:57:26

我还没玩过2.6.26。 我想问的是为什么导出符号的办法在这个版本里不行了? 谢谢

xiaosuo2008-11-24 09:24:06

在内核做这个说实话有点儿累,为啥不把这些地址作为参数,由模块加灾的shell脚本解析文件,然后传入模块呢?

xiaosuo2008-11-24 09:24:06

在内核做这个说实话有点儿累,为啥不把这些地址作为参数,由模块加灾的shell脚本解析文件,然后传入模块呢?