前言
手游发展至今,出现了许多的外挂,今天我们就来说说那些如果去对抗那些透视类外挂。
进入
我们都知道透视类外挂都需要读取游戏内角色坐标,所以,理论来说,只要知道角色地址是否被其他工具访问,便能解决此类问题。如何解决呢?
揭秘
当我们了解 Linux内存管理
后,会学习到一个新的词 缺页异常
,比如我们调用mmap来映射内存,为了防止内存无效分配,该内存空间在未访问时是不会创建物理内存页的。当程序需要使用这块内存区域时,会触发缺页中断,然后系统才会创建物理内存页。由此我们诞生了一种近乎完美的外挂检测方案。通过在对局角色数组中插入缺页内存地址,使外挂无法识别是否是正常游戏角色数据,从而触发检测。
在这里我们需要学习一个函数:mincore
#include <unistd.h>
#include <sys/mman.h>
int mincore(void *start, size_t length, unsigned char *vec);
函数说明:
mincore()请求向量,描述文件的哪些页位于核心,可以在没有磁盘访问的情况下读取。内核将为长度后面的字节开始地址。返回时,内核将填满VEC使用字节,其中最小有效位指示页是否为核心驻留。
使用
1.mmap 申请内存
char * memory= nullptr;
memory= (char*)mmap(nullptr,0x4000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
如果不对 memory 进行读写,那么 memory 默认为缺页状态
2.mincore 判断
int pageSize = getpagesize();
unsigned char vec = 0;
//memory[0]=1; 这个操作会把memory改为非缺页状态
unsigned long addr= reinterpret_cast<unsigned long>(memory);
unsigned long start = addr & (~(pageSize - 1));
mincore((void *)start, pageSize, &vec);
if (vec == 1)
{
LOGD("内存页:%p 存在于物理内存空间",addr);
}else{
LOGD("内存页:%p 不存在于物理内存空间",addr);
}
到这里就很清晰了,我们通过判断在对局角色插入的缺页内存地址,即可知道玩家是否使用了外挂!例如腾讯手游,网易手游等都是使用了此方案。当然,还有使用读取 /proc/pid/pagemap
的方式去判断。这里我就不多说了。下篇文章我会说说如何去对抗这种方案。
3 条评论
后面的内容呢-.- 怎么对抗
发了发了,可以看看。
好吧