From f4cc367abf5e98ddccda037e3522fc78f321b0b0 Mon Sep 17 00:00:00 2001 From: heipiao233 Date: Mon, 10 Mar 2025 23:06:47 +0800 Subject: [PATCH 1/2] Add compatibility for ashmem for Linux 6.0+. --- ashmem/Makefile | 2 +- ashmem/ashmem.c | 4 +-- ashmem/deps.c | 5 +++- ashmem/get_kln.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ ashmem/get_kln.h | 8 ++++++ 5 files changed, 81 insertions(+), 4 deletions(-) create mode 100644 ashmem/get_kln.c create mode 100644 ashmem/get_kln.h diff --git a/ashmem/Makefile b/ashmem/Makefile index c26eb37..7f8b047 100644 --- a/ashmem/Makefile +++ b/ashmem/Makefile @@ -1,6 +1,6 @@ ccflags-y += -I$(src) obj-m := ashmem_linux.o -ashmem_linux-y := ashmem.o deps.o +ashmem_linux-y := ashmem.o deps.o get_kln.o KDIR ?= /lib/modules/`uname -r`/build diff --git a/ashmem/ashmem.c b/ashmem/ashmem.c index 5605ccf..570b100 100644 --- a/ashmem/ashmem.c +++ b/ashmem/ashmem.c @@ -402,7 +402,7 @@ static int ashmem_mmap(struct file *file, struct vm_area_struct *vma) ret = -EPERM; goto out; } - vma->vm_flags &= ~calc_vm_may_flags(~asma->prot_mask); + vm_flags_clear(vma, ~calc_vm_may_flags(~asma->prot_mask)); if (!asma->file) { char *name = ASHMEM_NAME_DEF; @@ -947,7 +947,7 @@ static int __init ashmem_init(void) goto out_free2; } - ret = register_shrinker(&ashmem_shrinker); + ret = register_shrinker(&ashmem_shrinker, "ashmem_shrinker"); if (ret) { pr_err("failed to register shrinker!\n"); goto out_demisc; diff --git a/ashmem/deps.c b/ashmem/deps.c index ef1fbe7..8f00051 100644 --- a/ashmem/deps.c +++ b/ashmem/deps.c @@ -1,12 +1,15 @@ #include #include +#include "get_kln.h" typedef int (*shmem_zero_setup_ptr_t)(struct vm_area_struct *); static shmem_zero_setup_ptr_t shmem_zero_setup_ptr = NULL; int shmem_zero_setup(struct vm_area_struct *vma) { + kln_p kln = get_kln_p(); + if (kln == NULL) return -1; if (!shmem_zero_setup_ptr) - shmem_zero_setup_ptr = (shmem_zero_setup_ptr_t) kallsyms_lookup_name("shmem_zero_setup"); + shmem_zero_setup_ptr = (shmem_zero_setup_ptr_t) kln("shmem_zero_setup"); return shmem_zero_setup_ptr(vma); } diff --git a/ashmem/get_kln.c b/ashmem/get_kln.c new file mode 100644 index 0000000..d6a28e2 --- /dev/null +++ b/ashmem/get_kln.c @@ -0,0 +1,66 @@ +/* Reference: https://github.com/xcellerator/linux_kernel_hacking/issues/3 */ +#include +#include +#include + +#include "get_kln.h" + +#define KPROBE_PRE_HANDLER(fname) static int __kprobes fname(struct kprobe *p, struct pt_regs *regs) + +long unsigned int kln_addr = 0; +unsigned long (*kln_pointer)(const char* name) = NULL; + +static struct kprobe kp0, kp1; + +KPROBE_PRE_HANDLER(handler_pre0) { + kln_addr = (--regs->pc); + + return 0; +} + +KPROBE_PRE_HANDLER(handler_pre1) { + return 0; +} + +static int do_register_kprobe(struct kprobe* kp, char* symbol_name, void* handler) { + int ret; + + kp->symbol_name = symbol_name; + kp->pre_handler = handler; + + ret = register_kprobe(kp); + if (ret < 0) { + pr_err("do_register_kprobe: failed to register for symbol %s, returning %d\n", symbol_name, ret); + return ret; + } + + pr_info("Planted krpobe for symbol %s at %p\n", symbol_name, kp->addr); + + return ret; +} + +// this is the function that I have modified, as the name suggests it returns a pointer to the extracted kallsyms_lookup_name function +kln_p get_kln_p(void) { + int status; + + status = do_register_kprobe(&kp0, "kallsyms_lookup_name", handler_pre0); + + if (status < 0) return NULL; + + status = do_register_kprobe(&kp1, "kallsyms_lookup_name", handler_pre1); + + if (status < 0) { + // cleaning initial krpobe + unregister_kprobe(&kp0); + return NULL; + } + + unregister_kprobe(&kp0); + unregister_kprobe(&kp1); + + pr_info("kallsyms_lookup_name address = 0x%lx\n", kln_addr); + + kln_pointer = (unsigned long (*)(const char* name)) kln_addr; + + return kln_pointer; +} diff --git a/ashmem/get_kln.h b/ashmem/get_kln.h new file mode 100644 index 0000000..1ef2f0e --- /dev/null +++ b/ashmem/get_kln.h @@ -0,0 +1,8 @@ +#ifndef GET_KLN_H +#define GET_KLN_H +/* Reference https://github.com/xcellerator/linux_kernel_hacking/issues/3 */ + +typedef unsigned long (*kln_p)(const char*); +kln_p get_kln_p(void); + +#endif From 4faeaf7905c1efa04b6cecfedcaa87e7948d18a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=91=E5=AB=96233?= Date: Mon, 17 Mar 2025 22:43:45 +0800 Subject: [PATCH 2/2] Fix x86 compatibility --- ashmem/get_kln.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ashmem/get_kln.c b/ashmem/get_kln.c index d6a28e2..68967fd 100644 --- a/ashmem/get_kln.c +++ b/ashmem/get_kln.c @@ -13,7 +13,11 @@ unsigned long (*kln_pointer)(const char* name) = NULL; static struct kprobe kp0, kp1; KPROBE_PRE_HANDLER(handler_pre0) { + #if defined(__arm__) || defined(__aarch64__) kln_addr = (--regs->pc); + #else + kln_addr = (--regs->ip); + #endif return 0; }