Riru Hide 学习

mmap,/proc/maps小知识

Posted by BC on November 9, 2020

原理

​ 把这一块内存设置为MAP_ANONYMOUS,使其在/proc/maps的pathname列中的字符串消失。

​ mmap原理:

​ MAP_ANONYMOUS建立匿名映射。此时会忽略参数fd,不涉及文件,而且映射区域无法和其他进程共享。

​ 此时OS不认为这块内存是从文件读取的,就没有pathname。

代码

static int do_hide(hide_struct *data) {
    auto procstruct = data->original;
    auto start = (uintptr_t) procstruct->addr_start;
    auto end = (uintptr_t) procstruct->addr_end;
    auto length = end - start;
    int prot = get_prot(procstruct);

    // backup
    data->backup_address = (uintptr_t) _mmap(nullptr, length, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    if (data->backup_address == (uintptr_t) MAP_FAILED) {
        return 1;
    }
    LOGD("%" PRIxPTR"-%" PRIxPTR" %s %ld %s is backup to %" PRIxPTR, start, end, procstruct->perm, procstruct->offset, procstruct->pathname,
         data->backup_address);

    if (!procstruct->is_r) {
        LOGD("mprotect +r");
        _mprotect((void *) start, length, prot | PROT_READ);
    }
    LOGD("memcpy -> backup");
    memcpy((void *) data->backup_address, (void *) start, length);

    // munmap original
    LOGD("munmap original");
    munmap((void *) start, length);

    // restore
    LOGD("mmap original");
    _mmap((void *) start, length, prot, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
    LOGD("mprotect +w");
    _mprotect((void *) start, length, prot | PROT_WRITE);
    LOGD("memcpy -> original");
    memcpy((void *) start, (void *) data->backup_address, length);
    if (!procstruct->is_w) {
        LOGD("mprotect -w");
        _mprotect((void *) start, length, prot);
    }
    return 0;
}

不足

​ 对于扫描自身全部内存的检测没有用处。比如MTP。