本篇文章所提及的所有内容仅用作于游戏功能实现的原理性研究,禁止把文章中所提及的内容用到实际的游戏当中;这会绝对性的破坏游戏平衡机制,因读者阅读本篇文章后所产生的任何法律责任与本篇文章作者及博客主无任何直接与间接性责任。

APEX Legends 介绍

《Apex英雄》是由《泰坦天降》制作组Respawn研发的一款免费大逃杀游戏。于2019年2月5日发行。玩家在游戏中将扮演外星战场上的星空战士。目前《Apex英雄》发行商EA透露手游版本已在计划中并有可能实现跨平台对战。
《Apex英雄》共有有8个传奇角色,三名玩家组成一个小队,第一个赛季将从3月份开始,并会推出季票,每个赛季会带来新的武器、角色和皮肤等内容。

反作弊系统 Easy Anti-Cheat

Easy Anti Cheat缩写为EAC,是多人游戏中使用的Anti-Cheat。
该工具开发于2006年,供FT2,CS,CS:ZORE,CS:S,CS:GO,Magica:巫师大战,堡垒之夜,Apex英雄等不同的多人服务器托管者使用玫瑰和维京人之战。
该工具还用于诸如Rust&Fortnite之类的人口较高的游戏中。作为玩游戏所需的软件。

多年来,它受到了大型游戏公司(如Ubisoft,Xbox Game Studios,Crytek,Aeria Games等)的青睐。

该工具当前支持多种操作系统,包括:Windows(7、8、8.1、10),SteamOS和macOS。
EAC总公司/开发人员“ KAMU”已于(Epic Games)于2018年收购。

反作弊能力
EAC具有自动禁令列表和内核驱动程序,可进行自动数据分析和防止作弊。
EAC着重于作弊预防和检测这两个方面。但是似乎倾向于使作弊的发展更加困难。
EAC还提供强大的HWID跟踪和禁止功能。
值得一提的是,尽管EAC确实支持Linux,但其有效性低于Windows。

由于受到反作弊系统EAC的保护,APEX无法直接通过微软提供的WindowsAPI来修改游戏内存,这会是相当危险的行为因为通常会在进入游戏后直接被EAC检测到并封号;实验过程中我通过Windows内核驱动通过内核来修改游戏内存达到作弊效果。

思路与流程

人物发光也就是Glow的思路是首先从游戏中获取到人物地址,再从人物地址中读取Glow的偏移值,最后写入RGB数值(RGB地址是不同的3个地址)到地址当中。

  1. 获取游戏进程r5apex.exe的地址
  2. 获取到游戏内实体的地址
  3. 获取到游戏自身玩家的地址
  4. 判断获取到的实体是否是人物
  5. 根据玩家地址获取发光地址
  6. 根据发光地址获取到启用发光以及RGB的地址
  7. 写入对应数值

部分代码片段

在游戏中我们需要通过循环一定的次数来不断获取游戏内的实体地址,循环次数我们就按照100次来处理,游戏内的最多游戏玩家数量不会超过60。

//根据循环次数的数值来根据ID获取实体地址
    DWORD64 GetEntityById(int Ent, DWORD64 Base)
    {
    
        DWORD64 EntityList = Base/*游戏地址*/ + 实体列表偏移;
        DWORD64 BaseEntity = Mem->ReadTypeData<DWORD64>(EntityList);
        if (!BaseEntity)
            return NULL;
    
        return Mem->ReadTypeData<DWORD64>(EntityList + (Ent << 5));
    }

获取游戏中本地玩家也就是自身玩家的地址,获取到之后可以做一些判断比如自己不发光或者自己队友不发光等;方法有两种其一是通过循环遍历的方式来判断获取到地址另一种是直接根据本地玩家的偏移来获取。

 //方法1
    DWORD64 GetLocalEntity() {
    
        return Mem->ReadTypeData<DWORD64>(Base + 本地玩家偏移);
    }
    //方法2
    DWORD64 GetLocalEntity() {
    
        DWORD64 LocalEntityId = Mem->ReadTypeData<DWORD64>(Base + 本地玩家ID偏移);
    
        for (auto i = 0; i < 100; ++i)
        {
            DWORD64 Entity = GetEntityById(i, Base);
            if (Entity)
                if (Mem->ReadTypeData<DWORD64>(Entity + 0x8) == LocalEntityId)
                    return Entity;
        }
    }

由于游戏中的实体有很多不一定获取到的实体地址就是玩家的实体地址,所以还需要继续通过获取实体名字的方式来判断是不是玩家

bool IsPlayer(){
        uint64_t name = Mem->ReadTypeData<uint64_t>(centity + 实例名称偏移);
        if (name != 125780153691248)
            return false;
    
        return true;
    }

在获取到我们需要的人物地址之后,就是向几个地址写入对应的值来实现发光透视的效果。

void EnableGlow(DWORD64 Entity, float r, float g, float b) {
    
        Mem->WriteTypeData<bool>(Entity + 启用发光偏移, true);
        Mem->WriteTypeData<int>(Entity + 发光上下文偏移, 1);
        Mem->WriteTypeData<float>(Entity + 颜色R偏移, r);
        Mem->WriteTypeData<float>(Entity + 颜色G偏移, g);
        Mem->WriteTypeData<float>(Entity + 颜色B偏移, b);
    
        for (int offset = 位置偏移1; offset <= 位置偏移2; offset += 0x4)
            Mem->WriteTypeData<float>(Entity + offset, FLT_MAX);
    
        Mem->WriteTypeData<float>(Entity + 位置距离偏移, FLT_MAX);
    }

游戏内效果

APEX GLOW

项目完整代码

蹩脚代码,不足开源,自己动手,丰衣足食。

最后修改:2021 年 01 月 13 日 11 : 00 PM
如果觉得我的文章对你有用,请随意赞赏