学习交流, 请勿用于非法用途
续接上文内核层偷天换日之hook openat进行文件重定向
我们在分析一些软件的时候. 防护系统通过扫描/proc/self/maps,发现一些异常的so, 那么就会进行上报. 我们有很多方式解决这种问题, 但是我还是希望能够了解内核层底层原理的同时, 能够非常方便的解决此问题.

关于mmap的原理这里就不做详细的阐述, 这里面主要关注下文件映射, addr并不是完全相等映射, 只是相近而已. 通过官方的文档可以了解到.


进程的每段地址空间由struct vm_area_struct 描述。如上所示的每一行对应一个vm_area_struct结构体。一个文件可以映射到内存中,vm_area_struct的vm_file保存了文件描述符,这种映射称为有名映射,反之则为匿名映射
7857803000-785784b000
本段内存映射的虚拟地址空间范围, 对应vm_area_struct中的vm_start和vm_end
rw-p----权限
r-读,w-写 x-可执行 p-私有,对应vm_flags。
00000000
针对有名映射,指本段映射地址在文件中的偏移,对应vm_pgoff。对匿名映射而言,为vm_area_struct->vm_start
fd:00
所映射的文件所属设备的设备号,对应vm_file->f_dentry->d_inode->i_sb->s_dev。匿名映射为0。其中fd为主设备号,00为次设备号
00048000
文件的索引节点号,对应vm_file->f_dentry->d_inode->i_ino,与ls –i显示的内容相符。匿名映射为0。
/data/local/tmp/xxxx.so
所映射的文件名。对有名映射而言,是映射的文件名,对匿名映射来说,是此段内存在进程中的作用。[stack]表示本段内存作为栈来使用,[heap]作为堆来使用,其他情况则为无。
在内核层fs系统实现了/proc/self/maps设备驱动, 其中核心实现在task_mm.c的show_map_vma函数中.
通过上面的信息处理后, 所有的都没有对应的可执行权限了, 有了这种方法, 你就可以定制你自己的隐藏技术, maps文件便由你掌控

d90K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6&6K9r3&6#2i4K6u0r3L8%4l9%4N6q4)9J5c8Y4c8J5k6h3g2Q4x3V1k6V1k6i4k6Q4x3V1k6Z5K9h3c8W2i4K6g2X3K9h3&6B7k6h3y4@1i4K6g2X3M7$3)9`.
static void show_vma_header_prefix2(struct seq_file *m,
unsigned long start, unsigned long end,
vm_flags_t flags, unsigned long long pgoff,
dev_t dev, unsigned long ino)
{
seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
start,
end,
//文件权限相关, 这里把可执行权限隐藏掉, 伪造成匿名映射.或者其他系统映射都可以
flags & VM_READ ? 'r' : '-',
flags & VM_WRITE ? 'w' : '-',
'-',//flags & VM_EXEC ? 'x' : '-',
flags & VM_MAYSHARE ? 's' : 'p',
0,//pgoff,
0, 0, 0);//MAJOR(dev), MINOR(dev), ino);
}
static void
show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
{
struct mm_struct *mm = vma->vm_mm;
struct file *file = vma->vm_file;
vm_flags_t flags = vma->vm_flags;
unsigned long ino = 0;
unsigned long long pgoff = 0;
unsigned long start, end;
dev_t dev = 0;
const char *name = NULL;
char path_buf[PATH_MAX] = {0};
if (file) {
struct inode *inode = file_inode(vma->vm_file);
dev = inode->i_sb->s_dev;
ino = inode->i_ino;
pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
}
start = vma->vm_start;
end = vma->vm_end;
if(file) {
show_vma_header_prefix2(m, start, end, flags, pgoff, dev, ino);
} else {
show_vma_header_prefix(m, start, end, flags, pgoff, dev, ino);
}
/*
* Print the dentry name for named mappings, and a
* special [heap] marker for the heap:
*/
if (file) {
// 获取文件名称
char *path = d_path(&file->f_path, path_buf, sizeof(path_buf));
seq_pad(m, ' ');
if(strlen(path) > 0) {
if(strstr(path, "xxxx.so")) {
// 过滤xxxx.so
goto done;
}
}
seq_file_path(m, file, "\n");
goto done;
}
if (vma->vm_ops && vma->vm_ops->name) {
name = vma->vm_ops->name(vma);
if (name)
goto done;
}
name = arch_vma_name(vma);
if (!name) {
if (!mm) {
name = "[vdso]";
goto done;
}
if (vma->vm_start <= mm->brk &&
vma->vm_end >= mm->start_brk) {
name = "[heap]";
goto done;
}
if (is_stack(vma)) {
name = "[stack]";
goto done;
}
if (vma_get_anon_name(vma)) {
seq_pad(m, ' ');
seq_print_vma_name(m, vma);
}
}
done:
if (name) {
seq_pad(m, ' ');
seq_puts(m, name);
}
seq_putc(m, '\n');
}
static void show_vma_header_prefix2(struct seq_file *m,
unsigned long start, unsigned long end,
vm_flags_t flags, unsigned long long pgoff,
dev_t dev, unsigned long ino)
{
seq_setwidth(m, 25 + sizeof(void *) * 6 - 1);
seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu ",
start,
end,
//文件权限相关, 这里把可执行权限隐藏掉, 伪造成匿名映射.或者其他系统映射都可以
flags & VM_READ ? 'r' : '-',
flags & VM_WRITE ? 'w' : '-',
'-',//flags & VM_EXEC ? 'x' : '-',
flags & VM_MAYSHARE ? 's' : 'p',
0,//pgoff,
0, 0, 0);//MAJOR(dev), MINOR(dev), ino);
}
static void
show_map_vma(struct seq_file *m, struct vm_area_struct *vma, int is_pid)
{
struct mm_struct *mm = vma->vm_mm;
struct file *file = vma->vm_file;
vm_flags_t flags = vma->vm_flags;
unsigned long ino = 0;
unsigned long long pgoff = 0;
unsigned long start, end;
dev_t dev = 0;
const char *name = NULL;
char path_buf[PATH_MAX] = {0};
if (file) {
struct inode *inode = file_inode(vma->vm_file);
dev = inode->i_sb->s_dev;
ino = inode->i_ino;
pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT;
}
start = vma->vm_start;
end = vma->vm_end;
if(file) {
[培训]科锐软件逆向54期预科班、正式班开始火爆招生报名啦!!!
最后于 2021-10-14 14:43
被github_yhnu编辑
,原因: