Logo
blank Skip to main content

Kprobes Internals as a Field of Kernel Symbol Detection

Kernel space hooking allows user space applications to access system specific information without the necessary level of privilege. This can be extremely useful for security, parental control, system monitoring, and other applications.

In fact, there are various libraries and frameworks for Linux that allow for kernel space hooking.  However, as with many tools, they have their problems. In this article, we’ll look at some restrictions that you might face when trying to find kernel symbols in the system call table in order to identify specific functions that you need to hook, as well as how Linux kernel symbol search process can be improved with the use of kernel probes (kprobes).

Existing Implementation

The system call table facilitates the interaction between user space code and kernel space code in Linux. Various open source projects aimed at kernel hooking provide different implementations for getting identifiers of specific functions from the system call (or syscall) table.

Some of the more traditional approaches to getting syscall table identifiers include:

Restrictions

Both of the solutions linked to above are perfectly valid, but they also both have several restrictions when it comes to detecting kernel symbols:

  • The syscall table has limited scope from the general heap of kernel functions. Usually, this is enough, but generalization of the approach is always welcome
  • Both of these solutions contain platform-dependent implementations of the syscall table’s pointer lookup
  • Some internal functions contain the version in their own name, for example do_execveat_common.isra.XX, where XX is the – kernel version dependent number

Read also:
Hooking Linux Kernel Functions, Part 1: Looking for the Perfect Solution

Our Solution

These cases cannot be processed via the canonical pointer lookup, but the kernel is flexible and always has at least one alternative way to do things, or even a backdoor.

An alternative approach that allows you to overcome these restrictions is hidden in the kprobes API, which is also part of the Linux API. The kprobes API can be found in “include/linux/kallsyms.h” and is available only if the kernel is built with the CONFIG_KALLSYMS flag, which is turned on by default.

Related services

Kernel and Driver Development

In terms of hooking, the most interesting functions of kprobes internals are:

  • kallsyms_lookup_name_ptr – This function is straightforward and can look through all existing symbols to get a pointer to the symbol with exactly the same name as its parameter. This call can be used instead of the syscall table
  • kallsyms_on_each_symbol – This is a more powerful and complex function that can help a developer perform a wide range of tasks. The signature of this function is shown in Figure 1. where:
    • data is the name (or part of the name) of the symbol you’re looking for;
    • fn is a callback that can implement a variety of algorithms for incoming symbol analysis.
Using kallsyms_on_each_symbol kprobes function

 

kallsyms_on_each_symbol signature

The function above provides a platform-independent solution that isn’t bound by the scope of the available syscall function. Figure 2 shows a kprobes example of a kernel version independent implementation of a lookup for do_execveat_common.isra.XX.

The approach in Figure 2 lets you search for a symbol using only part of its name. This example is simple one, but if we replace strstr with a regular expression from the kernel’s API, the callback  becomes much more versatile.

Kernel symbol lookup with kprobes

 

Figure 2. do_execveat_common.isra.XX symbol lookup

Read also:
How to Write a Minimal Qt QML application with CMake

Conclusion

The kprobes API covered in this article is not a unique solution for getting kernel symbols, but it’s a very reliable and elegant approach that we at Apriorit use extensively in client projects.

If you want to learn more about system programming, check out our article on how to write a Qt QML application with CMake.

We have a slew of experienced Linux developers on board, so if you ever need a dedicated team to work on a Linux project, don’t hesitate to send us your request for proposal.

Tell us about your project

Send us a request for proposal! We’ll get back to you with details and estimations.

By clicking Send you give consent to processing your data

Book an Exploratory Call

Do not have any specific task for us in mind but our skills seem interesting?

Get a quick Apriorit intro to better understand our team capabilities.

Book time slot

Contact us