chenyu105 发表于 2014-08-20 22:43

如何给内核的memcpy里加钩子?

linux 3.16-rc2   X86_64架构

下面是我的修改步骤,发现有些问题:

1. 将内核自带的汇编实现memcpy注释掉

linux-3.16-rc2\arch\x86\lib\memcpy_64.S

ENTRY(__memcpy)
ENTRY(memcpy)
...
        CFI_ENDPROC
ENDPROC(memcpy)
ENDPROC(__memcpy)改为
ENTRY(__memcpy)
ENTRY(x86_memcpy)
...
        CFI_ENDPROC
ENDPROC(x86_memcpy)
ENDPROC(__memcpy)2. 在内核通用memcpy实现函数中加钩子

linux-3.16-rc2\lib\string.c

#ifndef __HAVE_ARCH_MEMCPY
void *memcpy(void *dest, const void *src, size_t count)
{
        char *tmp = dest;
        const char *s = src;

        while (count--)
                *tmp++ = *s++;
        return dest;
}
#endif改为
//#ifndef __HAVE_ARCH_MEMCPY
void *memcpy(void *dest, const void *src, size_t count)
{
        char *tmp = dest;
        const char *s = src;
        my_hook();
        while (count--)
                *tmp++ = *s++;
        return dest;
}
//#endif在mm目录新加一个文件,测试memcpy的回调是否生效:
linux-3.16-rc2\mm\memcpy_test.c
#include        <linux/mm.h>
#include        <linux/kallsyms.h>
#include        <linux/module.h>
int hook_value = -1;
int test_begin = 0;
voidmy_test_begin(void)
{
        char src = {0};
        char dst = {1};
        test_begin = 1;
        mb();
        memcpy((char*)dst,(char*)src,50);
        test_begin = 0;
        mb();
        printk("hook value:%d\n",hook_value);
}

voidmy_hook(void)
{
        if(test_begin)
                hook_value=1;
}打印发现hook_value仍然是-1,my_hook赋值没有生效,大家帮看看哪里有问题不?thx

humjb_1983 发表于 2014-08-20 23:19

呵呵,这么晚还在辛苦工作~
你确认走到这几个接口中了么?加打印看看呢?

chenyu105 发表于 2014-08-20 23:33

回复 2# humjb_1983

只要把if(test_begin)去掉,hook_value就能设置成1。
hook应该是走到了的。 关键是我加的这个memcpy_test.c 里的memcpy,为啥没有走到hook_value=1,这个实在想不通。
另外memcpy里不好加printk调试,因为后者里面好像就有memcpy,这样搞重入了不好整。

voidmy_hook(void)
{      
        if(test_begin)//判断去掉
                hook_value=1;
}
手工调用检测越界接口OK了, 就剩在memcpy里加越界检测接口了,这临门一脚出不来憋啊。

chenyu105 发表于 2014-08-21 18:31

解决了。
gcc会根据memcpy的长度来决定替换memcpy的实现,在内核主Makefile里加一句
KBUILD_CFLAGS += -fno-builtin
就好了
页: [1]
查看完整版本: 如何给内核的memcpy里加钩子?