原理
把这一块内存设置为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。