手游安全总结笔记

第一篇 概述
安全风险:静态修改文件、动态修改游戏逻辑、篡改协议、游戏盗号、恶意发言、工作室等。
手游通常包括:代码、资源、数据配置。代码是游戏楼及核心部分;资源包括:图画、声音、动画、3D模型、渲染等;数据配置指游戏中各种属性数值信息。
面临风险:
(1)静态修改文件包括修改游戏资源(最终影响游戏逻辑)、修改代码(大部分c++、动态链接库方式保存)、修改配置。
(2)动态篡改逻辑:常规的会伴随注入操作,利用技术手段将操作系统中的动态链接库加载到目标进程,通过执行动态链接库中的代码来实现某些功能。Android下的注入大体分两种包括:通过注入Zygote进程渗透到目标游戏进行中;直接注入目标游戏进行。IOS使用mobilesubstrate组件将动态链接库注入游戏进程。挂钩操作目的是为了拦截游戏逻辑。
①修改代码:特别是已被root的手机,游戏与恶意外挂权限不对等;本地代码修改;修改动态内存代码。
②修改数据:修改器,注入式修改、非注入式修改。Ios是注入进程再修改进程内数据;android则/proc/pid/maps(可以看到每个进程独立的内存地址)文件遍历r表示模块,再读写/proc/pid/mem(访问其他进程的内存变量)文件达到与注入式修改一样的效果。
(3)游戏协议:篡改游戏协议、重发游戏协议 在网络层或传输层拦截
修改游戏伤害值改变敌方伤害无效—>游戏设计为不信任客户端数据-可以多次重发相同协议,造成多次伤害
(4)游戏盗号
账号登录转移财产、少见也需重视
(5)恶意发言
(6)工作室(辅助插件、外挂、高质账号、系统失衡)

脱机挂(非法客户端)、模拟器、脚本精灵(自动刷币、经验)

辅助版外挂:专业插件(定制化外挂)、通用外挂
WPE抓包工具

辅助版外挂原理;
1. 专用插件 利用注入技术将功能模块注入游戏进程空间中,并执行功能模块的入口函数。 HOOK java层、汇编层
2. 通用工具

破解版外挂原理:逻辑代码:dll、so
数据资源:无脑替换和分析调试(资源作用、加密方式)

