如何访问内核模块中的任何内核符号?

我想在我的内核模块中使用函数getname 。 它不被导出。 由于我现在遇到这个问题,我想知道如何访问和使用任何不导出的内核符号。 我认为使用一个必要的步骤将取决于符号是什么,所以我想看看它将如何做一个types(例如,一个结构),一个variables,一个指针表(如系统调用表)和一个函数。 这些情况如何可以做到这两种情况:

  • 当我知道从System.map/proc/kallsyms符号的地址。
  • 当我知道符号的名称,并希望在检索它时使用kallsyms_lookup_name

我目前知道如何劫持系统调用,这需要声明类似的东西

 asmlinkage <return_type> (*<name_for_system_call>)(<the types of the its arguments separated by commas>); 

会有这样的东西被使用? 在http://stackoverflow.com/a/32968387/1953537回答另一个问题,海报呈现的例子是

 #include <linux/kallsyms.h> static void (*machine_power_off_p)(void); machine_power_off = (void*) kallsyms_lookup_name("machine_power_off"); 

但是如果符号返回一个指针呢? 我会在(*machine_power_off_p)的左边放一个星号吗?

Solutions Collecting From Web of "如何访问内核模块中的任何内核符号?"

访问未导出的函数与访问导出的函数没有区别,只不过不能在内核中解析其地址。 你可以这样做:

 static void (*your_func)(void); your_func=0xhex_addr; 

或为结构

 strucr your_struct{int i;double j} *stru; stru=0xhex_addr; 

指针的类型只是定义了从指针的地址中读取或写入多少个字节。

对于结构体或变量十六进制地址甚至可能驻留在内核代码段中,但是如果您尝试将某些内容写入该结构或var,则会出现段错误 – 读取将是合法的。 另外还有一件事情…在结构化这个技巧时,不要忘记结构数据对齐。

#include <linux/fs.h>声明extern struct filename *getname(const char __user *); 。 指向这个函数的指针的类型是struct filename *(*)(const char __user *) 。 如果声明该类型的变量,则变量名称将放在* in (*) 。 因此,您可以声明该类型的变量,并将kallsyms_lookup_name("getname")的返回值kallsyms_lookup_name("getname")给它,如下所示:

 static struct filename *(*getname_p)(const char __user *); getname_p = (struct filename *(*)(const char __user *)) kallsyms_lookup_name("getname"); 

对于你想要使用数字地址的其他情况,只需将kallsyms_lookup_name函数调用替换为实际编号( kallsyms_lookup_name返回符号值)。