项目链接:https://github.com/fuqiuluo/android-wuwa
为某个进程的虚拟地址"绑定"一块物理内存,让进程能够通过指定的虚拟地址访问到实际的物理页面。
但是不修改vma有关的任何东西,虽然是泄漏了些东西,至少实现了,不对吗?不需要去hook show_map
非常的脑子消失,不过采样器是可以检测到这个的,需要过一定的检测,至少不需要过太多...
下方代码只能分配一页,具体代码去项目里面查看!
int do_pte_mapping(struct socket *sock, void *arg) {
struct wuwa_pte_mapping_cmd cmd;
if (copy_from_user(&cmd, arg, sizeof(cmd))) {
return -EFAULT;
}
pgd_t *pgd;
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
pte_t *pte;
struct page* page = NULL;
int ret = 0;
struct pid* pid_struct = find_get_pid(cmd.pid);
if (!pid_struct) {
wuwa_warn("failed to find pid_struct: %d\n", cmd.pid);
return -ESRCH;
}
struct task_struct *task = get_pid_task(pid_struct, PIDTYPE_PID);
put_pid(pid_struct);
if (!task) {
wuwa_warn("failed to get task: %d\n", cmd.pid);
return -ESRCH;
}
struct mm_struct *mm = get_task_mm(task);
put_task_struct(task);
if (!mm) {
wuwa_warn("failed to get mm: %d\n", cmd.pid);
return -ESRCH;
}
static int (*my__pmd_alloc)(struct mm_struct *mm, pud_t *pud, unsigned long address) = NULL;
my__pmd_alloc = (int (*)(struct mm_struct *, pud_t *, unsigned long))kallsyms_lookup_name("__pmd_alloc");
static int (*my__pte_alloc)(struct mm_struct *mm, pmd_t *pmd) = NULL;
my__pte_alloc = (int (*)(struct mm_struct *, pmd_t *))kallsyms_lookup_name("__pte_alloc");
if (my__pmd_alloc == NULL || my__pte_alloc == NULL) {
wuwa_err("failed to find __pmd_alloc or __pte_alloc symbols\n");
ret = -ENOENT;
goto out_mm;
}
#define my_pte_alloc(mm, pmd) (unlikely(pmd_none(*(pmd))) && my__pte_alloc(mm, pmd))
#define my_pte_alloc_map(mm, pmd, address) (my_pte_alloc(mm, pmd) ? NULL : pte_offset_map(pmd, address))
page = alloc_pages(GFP_USER | __GFP_ZERO, get_order(cmd.num_pages * PAGE_SIZE));
if (!page) {
wuwa_err("failed to allocate pages\n");
ret = -ENOMEM;
goto out_mm;
}
pgd = pgd_offset(mm, cmd.start_addr);
if (pgd_none(*pgd) || pgd_bad(*pgd)) {
wuwa_err("invalid pgd\n");
ret = -EINVAL;
goto out_page;
}
p4d = p4d_alloc(mm, pgd, cmd.start_addr);
if (!p4d) {
wuwa_err("failed to allocate p4d\n");
ret = -ENOMEM;
goto out_page;
}
pud = pud_alloc(mm, p4d, cmd.start_addr);
if (!pud) {
wuwa_err("failed to allocate pud\n");
ret = -ENOMEM;
goto out_page;
}
if (unlikely(pud_none(*pud))) {
if (my__pmd_alloc(mm, pud, cmd.start_addr)) {
wuwa_err("failed to allocate pmd\n");
ret = -ENOMEM;
goto out_page;
}
}
pmd = pmd_offset(pud, cmd.start_addr);
if (!pmd) {
wuwa_err("failed to get pmd\n");
ret = -ENOMEM;
goto out_page;
}
pte = my_pte_alloc_map(mm, pmd, cmd.start_addr);
if (!pte) {
wuwa_err("failed to allocate or map pte\n");
ret = -ENOMEM;
goto out_page;
}
if (!pte_none(*pte)) {
wuwa_warn("pte already in use at address 0x%lx\n", cmd.start_addr);
pte_unmap(pte);
ret = -EEXIST;
goto out_page;
}
pte_t new_pte = mk_pte(page, PAGE_SHARED);
new_pte = pte_mkwrite(new_pte);
new_pte = pte_mkdirty(new_pte);
new_pte = pte_mkyoung(new_pte);
set_pte(pte, new_pte);
pte_unmap(pte);
flush_tlb_all();
mmput(mm);
wuwa_info("successfully mapped page at address 0x%lx for pid %d\n", cmd.start_addr, cmd.pid);
return 0;
out_page:
if (page) {
__free_pages(page, get_order(cmd.num_pages * PAGE_SIZE));
}
out_mm:
mmput(mm);
return ret;
}
代码里面的
PAGE_SHARED
记得改成PAGE_SHARED_EXEC
,不然不带可执行的哦!
其中的start_addr
为需要映射到的地址,例如0x900000,看你心意了