问题
I am wanting to use the function getname
in my kernel module. It is not exported. Since I am running into this problem right now, I would like to know how to access and use any kernel symbol that is not exported. I figure that the steps necessary to use one will differ depending what the symbol is, so I'd like to see how it would be done for a type (e.g., a struct), a variable, a table of pointers (like the system call table), and a function. How can these be done in either of these cases:
- When I know the address of the symbol from
System.map
or/proc/kallsyms
. - When I know the name of the symbol and want to use
kallsyms_lookup_name
in retrieving it.
I currently know how to hijack system calls and this requires declaring something like
asmlinkage <return_type> (*<name_for_system_call>)(<the types of the its arguments separated by commas>);
Would something like that be used? In http://stackoverflow.com/a/32968387/1953537 answer to another question, the example presented by the poster is
#include <linux/kallsyms.h>
static void (*machine_power_off_p)(void);
machine_power_off = (void*) kallsyms_lookup_name("machine_power_off");
But what if the symbol returns a pointer? Would I place an asterisk to the left of (*machine_power_off_p)
?
回答1:
#include <linux/fs.h>
declares extern struct filename *getname(const char __user *);
. A pointer to this function has type struct filename *(*)(const char __user *)
. If declaring a variable of that type, the variable name goes after the *
in (*)
. So you can declare a variable of that type and assign the return value of kallsyms_lookup_name("getname")
to it as follows:
static struct filename *(*getname_p)(const char __user *);
getname_p = (struct filename *(*)(const char __user *))
kallsyms_lookup_name("getname");
For your other case where you want to use a numeric address, just replace the kallsyms_lookup_name
function call with the actual number (kallsyms_lookup_name
returns the symbol value as a number anyway).
回答2:
Accessing not exported function doesn't differ from accessing exported functions, except that you can't resolve its address in kernel. You can do trick like this:
static void (*your_func)(void);
your_func=0xhex_addr;
or for struct
strucr your_struct{int i;double j} *stru;
stru=0xhex_addr;
Type of a pointer just defines how many bytes would be read or written from or to pointer's address.
For structure or variable hex address even may reside in kernel code segment, but you'll get segmentation fault if you'll try to write something to that struct or var - reading would be legit. And one more thing... when doing this trick with structure don't forget about structure data alignment.
来源:https://stackoverflow.com/questions/40431194/how-do-i-access-any-kernel-symbol-in-a-kernel-module