首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >BattlEye逆向工程师跟踪(4)

BattlEye逆向工程师跟踪(4)

原创
作者头像
franket
发布2021-02-09 12:59:25
发布2021-02-09 12:59:25
15.6K0
举报
文章被收录于专栏:技术杂记技术杂记

处理枚举

该机制将枚举计算机上所有打开的手柄,并标记任何游戏进程手柄。这样做是为了捕获作弊者,迫使其句柄具有通常无法获得的特定级别的访问权限,因为反作弊寄存器会回调,以防止进程获得游戏进程的内存修改权限。如果某个进程在游戏进程的打开句柄中被捕获,则会将相关信息(例如访问级别和进程名称)发送到游戏服务器:

代码语言:txt
复制
report_buffer = (__int8 *)malloc(0x2800);
report_buffer[0] = 0;
report_buffer[1] = 0x11;
buffer_index = 2;
handle_info = 0;
buffer_size = 0x20;
do
{
  buffer_size += 0x400;
  handle_info = (SYSTEM_HANDLE_INFORMATION *)realloc(handle_info, buffer_size);
  if ( !handle_info )
    break;
  query_status = NtQuerySystemInformation(0x10, handle_info, buffer_size, &buffer_size);// SystemHandleInformation
}
while ( query_status == STATUS_INFO_LENGTH_MISMATCH );
if ( handle_info && query_status >= 0 )
{
  process_object_type_index = -1;
  for ( handle_index = 0;
        (unsigned int)handle_index < handle_info->number_of_handles && buffer_index <= 10107;
        ++handle_index )
  {
    // ONLY FILTER PROCESS HANDLES  
    if ( process_object_type_index == -1
      || (unsigned __int8)handle_info->handles[handle_index].ObjectTypeIndex == process_object_type_index )
    {
      // SEE IF OWNING PROCESS IS NOT GAME PROCESS
      if ( handle_info->handles[handle_index].UniqueProcessId != GetCurrentProcessId() )
      {
        process_handle = OpenProcess(
                           PROCESS_DUP_HANDLE,
                           0,
                           *(unsigned int *)&handle_info->handles[handle_index].UniqueProcessId);
        if ( process_handle )
        {
          // DUPLICATE THEIR HANDLE
          current_process_handle = GetCurrentProcess();
          if ( DuplicateHandle(
                 process_handle,
                 (unsigned __int16)handle_info->handles[handle_index].HandleValue,
                 current_process_handle,
                 &duplicated_handle,
                 PROCESS_QUERY_LIMITED_INFORMATION,
                 0,
                 0) )
          {
            if ( process_object_type_index == -1 )
            {
              if ( NtQueryObject(duplicated_handle, ObjectTypeInformation, &typeinfo, 0x400, 0) >= 0
                && !_wcsnicmp(typeinfo.Buffer, "Process", typeinfo.Length / 2) )
              {
                process_object_type_index = (unsigned __int8)handle_info->handles[handle_index].ObjectTypeIndex;
              }
            }
            if ( process_object_type_index != -1 )
            {
              // DUMP OWNING PROCESS NAME
              target_process_id = GetProcessId(duplicated_handle);
              if ( target_process_id == GetCurrentProcessId() )
              {
                if ( handle_info->handles[handle_index].GrantedAccess & PROCESS_VM_READ|PROCESS_VM_WRITE )
                {
                  owning_process = OpenProcess(
                                     PROCESS_QUERY_LIMITED_INFORMATION,
                                     0,
                                     *(unsigned int *)&handle_info->handles[handle_index].UniqueProcessId);
                  process_name_length = 0x80;
                  if ( !owning_process
                    || !QueryFullProcessImageNameA(
                          owning_process,
                          0,
                          &report_buffer[buffer_index + 1],
                          &process_name_length) )
                  {
                    process_name_length = 0;
                  }
                  if ( owning_process )
                    CloseHandle(owning_process);
                  report_buffer[buffer_index] = process_name_length;
                  after_name_index = buffer_index + (char)process_name_length + 1;
                  *(_DWORD *)&report_buffer[after_name_index] = handle_info->handles[handle_index].GrantedAccess;
                  buffer_index = after_name_index + 4;
                }
              }
            }
            CloseHandle(duplicated_handle);
            CloseHandle(process_handle);
          }
          else
          {
            CloseHandle(process_handle);
          }
        }
      }
    }
  }
}
if ( handle_info )
  free(handle_info);
