Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading kernel memory using a module

As part of my project I need to read the kernel to get the memory address of system call table and system call address. Or in effect i need to extract the contents of the system call table and all the system calls.

Till now I use GDB for this purpose. Is there any way so that I could do it using a kernel module. I am new the kernel module programming. Looking for advice from experts here.

like image 445
user567879 Avatar asked Dec 28 '22 17:12

user567879


1 Answers

Let me first start by saying reading arbitrary kernel memory is tricky business! And there are many ways to do it, which vary in their degree of complexity and flexability.

1) Hard-code the address.

Search for it in your kernel version's System.map file:

# grep sys_call_table /boot/System.map-2.6.18-238.12.1.el5
c06254e0 R sys_call_table

With this, hard-code the address:

unsigned long *syscall_table = (unsigned long *)0xc06254e0;

Then, assuming you #include <linux/syscalls.h>, you can use the __NR_syscall definitions to grab the addresses of those syscalls within the code:

syscall_table[__NR_close]

This is the easiest method, but by far the least flexible. This module will only work on that exact kernel. If you insmod it into a different kernel, you're liable to get a kernel OOPs.

2) Brute-force scan for the table

Have a look at this:

http://memset.wordpress.com/2011/03/18/syscall-hijacking-dynamically-obtain-syscall-table-address-kernel-2-6-x-2/

He uses a method to brute force the kernel memory address range to find the sys_call_stable. As-is, it only works on 32bit (64bit has a different memory address range for the kernel).

This method is somewhat flexible, but may break down the road as the kernel semantics change.

3) Dynamically search System.map load time

You can read your kernel's System.map file when you load the module. I demonstrate this in the tpe-lkm module I wrote. The project is hosted on github.

Have a look at the find_symbol_address_from_file() from this file:

https://github.com/cormander/tpe-lkm/blob/master/symbols.c

Very flexible, as you can find any symbol you want, but reading files from kernel space is a big 'no no'. Don't ask me why, but people are always telling me that. You also run the risk that the System.map it looks at is invalid, and could cause a kernel OOPs. Also, the code is... messy.

4) Use kallsyms_on_each_symbol()

As of around kernel version 2.6.30, the kernel exports kallsyms_on_each_symbol(). We can thank the ksplice folks for that. With this you can't find the sys_call_table (it isn't in there for some reason), but you can find most other symbols.

Very flexible, very stable method of finding addresses of symbols, but somewhat complicated to understand ;)

I demonstrate this in my tpe-lkm project. Have a look at the find_symbol_callback() and find_symbol_address() function in this file:

https://github.com/cormander/tpe-lkm/blob/master/symbols.c

like image 121
Corey Henderson Avatar answered Dec 31 '22 14:12

Corey Henderson