Connect With Us:

Getting a symbolized kernel !

post thumb
Reverse
by Mathieu Renard/ on 07 Feb 2019

Getting a symbolized kernel !

Finding kernel symbols is essential for debugging such payloads because it provides valuable information about the internal state of the kernel and the execution of the system. Without symbols, it is difficult to identify the source of errors, trace the execution path, or set breakpoints at specific locations in the code. Debug symbols contain information about the function names, variable names, line numbers, and other relevant metadata that are necessary for debugging. By including debug symbols in the kernel, developers can better understand the behavior of the system and diagnose and fix issues more efficiently.

If you have your kernel sources and don’t know how to enable debug mode check this.

Many embedded systems run Linux kernel, on them it may not be neither easy nor possible to recompile the Linux kernel to enable debug symbols. This is due to the limited resources of these devices have in memory or in storage space. In such situations, vmlinux-to-elf may be an alternative solution (skip the next paragraph if you are in this situation).

Symbolizing Linux Kernel using the Kallsyms table

Enabling debug symbols by compiling the kernel can increase its size, which may not be suitable for devices with limited storage. In this use case vmlinux-to-elf can be used in order to retreive symbol information stored in the binary especially in the kallsyms table. However, it is important to note that this approach may not provide complete symbol information and may be less accurate than debugging with full debug symbols.

kallsyms table

The kallsyms table in the Linux kernel is a symbol table that contains information about the kernel’s functions and variables. It provides a mapping between the names of these symbols and their corresponding memory addresses. The table is generated during the kernel build process and is used by various debugging tools, including GDB, to locate and identify symbols in the kernel code.

The kallsyms table is useful for debugging because it allows developers to easily locate and identify the kernel functions and variables that are being executed or accessed. By identifying the function name or variable name associated with a particular memory address, developers can gain a better understanding of the code and its behavior. This is particularly important when debugging complex kernel code or when attempting to trace the flow of execution through the kernel. Without the kallsyms table, developers would need to rely on manual inspection of the kernel code or use other, less efficient, debugging techniques.

vmlinux-to-elf

vmlinux-to-elf is a tool that can be used to obtain a fully analyzable .ELF file from a vmlinux/vmlinuz/bzImage/zImage kernel image. This tool can work with either a raw binary blob or an already existing but stripped .ELF file. It uses a kernel symbol table (kallsyms) to recover function and variable symbols. This symbol table is compressed and is present in almost every kernel. The tool can recover strings that are not visible in the original binary.

To install vmlinux-to-elf system-wide, follow these steps:

  1. Clone the vmlinux-to-elf repository.
  2. Run the command pip3 install in the cloned directory.
 sudo apt install python3-pip
 sudo pip3 install --upgrade lz4 zstandard git+https://github.com/clubby789/python-lzo@b4e39df
 sudo pip3 install --upgrade git+https://github.com/marin-m/vmlinux-to-elf

Usage:

 vmlinux-to-elf <input_kernel.bin> <output_kernel.elf>

Now we have an .ELF file that we can analyze and debug.

No debug symbols, no kallsyms table ?

Static analysis and bindiffing

When it’s not possible to recompile the kernel to enable debug symbols, and the kallsyms table is not available, it can be challenging to retrieve symbols. In such cases, one can use disassemblers like IDA Pro or Ghidra to analyze the binary and identify function names and locations. These tools use static analysis to decompile the binary into readable codes and present it in a graphical format. Additionally, tools like Diaphora can compare the binary to a known good version of the code and identify differences, which can help in identifying functions and their corresponding names. Once the functions are identified, they can be used in conjunction with debugging tools like GDB to assist in the debugging process.

Printk and debug strings

Another way to identify function names in the absence of debug symbols or the kallsyms table is to look for printk strings in the kernel code. Printk is a function used for printing messages to the kernel log, and it is often used for debugging purposes. Developers often include useful information in the messages they print, including function names and parameters. By searching for these messages in the kernel code or log, it is sometimes possible to infer the name of a function or understand the flow of the code. However, this technique has limitations, as not all functions are called with printk statements and not all printk statements contain useful information. Additionally, searching through large volumes of log data can be time-consuming and error-prone. Therefore, this technique should be used in conjunction with other debugging techniques, such as dynamic analysis and static analysis.

Conclusion

References

comments powered by Disqus