Chinaunix首页 | 论坛 | 博客
  • 博客访问: 201715
  • 博文数量: 81
  • 博客积分: 55
  • 博客等级: 民兵
  • 技术积分: 26
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-21 17:54
文章分类
文章存档

2018年(1)

2017年(1)

2016年(5)

2015年(23)

2014年(51)

我的朋友

分类: LINUX

2014-12-01 16:33:32

项目中有两个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

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