Arm汇编、c/c++(游戏引擎主逻辑编写)、android开发(最低要求程序生命周期和native程序开发)、ios开发(基于mobilesubstrate越狱开发)
游戏引擎:unity 3D (大部分c#开发),其游戏主逻辑大多打包在aseets\bin\Data、Managred\Assembly-Csharp.dll中 ; Cocos2d-x:一般c++或Lua开发
静态分析:IDA、ILSpy(.net反汇编风险3D的dll)
动态调试:Android IDA;iOS gdb或11db(Mac下)+Debugsserver
Objective-C

静态修改:完整性校验或签名校验难绕过,需动态
动态修改;修改进程中的内存数据;修改进程中的代码;调用游戏函数。一般需将外挂模块注入目标进程,之后再通过直接写进程空间的方式修改数据,可以通过patch代码或动态Hook方式修改游戏逻辑。

第二篇环境搭建
Android调试android_server 附加方式调试、
IDA、APKTool、ILSpy、MatchOView、MobileSubStrate工具使用,后两者不熟ios的

第三篇游戏基础篇
游戏分类:MMORPG、FPS、卡牌、ARPG、MOBA、消除类游戏、RTS、跑酷类

游戏系统及开发:手游系统组成:登录系统、成长系统、战斗系统、经济系统、邮件系统、聊天系统。。。。。
手游开发:客户端开发、服务器开发
手游网络模式;强联网(安全性较高,服务器处理了大部分逻辑)、弱联网

游戏引擎:游戏的核心部件的功能代码,通用框架
游戏运行分四层:硬件层、第三方功能组件层、游戏引擎层、游戏逻辑层

游戏引擎子系统:①渲染系统:复杂、强大。渲染:将模型等二进制文件中的图像信息(轮廓、视点、纹理、照明)显示到屏幕输出的过程。 从模型生成图像。 消耗大部分计算量 游戏需实时渲染技术,实际中采用预渲染技术去获取静态物体贴图(场景烘培技术) FPS透视外挂,和渲染很大关系,此类外挂核心室关闭引擎的z-buffer(z缓存:是在为物件进行着色时,执行“隐藏面消除”工作的一项技术,所以隐藏物件背后的部分就不会被显示出来。 Z轴:3D像素 纵深度),导致墙壁后的人物也渲染出来
②音频系统 音频处理技术
③物理系统 主要模拟牛顿力学模型,直观理解:游戏中出现的碰撞、跳跃、飞行等 碰撞检测(两个或多个对象是否产生交集) 透视外挂,引擎接口室公开的,可以快速定位代码,修改碰撞检测逻辑,实现无敌、穿墙等。 像素级别碰撞检测
④人工智能 博弈游戏

移动游戏主流引擎:Cocos2D(免费开源的)、Unity3D(跨平台,简单选项就可以编译处不同版本(脚本中的宏控制区分不同平台),大部分c#开发,封装了很多引擎的功能特性)

游戏安全漏洞:根据漏洞原理,可将游戏漏洞分为:游戏逻辑漏洞、协议稳定型漏洞(Fuzz工具思想挖掘)、服务器校验疏忽漏洞。

第四篇 逆向篇
动态分析中经常需要使用 IDA的IDC脚本—最常用的是dump内存数据

第五篇 开发篇
游戏安全实验室文章:http://gslab.qq.com/article-162-1.html
注入、Hook、游戏进程模块信息获取、反调试的原理 需单独深入研究咯

  1. 从Android的开发来说,Android系统本身就提供给了我们两种开发模式,基于Android SDK的Java语言开发,基于AndroidNDK的Native C/C++语言开发。Hook的时候就必须在两个层面上来讨论。对于Native层来说Hook的难点其实是在理解ELF文件与学习ELF文件上,特别是对ELF文件不太了解的读者来说;对于Java层来说,Hook就需要了解虚拟机的特性与Java上反射的使用。
    Hook技术无论对安全软件还是恶意软件都是十分关键的一项技术,其本质就是劫持函数调用。但是由于处于Linux用户态,每个进程都有自己独立的进程空间,所以必须先注入到所要Hook的进程空间,修改其内存中的进程代码,替换其过程表的符号地址。在Android中一般是通过ptrace函数附加进程,然后向远程进程注入so库,从而达到监控以及远程进程关键函数挂钩。
    注入和hook有不可分的联系,通常说在一起了。HOOK的本质就是更改原有代码执行流程的方式, 将自定义代码嵌入到原有流程之中的一种方式.。
    Android下进程之间是隔离的,需要先注入到目标进程空间。需要将特定模块注入游戏进程。
    Android下手游注入:①ptrace注入 ②Zygote注入 ③感染ELF文件的注入
    Ptrace函数为一个进程提供监视和控制其它进程的方法,ptrace函数原型可以查下,使用request参数:附加、分离、读取远程进程寄存器环境、设置远程进程寄存器、远程进程内存读写等等。
    Ptrace注入目的是将外部模块注入游戏进程中,然后执行被注入模块的代码,就可以对游戏进程代码、数据进行修改了。
    Ptrace注入方式有两种:(1)使用ptrace将shellcode注入目标进程的内存空间,然后通过执行shellcode调用远程进程模块;(2)直接远程调用dlopen、dlsym等函数加载被注入模块并执行代码(request附加目标进程,保存进程所有寄存器值,nmap函数分配内存,向目标进程空间写入加载模块名和调用函数,dlopen代开注入模块,调用dlsym获取调用函数地址,调用被注入模块函数,detach)。
    Zygote注入:其他进程都是有Zygote fork的,Zygote是系统级进程
    原理:先把模块注入Zygote进程,注入完成后,在操作系统中启动应用程序,游戏进程是Zygote创建的,其进程中就包括已注入Zygote的模块了。
    目标须在注入Zygote成功后启动,才能被注入;在新启动程序执行前获取控制全,判断当前进程是否为目标进程。
    Zygote注入器是核心,其实现。。。
    判断当前进程是否是目标游戏进程也很重要
    感染ELF注入:修改可执行文件,添加自己的代码。是运行时先执行自己的代码,再回去执行逻辑。
    ELF格式

Program header table:保存了ELF文件加载过程中哥section的内存映射、依赖库等信息,时ELF感染的重要结构之一。 程序头表:只有ELF头的位置是固定的,其余各部分的位置、大小等信息由ELF头中的各项值来决定。
感染ELF文件注入原理:修改Program Header table的依赖库信息,添加自己定义的库文件,当游戏进程加载主逻辑模块时,也会加载自定义的库文件。
修改后 ,通常修改程序头表中位置信息,指向新的程序头表,而且也不影响后面数据偏移。 通常修改移动到文件末尾

Hook技术:系统消息Hook、API Hook(又分为基于汇编代码替换的Hook方式(内联hook,异常hook…)和使用Hook函数地址替换原始函数地址(导入表hook、虚表hook…))。
基于异常Hook:获取执行到某地址的寄存器信息或者某地址的访问者信息较优
原理:对我们想要监控的地址设一个非法指令(需对daimadaun 增加写权限),当执行到非法指令时系统会回掉我们预先设定好的异常处理函数(SIGILL异常机制),在这个异常处理函数里面恢复地址的原指令,获取context信息,然后打印寄存器信息即可。可以在获取到异常后,对目标地址的下一条指令做异常Hook操作,然后在下一个异常来临的时候,在异常处理函数中恢复当前异常指令并重新对目标地址写非法指令,以等待下一次目标地址被调用时获取我们想要的信息。
内联Hook:基于二进制汇编代码替换、底层 功能强大、效率高
针对函数的特定位置进行HOOK
原理:直接修改要hook位置的指令,让其跳转到桩函数,在桩函数中,会处理寄存器等信息,并调用相应hook点用户自定义的桩函数,在处理完桩函数后,会跳转执行原指令。
导入表Hook:
在Android PLT/GOT 符号重定向过程中,直接调用函数,整个过程是先到.plt,再到.got,最后才定位到真正的函数地址。那么只需要修改.got表中的函数指针,便可以实现Hook(https://blog.csdn.net/jltxgcy/article/details/52216727)
原理:锁定目标so及其导入函数,打开so文件,解析elf文件,着粗静态got表位置,,并找到内存中相应got表的位置,此时内存中的got表保存这导入函数的地址,读取目标函数地址,匹配got表每一项函数的入口地址是否相符,找到的话直接替换新的函数地址,完成hook。

2.游戏进程模块获取
模块信息:动态加载的链接库信息和可执行文件的信息。 模块基地址、模块名、模块路径…
外挂需提前获取游戏模块信息。
Proc文件系统,是一个虚拟文件系统(只有进程在运行过程中,该文件下才有相应的文件),不占用磁盘空间,而是由内核挂载到内存中。proc文件系统提供了内核配置、进程状态输出等功能,提供有关系统中进程的信息
模块遍历的运用场景非常广泛,如:获取自己进程的内存模块信息; 获取目标进程的内存模块信息;检查注入模块的信息;检查Hook模块的信息。

3.篡改游戏内容:代码或数据
针对不同的读写对象,通用的步骤就是寻找对象地址(位置)→获取相应权限→读写。局部数据hook获取修改时机
注入式:适合动态数据。基本的,静态分析到地址→改写页属性(mprotect函数改写属性)→直接修改内容,更进一步hook技术了。
全局数据直接系应该或内存改,局部数据hook获取修改时机
非注入式:修改静态代码、资源信息等,也可获取动态数据

  1. 反调试:Self-Dubugging反调试、轮询检测反调试、java层反调试。
    反调试详解:https://blog.csdn.net/qq_32400847/article/details/52798050
    Self-Dubugging:父进程创建一个子进程(调试器),并有这个子进程调试父进程。基石是ptrace函数。 高效实时、消耗少、不影响进程性能
    轮询检测:基于循环检测进程状态,实现简单,消耗资源。检测TracePid字段的值。
    Java层反调试主要正对基于JDWP协议的java代码调试器。JDWP(https://www.ibm.com/developerworks/cn/java/j-lo-jpda3/)Java Debug Wire Protocol,它定义了调试器(debugger)和被调试的 Java 虚拟机(target vm)之间的通信协议。

第六篇 实战篇
语言基础、逆向、看具体操作了
Mono:https://www.cnblogs.com/zhaoqingqing/archive/2016/08/12/5762867.html
http://www.mono-project.com/docs/about-mono/

你可能感兴趣的:(安全技术,手游安全,游戏安全)