Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ashmem/Makefile
Original file line number Diff line number Diff line change
@@ -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

Expand Down
4 changes: 2 additions & 2 deletions ashmem/ashmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 4 additions & 1 deletion ashmem/deps.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#include <linux/mm.h>
#include <linux/kallsyms.h>
#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);
}

70 changes: 70 additions & 0 deletions ashmem/get_kln.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* Reference: https://github.com/xcellerator/linux_kernel_hacking/issues/3 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>

#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) {
#if defined(__arm__) || defined(__aarch64__)
kln_addr = (--regs->pc);
#else
kln_addr = (--regs->ip);
#endif

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;
}
8 changes: 8 additions & 0 deletions ashmem/get_kln.h
Original file line number Diff line number Diff line change
@@ -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