可以用一个模块替换一个Linux内核函数吗?

前端之家收集整理的这篇文章主要介绍了可以用一个模块替换一个Linux内核函数吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我进入内核工作了一点我的夏季研究.我们正在寻求在特定RTT计算中对TCP进行修改.我想做的是将tcp_input.c中的一个函数的分辨率替换为动态加载的内核模块提供的函数.我认为这会提高我们开发和分发修改的步伐.

我感兴趣的函数被声明为静态,但是我已经使用非静态函数重新编译了内核,并通过EXPORT_SYMBOL导出.这意味着内核的其他模块/部分现在可以访问该功能.我已经通过“cat / proc / kallsyms”验证了这一点.

现在我想加载一个模块,可以从初始化到动态加载的函数重写符号地址.类似地,当要卸载模块时,它将恢复原始地址.这是可行的做法吗?你们都有建议如何更好地实施?

谢谢!

Overriding functionality with modules in Linux kernel相同

编辑:
这是我最终的做法.
给定以下函数(我想覆盖,而不是导出):

static void internal_function(void) 
{
  // do something interesting
  return;
}

修改如下:

static void internal_function_original(void)
{
  // do something interesting
  return;
}

static void (*internal_function)(void) = &internal_function_original;
EXPORT_SYMBOL(internal_function);

这重新定义了预期的函数标识符,而不是指向原始实现的函数指针(可以以类似的方式调用). EXPORT_SYMBOL()使地址全局可访问,因此我们可以从模块(或其他内核位置)进行修改.

现在您可以使用以下形式编写内核模块:

static void (*original_function_reference)(void);
extern void (*internal_function)(void);

static void new_function_implementation(void)
{
  // do something new and interesting
  // return
}

int init_module(void)
{
  original_function_reference = internal_function;
  internal_function           = &new_function_implementation;
  return 0;
}

void cleanup_module(void)
{
  internal_function = original_function_reference;
}

此模块将使用动态加载的版本替换原始实现.卸载后,恢复原始引用(和实现).在具体情况下,我为TCP中的RTT提供了一个新的估计.通过使用模块,我可以进行小的调整并重新启动测试,而无需重新编译和重新启动内核.

解决方法

我不确定会工作 – 我相信,您要替换的功能的内部调用的符号解析将在您的模块加载时完成.

相反,您可以通过重命名现有函数来更改代码,然后使用函数的原始名称创建一个全局函数指针.将函数指针初始化到内部函数的地址,因此现有代码将不会修改.导出全局函数指针的符号,那么您的模块只能通过在模块加载和卸载时间分配来更改其值.

猜你在找的Linux相关文章