From 02efdca8d08fe2ae2c7ba04959d3ab1f797fc1a3 Mon Sep 17 00:00:00 2001 From: Andriy Petrov Date: Wed, 17 Apr 2024 14:26:30 +0200 Subject: [PATCH] rewrites --- README.md | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f8559eb..8646cc3 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,17 @@ -The process of [kernel modules compilation](https://www.kernel.org/doc/html/v5.6/kbuild/modules.html) depends heavily on accessibility of header files provided by kernel. There are exist no guarantees on ABI compatibility even between minor kernel versions. This is [deliberate design choice](https://github.com/torvalds/linux/blob/v4.9/Documentation/stable_api_nonsense.txt) made by kernel developers. Kernel module compilation *depends* on kernel headers. +Kernel module [compilation](https://www.kernel.org/doc/html/v5.6/kbuild/modules.html) *depends* on kernel headers. This is a [deliberate design choice](https://github.com/torvalds/linux/blob/v4.9/Documentation/stable_api_nonsense.txt) made by kernel developers. As result, there is no even a slight guarantee of an ABI compatibility even between minor kernel versions. > But what to do if, for the variety of reasons, for the kernel you are interest in, headers are unavailable? -The code in this repo focuses on Android, but most of the information and techniques discussed here can be easily applied to the generic Linux kernel as well. +The code in this repo gives an answer to this question. It focuses on Android, but most of the information and techniques discussed here can be easily applied to the generic Linux kernel as well. # ELF symbols stealing -The main idea, is to use Android NDK to compile generic Linux kernel module. And embed it with ELF symbols collected from some existing kernel module (see `/vendor/lib/modules/*.ko`). In such a way, that the LKM loader would be able to recognise and resolve all necessary dependencies and definitions. +The main idea, is to use Android NDK to compile generic a Linux kernel module with pre-embed ELF symbols collected from some existing kernel module. See, for example, `/vendor/lib/modules/*.ko` for a possible donor. The idea is to provide just enough information, so that the LKM loader would be able to recognise and resolve all the necessary dependencies and default, and in the end to load our kernel agnostic module. ## PLT section -This part is pretty straight forward, we simply have to define a few ELF symbols, that Android LKM is expecting to find within *normal* module. We are going to really on [compiler keyword](https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Variable-Attributes.html) `__attribute__` for this. +This part is pretty straight forward, we simply have to define a few ELF symbols, that Android LKM is expecting to find within *normal* module. We are going to use `__attribute__` [compiler keyword](https://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Variable-Attributes.html) for this. ```c // insmod error: module PLT section(s) missing @@ -48,7 +48,7 @@ objdump -s -j .modinfo $KMODULE 00d0 00 ``` -This ELF section essentially is collection of 'TAG=VALUE' entries separated by NULL character '\0'. The most important part is `vermagic`, since loader is using it do identify which kernel headers were used for module compilation. +This ELF section essentially is a collection of 'TAG=VALUE' entries separated by NULL character '\0'. The most important part is `vermagic`, since the loader is using it do identify which kernel headers were used for the module compilation and compares it against his own `vermagic` variable. They must be identical. ```bash cat /proc/version @@ -131,6 +131,21 @@ In order for module to use any externally declared symbol module must: ``` 2. Add another entry to the `__versions` section +```c + char __attribute__((section("__versions"))) ____versions[] = { + /* module_layout */ // <<-- MUST BE PROVIDED + 0xe8, 0xd6, 0xfc, 0x68, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x5f, 0x6c, + 0x61, 0x79, 0x6f, 0x75, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + /* printk */ + 0xa1, 0x58, 0x55, 0x98, 0x00, 0x00, 0x00, 0x00, 0x70, 0x72, 0x69, 0x6e, 0x74, 0x6b, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +``` # Misc commands