Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >BattlEye堆栈行走(1)

BattlEye堆栈行走(1)

原创
作者头像
franket
修改于 2021-03-10 11:18:48
修改于 2021-03-10 11:18:48
7190
举报
文章被收录于专栏:技术杂记技术杂记

现代商业反作弊面临着专业游戏黑客生产中日益增强的竞争能力,因此已经开始采取可疑的方法来防止这种情况。在本文中,我们将介绍一个以前未知的反作弊模块,该模块被商业化的反作弊BattlEye推到播放器的一小部分。流行的理论是,由于该模块是动态推送的,因此该模块专门针对反向工程师,以监视视频游戏黑客工具的产生。

Shellcode ??

本文中的代码段是对我们从BattlEye转储和反混淆的shellcode 1的美化反编译。Shellcode在Tarkov的Escape中混乱时被推送到我的开发机器上。在这台机器上,各种逆向工程应用程序(例如x64dbg)已安装并经常运行,这可能引起了有关反作弊的注意。为了证实怀疑,启动了主要用于测试的辅助计算机,并在其上安装了来自Tarkov的Escape。有问题的shellcode没有推送到辅助计算机,该辅助计算机在与开发计算机相同的网络上运行,并使用相同的游戏帐户。

1 Shellcode指的是动态加载到正在运行的进程中的独立代码。

Secret Club的其他成员也经历过同样的磨难,这里的共同点是我们都是高度专业的反向工程师,这意味着大多数工程师都安装了相同的应用程序。为了给棺材钉上钉子,我让我的一些高中同学让我在玩Tarkov的Escape时在他们的机器上记录shellcode活动(使用虚拟机监控程序),但没有一个人收到有问题的模块。毋庸置疑,下面的代码段将显示针对某种技术上的少数派。

