深入理解内存读写检测机制

声明:本人业余研究检测纯属兴趣爱好,请勿用于非法用途。否则后果自行承担。

写内存的检测这里就不多做介绍了,这篇文章主要介绍读内存的检测。

首先读内存在Linux、安卓上是可以被检测的。要读懂下面的内容的话可能要先了解一下缺页中断,有关缺页中断的知识可以自己百度搜。
一、检测原理
事先声明一段内存(自己永远不去读),然后随机插入到正常内存中,利用mincore函数不断检测这段内存是否在物理内存中。如果在物理内存中,则说明有人非法读取了我们的内存。因为这段内存我们自己没有读过,它不应该出现在物理内存中。
二、反检测
了解了检测原理,接下来就简单了。
我们只需要提前知道哪些内存不在物理内存中就可以提前避免了。问题是,怎么避免呢?有三种方法。
1.注入或者劫持游戏后,在目标内部调用mincore检测所有需要读取的内存。不在物理内存则跳过。
2.读取目标/proc/pid/pagemap文件。这个文件怎么读?什么格式?我就不多解释了,直接贴代码。

bool MissingPageQuery(Pointer vaddr)
{
    Pointer vir_index=vaddr/PAGE_SIZE;
    //Pointer m_offset=vaddr%PAGE_SIZE;
    Pointer file_offset=vir_index*ITEM_SIZE;  //file inner offer
    Pointer item_bit = 0;
    struct iovec iov;
    iov.iov_base = &item_bit;
    iov.iov_len = ITEM_SIZE;
    //lseek(fd,file_offset,SEEK_SET);
    //syscall(SYS_readv,fd, &iov, 1);
    syscall(SYS_preadv,fd_pagemap, &iov, 1, file_offset);
    if(item_bit & (uint64_t)1<<63){
    	//不是缺页状态可以读取
        return true;
    }
    //是缺页状态不可以读取
    return false;
}

为什么要用preadv呢?因为pagemap一般是被监控的文件,用read会直接被检测到。

3.直接读取检测列表
前面说了,检测内存需要创建一段自己不读的内存作为陷阱插入正常内存当中。这段内存自己也不能读,所以检测者肯定需要创建一个表来告诉自己的程序哪些内存自己不去读。因此我们也可以顺其道而行之,读取检测者的检测表。
当然,这需要提前研究检测列表的结构。因为有些检测者已经意识到这个问题,所以会尽可能让检测表庞大而复杂。
那么怎么知道检测结构?在不使用前两种方法协助的情况下,直接挨个查看世界数组的每个地址,将每个地址在ca内存中搜索一下,如果存在于ca内存中的多个地方,基本可以判断这是一个检测。当然也有少部分在ca内存中的地址不是检测。当你拿到检测地址后,可以先找到检测的基址。找到基址后就可以研究检测数组结构了。有的可能是个简单的数组,有的则可能是多重结构体。
第3种挨个搜索每个地址是否在ca内存中似乎有些麻烦!有没有办法快速得知?有!一般ue4类型的话,leve下面都还有一个数组记录所有地址。写个程序对比两个数组。

给检测者们的一些建议:
1.检测表中再插入陷阱是可行的,但套娃操作只能解决一时。还是要尽可能让检测表失去可读性等反逆向常用手段。
2.用于检测的内存段要尽可能伪装成正常内存,这需要开发者有一些内存操作经验。以避免反检测者通过非常规手段过掉检测。

  • 13
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值