battleye::send(report_buffer, buffer_index, false);
free(report_buffer);

流程枚举

shellcode实现的第一个例程是一个包罗万象的功能,用于记录和转储有关所有正在运行的进程的信息。这是相当普遍的,但出于完整性考虑,已包含在本文中。这还将上传磁盘上主映像的文件大小。

代码语言:txt
复制
snapshot_handle = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0x00 );
if ( snapshot_handle != INVALID_HANDLE_VALUE )
{
  process_entry.dwSize = 0x130;
  if ( Process32First(snapshot_handle, &process_entry) )
  {
    report_buffer = (std::uint8_t*)malloc(0x5000);
    report_buffer[0] = 0;
    report_buffer[1] = 0xB;
    buffer_index = 2;
    
    // ITERATE PROCESSES
    do
    {
      target_process_handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, process_entry.th32ProcessID);
      
      // QUERY PROCESS IAMGE NAME
      name_length = 0x100;
      query_result = QueryFullProcessImageNameW(target_process_handle, 0, &name_buffer, &name_length);
      name_length = WideCharToMultiByte(
          CP_UTF8, 
          0x00, 
          &name_buffer, 
          name_length,
          &report_buffer[buffer_index + 5], 
          0xFF, 
          nullptr, 
          nullptr);
      
      valid_query = target_process_handle && query_result && name_length;
      
      // Query file size
      if ( valid_query )
      {
        if ( GetFileAttributesExW(&name_buffer, GetFileExInfoStandard, &file_attributes) )
          file_size = file_attributes.nFileSizeLow;
        else
          file_size = 0;
      }
      else
      {
        // TRY QUERY AGAIN WITHOUT HANDLE
        process_id_information.process_id = (void *)process_entry.th32ProcessID;
        process_id_information.image_name.Length = '\0';
        process_id_information.image_name.MaximumLength = '\x02\0';
        process_id_information.image_name.Buffer = name_buffer;
        
        if ( NtQuerySystemInformation(SystemProcessIdInformation, 
                                        &process_id_information, 
                                        24, 
                                        1) < 0 ) 
        {
          name_length = 0;
        }
        else
        {
          name_address = &report_buffer[buffer_index + 5];
          name_length = WideCharToMultiByte(
                          CP_UTF8,
                          0,
                          (__int64 *)process_id_information.image_name.Buffer,
                          process_id_information.image_name.Length / 2,
                          name_address,
                          0xFF,
                          nullptr,
                          nullptr);
        }
        file_size = 0;
      }

      // IF MANUAL QUERY WORKED
      if ( name_length )
      {
        *(_DWORD *)&report_buffer[buffer_index] = process_entry.th32ProcessID;
        report_buffer[buffer_index + 4] = name_length;
        *(_DWORD *)&report_buffer[buffer_index + 5 + name_length] = file_size;
        buffer_index += name_length + 9;
      }
      if ( target_process_handle )
        CloseHandle(target_process_handle);
      
      // CACHE LSASS HANDLE FOR LATER !!
      if ( *(_DWORD *)process_entry.szExeFile == 'sasl' )
        lsass_handle = OpenProcess(0x410, 0, process_entry.th32ProcessID);
    }
    while ( Process32Next(snapshot_handle, &process_entry) && buffer_index < 0x4EFB );

    // CLEANUP
    CloseHandle((__int64)snapshot_handle);
    battleye::send(report_buffer, buffer_index, 0);
    free(report_buffer);
  }
}

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

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

目录
  • 流程枚举
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档