我想在我的内核模块中使用函数getname
。它不会导出。由于我现在遇到这个问题,我想知道如何访问和使用任何未导出的内核符号。我认为使用一个步骤所需的步骤将根据符号的不同而有所不同,所以我想看看如何对一个类型(例如,一个结构),一个变量,一个指针表(如系统调用表)和一个函数。如何在以下任何一种情况下完成这些工作:
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)
的左边放一个星号吗?
答案 0 :(得分:1)
#include <linux/fs.h>
声明extern struct filename *getname(const char __user *);
。指向此函数的指针具有类型struct filename *(*)(const char __user *)
。如果声明该类型的变量,则变量名称位于*
中的(*)
之后。因此,您可以声明该类型的变量,并将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
无论如何都将符号值作为数字返回)。
答案 1 :(得分:0)
访问未导出的功能与访问导出的功能并不相同,只是您无法在内核中解析其地址。你可以这样做:
static void (*your_func)(void);
your_func=0xhex_addr;
或结构
strucr your_struct{int i;double j} *stru;
stru=0xhex_addr;
指针的类型只定义从指针的地址读取或写入的字节数。
对于结构或变量十六进制地址,甚至可能驻留在内核代码段中,但如果您尝试将某些内容写入该结构或var,则会导致分段错误 - 读取将是合法的。还有一件事......当用结构做这个技巧时,不要忘记结构数据的对齐。