Skip to content

Commit

Permalink
support: remap_process_memory
Browse files Browse the repository at this point in the history
  • Loading branch information
fuqiuluo committed Jan 24, 2025
1 parent b4a8431 commit 1459c29
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 15 deletions.
5 changes: 4 additions & 1 deletion ovo/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ $(MODULE)-objs += kkit.o
$(MODULE)-objs += peekaboo.o
$(MODULE)-objs += memory.o

EXTRA_CFLAGS = -fno-pic
EXTRA_CFLAGS += -DHIDE_SELF_MODULE=0

all:
make -C $(KDIR) EXTRA_CGLAGS=-fno-pic M=$(PWD) modules
make -C $(KDIR) EXTRA_CFLAGS="$(EXTRA_CFLAGS)" M=$(PWD) modules

clean:
make -C $(KDIR) M=$(PWD) clean
155 changes: 144 additions & 11 deletions ovo/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <asm/page.h>
#include <linux/pgtable.h>
#include <linux/vmalloc.h>
#include <linux/mman.h>

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 11, 0)
#include <linux/sched/mm.h>
Expand All @@ -31,6 +32,7 @@
#endif

#include "mmuhack.h"
#include "kkit.h"

#ifdef CONFIG_CMA
//#warning CMA is enabled!
Expand Down Expand Up @@ -295,23 +297,154 @@ int access_process_vm_by_pid(pid_t from, void __user*from_addr, pid_t to, void _
return 0;
}

int remap_process_memory(pid_t from, void *from_addr, pid_t to, void *to_addr) {
/* struct task_struct *task_a, *task_b;
struct mm_struct *mm_a, *mm_b;
struct vm_area_struct *vma_b;
void* remap_process_memory(pid_t from, void *from_addr, pid_t to, size_t size) {
static struct vm_area_struct *(*ovo_vm_area_alloc)(struct mm_struct *) = NULL;
struct task_struct *from_task, *to_task;
struct vm_area_struct *from_vma, *vma;
pte_t* ptep;
unsigned long pfn;
void* unmapped_addr;
unsigned long (*get_area)(struct file *, unsigned long,
unsigned long, unsigned long, unsigned long);
struct mm_struct* mm;

if (!capable(CAP_SYS_ADMIN))
return NULL;

size = PAGE_ALIGN(size);
if (!from_addr || !size || size > TASK_SIZE)
return NULL;

if (ovo_vm_area_alloc == NULL) {
ovo_vm_area_alloc = (struct vm_area_struct *(*)(struct mm_struct *))
ovo_kallsyms_lookup_name("vm_area_alloc");
}

if(ovo_vm_area_alloc == NULL) {
pr_err("[ovo] ovo_vm_area_alloc not found!");
return NULL;
}

{
rcu_read_lock();
from_task = pid_task(find_vpid(from), PIDTYPE_PID);
to_task = pid_task(find_vpid(to), PIDTYPE_PID);

if (!from_task || !to_task || !from_task->mm || !to_task->mm)
return NULL;

get_task_struct(from_task);
get_task_struct(to_task);
rcu_read_unlock();
}

mm = get_task_mm(from_task);

from_vma = find_vma(mm, (unsigned long)from_addr);
if (!from_vma) {
mmput(mm);
put_task_struct(from_task);
put_task_struct(to_task);
return NULL;
}

ptep = page_from_virt_user(mm, (unsigned long) from_addr);
pfn = pte_pfn(READ_ONCE(*ptep));

{ // release from_task's mm & from_task
mmput(mm);
put_task_struct(from_task);
mm = NULL;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 10, 0)
#error "remap_process_memory: Not support Kernel 6.11.0"
#else
mm = get_task_mm(to_task);
get_area = mm->get_unmapped_area;
#endif

unmapped_addr = (void*) get_area(NULL, 0, size, 0, 0);
if (IS_ERR_VALUE(unmapped_addr)) {
mmput(mm);
put_task_struct(to_task);
return NULL;
}

if ((unsigned long ) unmapped_addr > TASK_SIZE - size) {
mmput(mm);
put_task_struct(to_task);
return NULL;
}

if (offset_in_page((unsigned long) unmapped_addr)) {
mmput(mm);
put_task_struct(to_task);
return NULL;
}

vma = ovo_vm_area_alloc(mm);
if (!vma) {
mmput(mm);
put_task_struct(to_task);
return NULL;
}

vma->vm_start = (unsigned long) unmapped_addr;
vma->vm_end = ((unsigned long) unmapped_addr) + size;
*((unsigned long*) &vma->vm_flags) =
calc_vm_prot_bits(PROT_READ | PROT_WRITE, 0);
vma->vm_page_prot = vm_get_page_prot(vma->vm_flags);

if(remap_pfn_range(vma, (unsigned long)unmapped_addr, pfn, size, PAGE_SHARED)) {
pr_err("[ovo] remap_pfn_range failed!");
mmput(mm);
put_task_struct(to_task);
return NULL;
}

mmput(mm);
put_task_struct(to_task);
return unmapped_addr;
}

int unmap_process_memory(pid_t from, void *from_addr, size_t size) {
struct task_struct *from_task;
struct mm_struct *mm;
struct vm_area_struct *vma;
pte_t* ptep;
unsigned long pfn;

rcu_read_lock();
task_a = pid_task(find_vpid(from), PIDTYPE_PID);
task_b = pid_task(find_vpid(to), PIDTYPE_PID);
from_task = pid_task(find_vpid(from), PIDTYPE_PID);

if (!from_task)
return -ESRCH;

get_task_struct(from_task);
rcu_read_unlock();

if (!task_a || !task_a->mm || !task_b || !task_b->mm) {
return -1;
mm = get_task_mm(from_task);
if (!mm)
return -ESRCH;

vma = find_vma(mm, (unsigned long)from_addr);
if (!vma) {
mmput(mm);
put_task_struct(from_task);
return -ESRCH;
}

mm_a = get_task_mm(task_a);
mm_b = get_task_mm(task_b);
ptep = page_from_virt_user(mm, (unsigned long) from_addr);
pfn = pte_pfn(READ_ONCE(*ptep));

if (remap_pfn_range(vma, (unsigned long)from_addr, 0, size, PAGE_SHARED)) {
mmput(mm);
put_task_struct(from_task);
return -EIO;
}

*/
mmput(mm);
put_task_struct(from_task);
return 0;
}
5 changes: 2 additions & 3 deletions ovo/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ int write_process_memory(pid_t pid, void __user* addr, void __user* src, size_t
int access_process_vm_by_pid(pid_t from, void __user* from_addr, pid_t to, void __user* to_addr, size_t size);

// 内存重映射
// 默认一次性映射一页内存,使用的是vm_insert_page
int remap_process_memory(pid_t from, void __user* from_addr, pid_t to, void __user* to_addr);
int unmap_process_memory(pid_t from, void __user* from_addr);
void* remap_process_memory(pid_t from, void __user* from_addr, pid_t to, size_t size);
int unmap_process_memory(pid_t from, void __user* from_addr, size_t size);

#endif //OVO_MEMORY_H
2 changes: 2 additions & 0 deletions ovo/peekaboo.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ void cuteBabyPleaseDontCry(void) {
}

#ifdef MODULE
#if HIDE_SELF_MODULE == 1
list_del(&THIS_MODULE->list); //lsmod,/proc/modules
kobject_del(&THIS_MODULE->mkobj.kobj); // /sys/modules
list_del(&THIS_MODULE->mkobj.kobj.entry); // kobj struct list_head entry
#endif
#endif
}

0 comments on commit 1459c29

Please sign in to comment.