手游安全保护-基础篇
Posted '小五'
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手游安全保护-基础篇相关的知识,希望对你有一定的参考价值。
前言
手游发展至今,与外挂的对抗中,显然我们手游安全保护已占据上风,今天就带大家了解了解是如何区分玩家是否使用外挂的原理。
外挂原理分析
透视类外挂
此类外挂通常分为2种
1.修改游戏人物模型渲染数据实现地图穿透效果
2.读取游戏角色坐标绘制到屏幕上
对于第1种方式我们很轻易检测出来,由于通常模型数据并不是动态的,我们可以在初始化模型数据后,记录数据的crc32校验值,每隔一段时间对数据进行一次校验对比。
第2种方式,我们想要检测出来难度就大大增加了,因为我们并不能判断外挂是否访问了角色内存地址,再因为安卓并不像windows,游戏权限并没有外挂高,游戏仅限于用户态,然而,外挂程序通常为内核态,所以我们只能在应用本身想办法。
自瞄类外挂
此类型外挂实现方式很多,不过通常在FPS类游戏中实现方法是修改鼠标坐标(准星),moba类游戏中则是修改技能坐标,由于准星数据是动态的,我们检测难度也是很高,不过,这怎么能难到我们聪明绝’顶’的工程师呢?
我们首先需要找到此类外挂的特点,比如,准星会追随角色坐标,我们可以对子弹预瞄轨迹,命中率,爆头率等数据进行计算得知此玩家是否开了自瞄挂,但是,对于那种技术好的玩家,又可能会误判,调整检测阀值又可能会漏网一些外挂玩家,怎么办呢?时间有限,我们下期文章再说。
进入主题
归根结底,上述的自瞄类外挂和透视类外挂都需要读取游戏内角色坐标,所以,理论来说,只要能够判断角色地址是否被第三方工具访问,便能解决此类问题。如何解决呢?
我们先来了解一下Linux内存管理。
在linux操作系统有虚拟内存与物理内存的概念。
虚拟内存与物理内存的关系图
页表工作原理
我们的cpu想访问虚拟地址所在的虚拟页(VP3),根据页表,找出页表中第三条的值.判断有效位。 如果有效位为1,DRMA缓存命中,根据物理页号,找到物理页当中的内容,返回。
若有效位为0,参数缺页异常,调用内核缺页异常处理程序。内核通过页面置换算法选择一个页面作为被覆盖的页面,将该页的内容刷新到磁盘空间当中。然后把VP3映射的磁盘文件缓存到该物理页上面。然后页表中第三条,有效位变成1,第二部分存储上了可以对应物理内存页的地址的内容。
缺页异常处理完毕后,返回中断前的指令,重新执行,此时缓存命中,执行1。
将找到的内容映射到告诉缓存当中,CPU从告诉缓存中获取该值,结束。
有一篇博客已经将此相关内容讲解的很详细了,传送门:虚拟内存与物理内存的联系与区别
回归主题,上面所述有个关键词叫缺页异常
比如我们调用mmap来映射内存,为了防止内存无效分配,该内存空间在未访问时是不会创建物理内存页的。当程序需要使用这块内存区域时,会触发缺页中断,然后系统才会创建物理内存页。
由此我们诞生了一种近乎完美的外挂检测方案。通过在对局角色数组中插入缺页内存地址,使外挂无法识别是否是正常游戏角色数据,从而触发检测。
在这里我们需要学习一个函数:mincore
#include <unistd.h>
#include <sys/mman.h>
int mincore(void *start, size_t length, unsigned char *vec);
函数说明:
mincore()请求向量,描述文件的哪些页位于核心,可以在没有磁盘访问的情况下读取。内核将为长度后面的字节开始地址。返回时,内核将填满VEC使用字节,其中最小有效位指示页是否为核心驻留。
官方介绍大家可能没看明白,看下面案例可能就明白了
int pageSize = getpagesize();
unsigned char vec = 0;
unsigned long start = addr & (~(pageSize - 1));
mincore((void *)start, pageSize, &vec);
if (vec == 1)
{
printf("内存页:%p 存在与物理内存空间",addr);
}else{
printf("内存页:%p 不存在与物理内存空间",addr);
}
到这里就很清晰了,我们通过判断在对局角色插入的缺页内存地址,即可知道玩家是否使用了外挂!
例如腾讯手游,网易手游等都是使用了此方案。
由于时间关系,也就不放相关案例了,下一期讲解外挂是如何使用各种注入实现hook修改游戏函数以及如何防止游戏被hook,点个关注不迷路。
转载请注明出处:https://xiaowu.blog.csdn.net/article/details/119471016
以上是关于手游安全保护-基础篇的主要内容,如果未能解决你的问题,请参考以下文章