语境(

在本文中,您将看到对称为的函数的引用battleye::send。商业防欺诈使用此功能将信息从BEClient_x64/x86.dll游戏过程中的客户端模块发送到相应的游戏服务器。这将被解释为纯粹的“通过互联网发送数据”功能,并且仅将缓冲区作为输入。每个报告标题中的ID确定“数据包”的类型,可用于区分数据包。

设备驱动程序枚举

该例程有两个主要目的:枚举设备驱动程序和各个设备驱动程序使用的已安装证书。尽管前者有些令人惊讶,但此shellcode会将与任意“邪恶”过滤器匹配的任何设备驱动程序(!!)上传到游戏服务器。这意味着,如果您的专有,绝密且完全不相关的设备驱动程序中包含单词“ Callback”,则shellcode会将文件的全部内容上传到磁盘上。这是一个隐私问题,因为它是设备驱动程序的一个相对常用的词,该设备驱动程序安装了用于监视事件的内核回调。

证书枚举器将计算机上设备驱动程序使用的所有证书的内容直接发送到游戏服务器:

代码语言:txt
AI代码解释
复制
  // ONLY ENUMERATE ON X64 MACHINES
  GetNativeSystemInfo(&native_system_info);
  if ( native_system_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 )
  {
    if ( EnumDeviceDrivers(device_list, 0x2000, &required_size) )
    {
      if ( required_size <= 0x2000u )
      {
        report_buffer = (__int8 *)malloc(0x7530);
        report_buffer[0] = 0;
        report_buffer[1] = 0xD;
        buffer_index = 2;

        // DISABLE FILESYSTEM REDIRECTION IF RUN IN WOW64
        if ( Wow64EnableWow64FsRedirection )
          Wow64EnableWow64FsRedirection(0);

        // ITERATE DEVICE DRIVERS
        for ( device_index = 0; ; ++device_index )
        {
          if ( device_index >= required_size / 8u /* MAX COUNT*/ )
            break;

          // QUERY DEVICE DRIVER FILE NAME
          driver_file_name_length = GetDeviceDriverFileNameA(
                                      device_list[device_index],
                                      &report_buffer[buffer_index + 1],
                                      0x100);
          report_buffer[buffer_index] = driver_file_name_length;

          // IF QUERY DIDN'T FAIL
          if ( driver_file_name_length )
          {
            // CACHE NAME BUFFER INDEX FOR LATER USAGE
            name_buffer_index = buffer_index;

            // OPEN DEVICE DRIVER FILE HANDLE
            device_driver_file_handle = CreateFileA(
                                          &report_buffer[buffer_index + 1],
                                          GENERIC_READ,
                                          FILE_SHARE_READ,
                                          0,
                                          3,
                                          0,
                                          0);

            if ( device_driver_file_handle != INVALID_HANDLE_VALUE )
            {
              // CONVERT DRIVER NAME
              MultiByteToWideChar(
                0,
                0,
                &report_buffer[buffer_index + 1],
                0xFFFFFFFF,
                &widechar_buffer,
                0x100);
            }
            after_device_driver_file_name_index = buffer_index + report_buffer[buffer_index] + 1;

            // QUERY DEVICE DRIVER FILE SIZE
            *(_DWORD *)&report_buffer[after_device_driver_file_name_index] = GetFileSize(device_driver_file_handle, 0);
            after_device_driver_file_name_index += 4;
            report_buffer[after_device_driver_file_name_index] = 0;
            buffer_index = after_device_driver_file_name_index + 1;

            CloseHandle(device_driver_file_handle);

            // IF FILE EXISTS ON DISK
            if ( device_driver_file_handle != INVALID_HANDLE_VALUE )
            {
              // QUERY DEVICE DRIVER CERTIFICATE
              if ( CryptQueryObject(
                     1,
                     &widechar_buffer,
                     CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED,
                     CERT_QUERY_FORMAT_FLAG_BINARY,
                     0,
                     &msg_and_encoding_type,
                     &content_type,
                     &format_type,
                     &cert_store,
                     &msg_handle,
                     1) )
              {
                // QUERY SIGNER INFORMATION SIZE
                if ( CryptMsgGetParam(msg_handle, CMSG_SIGNER_INFO_PARAM, 0, 0, &signer_info_size) )
                {
                  signer_info = (CMSG_SIGNER_INFO *)malloc(signer_info_size);
                  if ( signer_info )
                  {
                    // QUERY SIGNER INFORMATION
                    if ( CryptMsgGetParam(msg_handle, CMSG_SIGNER_INFO_PARAM, 0, signer_info, &signer_info_size) )
                    {
                      qmemcpy(&issuer, &signer_info->Issuer, sizeof(issuer));
                      qmemcpy(&serial_number, &signer_info->SerialNumber, sizeof(serial_number));
                      cert_ctx = CertFindCertificateInStore(
                                                   cert_store,
                                                   X509_ASN_ENCODING|PKCS_7_ASN_ENCODING,
                                                   0,
                                                   CERT_FIND_SUBJECT_CERT,
                                                   &certificate_information,
                                                   0); 
                      if ( cert_ctx )
                      {
                        // QUERY CERTIFICATE NAME
                        cert_name_length = CertGetNameStringA(
                                             cert_ctx,
                                             CERT_NAME_SIMPLE_DISPLAY_TYPE,
                                             0,
                                             0,
                                             &report_buffer[buffer_index],
                                             0x100);
                        report_buffer[buffer_index - 1] = cert_name_length;
                        if ( cert_name_length )
                        {
                          report_buffer[buffer_index - 1] -= 1;
                          buffer_index += character_length;
                        }
                        // FREE CERTIFICATE CONTEXT
                        CertFreeCertificateContext(cert_ctx);
                      }
                    }
                    free(signer_info);
                  }
                }
                // FREE CERTIFICATE STORE HANDLE
                CertCloseStore(cert_store, 0);
                CryptMsgClose(msg_handle);
              }

              // DUMP ANY DRIVER NAMED "Callback????????????" where ? is wildmark
              if ( *(_DWORD *)&report_buffer[name_buffer_index - 0x11 + report_buffer[name_buffer_index]] == 'llaC'
                && *(_DWORD *)&report_buffer[name_buffer_index - 0xD + report_buffer[name_buffer_index]] == 'kcab'
                && (unsigned __int64)suspicious_driver_count < 2 )
              {
                // OPEN HANDLE ON DISK
                file_handle = CreateFileA(
                    &report_buffer[name_buffer_index + 1],
                    0x80000000,
                    1,
                    0,
                    3,
                    128,
                    0);

                if ( file_handle != INVALID_HANDLE_VALUE )
                {
                  // INITIATE RAW DATA DUMP
                  raw_packet_header.pad = 0;
                  raw_packet_header.id = 0xBEu;
                  battleye::send(&raw_packet_header, 2, 0);

                  // READ DEVICE DRIVER CONTENTS IN CHUNKS OF 0x27EA (WHY?)
                  while ( ReadFile(file_handle, &raw_packet_header.buffer, 0x27EA, &size, 0x00) && size )
                  {
                    raw_packet_header.pad = 0;
                    raw_packet_header.id = 0xBEu;
                    battleye::send(&raw_packet_header, (unsigned int)(size + 2), 0);
                  }

                  CloseHandle(file_handle);
                }
              }  
            }
          }
        }

        // ENABLE FILESYSTEM REDIRECTION
        if ( Wow64EnableWow64FsRedirection )
        {
          Wow64EnableWow64FsRedirection(1, required_size % 8u);
        }

        // SEND DUMP
        battleye::send(report_buffer, buffer_index, 0);
        free(report_buffer);
      }
    }
  }

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
暂无评论
推荐阅读
编辑精选文章
换一批
[源码解析] 模型并行分布式训练Megatron (2) --- 整体架构
NVIDIA Megatron 是一个基于 PyTorch 的分布式训练框架,用来训练超大Transformer语言模型,其通过综合应用了数据并行,Tensor并行和Pipeline并行来复现 GPT3,值得我们深入分析其背后机理。
罗西的思考
2022/05/09
2.9K0
[源码解析] 模型并行分布式训练Megatron (2) --- 整体架构
[源码解析] 模型并行分布式训练Megatron (5) --Pipedream Flush
NVIDIA Megatron 是一个基于 PyTorch 的分布式训练框架,用来训练超大Transformer语言模型,其通过综合应用了数据并行,Tensor并行和Pipeline并行来复现 GPT3,值得我们深入分析其背后机理。本系列有 5 篇文章,通过论文和源码和大家一起学习研究。本文将看看 Megatron 如何给流水线各个阶段安排执行执行序列。
罗西的思考
2022/05/09
1.8K0
[源码解析] 模型并行分布式训练Megatron (5) --Pipedream Flush
[源码解析] 模型并行分布式训练 Megatron (3) ---模型并行实现
NVIDIA Megatron 是一个基于 PyTorch 的分布式训练框架,用来训练超大Transformer语言模型,其通过综合应用了数据并行,Tensor并行和Pipeline并行来复现 GPT3,值得我们深入分析其背后机理。
罗西的思考
2022/11/28
2.3K0
[源码解析] 模型并行分布式训练 Megatron (3) ---模型并行实现
大型语言模型(LLMs)是怎样“学习”的?一封给网络工程师的大模型指南
数字时代,人工智能(AI)及其相关技术正日益成为许多领域的热门话题。其中,生成式人工智能(Gen AI)和大型语言模型(LLMs)引起了广泛的兴趣和讨论。然而,尽管这些术语在科技界和专业领域中频繁出现,网络工程师对其的理解却不多。
星融元Asterfusion
2024/05/09
8451
大型语言模型(LLMs)是怎样“学习”的?一封给网络工程师的大模型指南
深入理解Pytorch中的分布式训练
作者:台运鹏 (正在寻找internship...) 主页:https://yunpengtai.top
zenRRan
2023/01/12
1.4K0
深入理解Pytorch中的分布式训练
[源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎
在前文中,我们介绍了PipeDream的总体架构,Profile阶段,计算分区阶段和模型转换阶段,本文我们介绍运行时执行引擎,这是一个统一基础设施层。
罗西的思考
2021/09/14
7520
[源码解析] 深度学习流水线并行 PipeDream(4)--- 运行时引擎
[源码解析] PyTorch 分布式(18) --- 使用 RPC 的分布式管道并行
在前面的文章之中,我们已经学习了PyTorch 分布式的基本模块,接下来我们通过几篇文章来看看如何把这些模块应用到实践之中,顺便把PyTorch分布式逻辑整体梳理一下。本文介绍如何使用 RPC 来完成分布式管道并行。
罗西的思考
2021/12/21
8260
[源码解析] PyTorch 分布式(18) --- 使用 RPC 的分布式管道并行
【AI系统】混合并行
混合并行(HybridParallel)是一种用于分布式计算的高级策略,它结合了数据并行和模型并行的优势,以更高效地利用计算资源,解决深度学习中的大模型训练问题。混合并行不仅能提高计算效率,还能在有限的硬件资源下处理更大的模型和数据集。在深度学习中,数据并行和模型并行各自有其适用的场景和局限性。数据并行适用于训练样本较多而模型较小的情况,通过将数据集分割成多个子集并在不同的设备上同时训练来提高训练速度。而模型并行则适用于模型较大无法单独放入一个设备内存的情况,通过将模型切分成不同的部分分别在多个设备上进行计算。混合并行通过将这两种并行方式结合,加速计算和处理超大模型,从而在各种硬件条件下实现高效的神经网络模型训练。现主流的混合并行为 3D 混合并行,但由于他们一般都在大规模分布式深度学习训练框架中使用,如:Deepspeed 和 Colossal AI,而不是 AI 框架,因此只进行简单讨论。
用户11307734
2024/12/09
2230
[源码解析] 模型并行分布式训练Megatron (1) --- 论文 & 基础
NVIDIA Megatron 是一个基于 PyTorch 的分布式训练框架,用来训练超大Transformer语言模型,其通过综合应用了数据并行,Tensor并行和Pipeline并行来复现 GPT3,值得我们深入分析其背后机理。
罗西的思考
2022/05/09
3.3K0
[源码解析] 模型并行分布式训练Megatron (1) --- 论文 & 基础
[源码解析] PyTorch分布式优化器(3)---- 模型并行
本系列介绍分布式优化器,分为三篇文章,分别是基石篇,DP/DDP/Horovod 之中数据并行的优化器,PyTorch 分布式优化器,按照深度递进。本文介绍PyTorch 分布式优化器和PipeDream之中的优化器,主要涉及模型并行(流水线并行)。
罗西的思考
2021/12/10
1.5K0
[源码解析] PyTorch分布式优化器(3)---- 模型并行
[源码解析] PyTorch 分布式之 ZeroRedundancyOptimizer
PyTorch Zero Redundancy Optimizer 是一类旨在解决数据并行训练和模型并行训练之间权衡问题的算法。Zero Redundacy Optimizer 的思想来源于微软的ZeRO,具体实现是基于 Fairscale 的OSS。
罗西的思考
2022/05/09
1K0
[源码解析] PyTorch 分布式之 ZeroRedundancyOptimizer
Pytorch 分布式训练
即进程组。默认情况下,只有一个组,一个 job 即为一个组,也即一个 world。
肉松
2020/09/07
2.5K0
Pytorch 分布式训练
[源码解析] 深度学习流水线并行 PipeDream(5)--- 通信模块
在前文中,我们介绍了PipeDream的总体架构,Profile阶段,计算分区阶段,模型转换阶段和运行时引擎,本文我们介绍PipeDream 的通信模块,通信模块是引擎的基础,同时也是PyTorch DDP,P2P 如何使用的一个万花筒和完美示例。
罗西的思考
2021/09/14
6650
PyTorch 2.2 中文官方教程(十九)
本教程使用 Resnet50 模型演示了如何使用torch.distributed.rpc API 实现分布式管道并行。这可以看作是单机模型并行最佳实践中讨论的多 GPU 管道并行的分布式对应。
ApacheCN_飞龙
2024/02/05
4030
PyTorch 2.2 中文官方教程(十九)
[源码解析] 快手八卦 --- 机器学习分布式训练新思路(2)
“Bagua“ 是快手和苏黎世理工(ETH Zürich)联合开发的分布式训练框架。其专门针对分布式的场景设计特定的优化算法,实现算法和系统层面的联合优化,力图极致化分布式训练的效率。其特点是:
罗西的思考
2022/05/09
5390
[源码解析] 快手八卦 --- 机器学习分布式训练新思路(2)
PyTorch分布式训练进阶:这些细节你都注意到了吗?
导语 | pytorch作为目前主流的深度学习训练框架之一,可以说是每个算法同学工作中的必备技能。此外,pytorch提供了极其方便的API用来进行分布式训练,由于最近做的工作涉及到一些分布式训练的细节,在使用中发现一些之前完全不会care的点,现记录于此,希望对有需求的同学有所帮助。 本文包含: pytorch分布式训练的工作原理介绍。 一些大家平时使用时可能不太注意的点,这些点并不会导致直观的bug或者训练中断,但可能会导致训练结果的偏差以及效率的降低。 同时结合某些场景,介绍更为细粒度(group)的
腾讯云开发者
2022/05/13
1.1K0
PyTorch分布式训练进阶:这些细节你都注意到了吗?
[ai学习笔记]分布式训练原理:DeepSeek千卡集群通信优化策略
在人工智能和深度学习快速发展的当下,模型的规模和复杂度不断攀升,对计算资源的需求也日益增长。为了在有限的时间内训练出高性能的深度学习模型,分布式训练技术应运而生。分布式训练通过将模型和数据分布在多个计算节点上并行处理,大大加速了训练过程。DeepSeek等先进的分布式训练系统在大规模集群环境下,通过优化通信策略,实现了高效的节点间通信和协同训练,能够在千卡规模的集群上充分发挥计算潜能,推动了复杂模型的快速训练和应用。
数字扫地僧
2025/03/15
3800
[ai学习笔记]分布式训练原理:DeepSeek千卡集群通信优化策略
[源码解析] PyTorch 分布式(1)------历史和概述
本文主要在对PyTorch官方文档的翻译之上加入了自己的理解,希望给大家一个PyTorch分布式的历史脉络和基本概念,有兴趣的朋友可以仔细研究一下历史,看看一个机器学习系统如何一步一步进入分布式世界 / 完善其功能。
罗西的思考
2021/11/04
1.4K0
大模型的实践应用-大语言模型的分布式训练并行策略,数据并行原理
大家好,我是微学AI,今天给大家介绍一下大模型的实践应用14-大语言模型的分布式训练并行策略,数据并行原理。大语言模型的分布式训练并行策略主要通过数据并行来实现。数据并行是指将训练数据划分为多个小批量, 然后将这些小批量分配给不同的计算设备进行并行处理。通过数据并行的并行策略,每个计算设备都可以独立地计算小批量数据的梯度,并将结果进行聚合,从而实现模型的并行训练。这种分布式训练策略可以加速大语言模型的训练过程,并提高模型的性能和效果。
微学AI
2025/05/29
1060
大模型的实践应用-大语言模型的分布式训练并行策略,数据并行原理
[源码解析] PyTorch分布式(5) ------ DistributedDataParallel 总述&如何使用
本文是 PyTorch 分布式系列的第五篇,以几篇官方文档的翻译为基础,加入了自己的一些思考,带领大家进入DistributedDataParallel,在后续会用5~6篇左右做深入分析。
罗西的思考
2021/11/18
2.2K0
[源码解析] PyTorch分布式(5) ------ DistributedDataParallel 总述&如何使用
推荐阅读
相关推荐
[源码解析] 模型并行分布式训练Megatron (2) --- 整体架构
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档