1
votes

I have been using this process check-pointing project from Berkeley labs (namely, BLCR). And I noticed that they have been referencing some functions in the kernel that were not exported nor they were declared in any of the header files. Their code consists of kernel modules and some user-space utilities. So, they do not need to apply any kernel patches.

Their configure script generated some header files that declare these functions as externs and then assign some pointer value to each of the called functions. I am not sure how they generate these pointers to functions or how they are using them.

My question is: is there any way to call an in-kernel function without exporting that function and without declaring it in a header file?

3

3 Answers

8
votes

Most basic way:

Address can located by parsing System.map or /proc/kallsyms (you may need to be root to see addresses, a normal user may see zeros here).

Function prototype can be found by looking at Kernel source.

If we wanted to call

void __stack_chk_fail(void) 

Without using the exported symbol we would resolve an address and declare like:

void (*scf)(void) = (int (*)() ) 0xffffffff810519d0;

Then call with:

scf(); 

(__stack_chk_fail is actually exported but was the first function with no parameters I saw when answering the question).

3
votes

Anyway, after some grepping and reading code I can give you my idea, though it might be not 100% correct.

As you said

Their configure script generated some header files that declare these functions as externs and then assign some pointer value to each of the called functions.

This can be done by simple investigating of System.map file. It's a text file that holds table with kernel symbols and their addresses. Having that file some script can look in System.map for needed symbols (function names), get address for that function and generate externs with found pointers. Nice hack.

0
votes

Based on @JOgden's answer, using not-exported symbol need to consider ASLR (KASLR). If ASLR is enable, the address you get from system.map is wrong.

You need to find out the offset and add the absolute value from system.map.

Following is one of the way to get the offset:

offset = &system_wq - system_wq_addr;

system_wq is identifier and system_wq_addr is address of system_wq get from system.map