Reading kernel memory using a module
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
Linux kernel module - accessing memory mapping
From the module's code THIS_MODULE
macro is actually a pointer to the struct module
object. Its module_init
and module_core
fields point to memory regions, where all module sections are loaded.
As I understand, sections division is inaccessible from the module code(struct load_info
is dropped after module is loaded into memory). But having module's file you can easily deduce section's addresses after load:
module_init:
- init sections with code (.init.text)
- init sections with readonly data
- init sections with writable data
module_core:
- sections with code (.text)
- sections with readonly data
- sections with writable data
If several sections suit to one category, they are placed in the same order, as in the module's file.
Within module's code you can also print address of any its symbol, and after calculate start of the section, contained this symbol.
Related Topics
Bash Cut Columns to One File and Save onto The End of Another File
System Calls: Difference Between Sys_Exit(), Sys_Exit and Exit()
How to Send a Signal to Process That Belongs to Different User
Where M Flag and O Flag Will Be Stored in Linux
Bash: Start Remote Python Application Through Ssh and Get Its Pid
Error Installing Chrome on Aws Ec2 Linux Instance: Scaling_Cur_Freq & Scaling_Max_Freq Not Found
How to Clear Docker Task History
Copying an Image to The Clipboard from Command Line
Operand Generation of Call Instruction on X86-64 Amd
Terraform - Unable to Run Multiple Commands in Local Exec
How to Open Multiple Instances of a Program in Linux
Why Does Linux Perf Use Event L1D.Replacement for "L1 Dcache Misses" on X86
Process Niceness (Priority) Setting Has No Effect on Linux
Setuid on an Executable Doesn't Seem to Work
Why Can't I Install Any Packages with Ghc 7.8.4 on Raspberry Pi
Inotify Fd - Why Is The Limit Per User Id and Not Per Process
How to I Detect Whether a Tty Belonging to a Gsm/3G-Modem Is a Data or Control Port