分类
游戏安全

EasyAntiCheat UserMode AntiCheat Window Detection

updated Dumped by 2020/5/16 apex eac usermode

2020/5/16补充一些信息
他感兴趣的窗口条件
首先是 if ( _bittest64(&window_exstyle, 0x13u) ) 满足
然后窗口要可见
窗口的高度和宽度不为0/或1
窗口类名和名称由eAc_crc_or_xor计算后不是0x3BC41165或0x950C78DE
窗口样式不是0x2483027968
窗口拓展样式不是0x8280088或 0x8280028
由此可见 满足其窗口白名单要求还是有些难顶的
send packet idx:为0x129 其中包含 窗口的类名 窗口名称 窗口样式 窗口 拓展样式 窗口所属进程id 窗口所属线程id 等.
简单看了下 有什么错误 望指正

下面还原eac 是如何搜集 窗口信息 以及它对哪些窗口感兴趣

char __usercall eAc_detection_window@<al>(__int64 (__fastcall ***a1)(_QWORD)@<rcx>, __int64 a2@<rbx>)
{
//.....
//搜集感兴趣的窗口信息
  imp_EnumWindows((__int64)enum_windows_callbacks, (__int64)&enum_windows_context);
  if ( enum_window_successed )//不为0条
    eAc_send_windowinfo(v5, (__int64 *)&data);//发送给服务器
    //........
    }

//这里是它用来加密不符合它条件的窗口名称或者类名的方法


__int64 __fastcall eAc_Crc_or_Xor(unsigned __int8 *a1, unsigned __int64 a2, unsigned int a3)
{
  unsigned __int8 v3; // ST20_1
  char v5; // [rsp+21h] [rbp-27h]
  unsigned __int8 *v6; // [rsp+28h] [rbp-20h]
  unsigned __int64 i; // [rsp+30h] [rbp-18h]
  unsigned __int64 v8; // [rsp+58h] [rbp+10h]
  unsigned int v9; // [rsp+60h] [rbp+18h]

  v9 = a3;
  v8 = a2;
  v6 = a1;
  memset(&v5, 0, sizeof(v5));
  eAc_Get_api_callback(&qword_D6970[29], Get_Cpuid_supported_crc_info, &Cpuid_info);
  if ( Cpuid_info )
  {
    while ( v8 > 3 )
    {
      v9 = _mm_crc32_u32(v9, *(_DWORD *)v6);
      v6 += 4;
      v8 -= 4i64;
    }
    while ( v8 )
    {
      v3 = *v6++;
      v9 = _mm_crc32_u8(v9, v3);
      --v8;
    }
  }
  else
  {
    for ( i = 0i64; i < v8; ++i )
      v9 = *((_DWORD *)qword_C0A40 + (unsigned __int8)(v6[i] ^ v9)) ^ (v9 >> 8);
  }
  return v9;
}

//窗口信息搜集由EnumWindows 函数的回调完成

void __fastcall enum_windows_callbacks(__int64 context)
{
  struct_v10 *v1; // rdx
  __int64 v2; // rbx
  __int64 v3; // rbp
  __int64 v4; // rdi
  __int64 v5; // rsi
  __int64 v6; // r12
  __int64 v7; // r13
  __int64 v8; // r14
  __int64 v9; // r15
  struct_v10 *v10; // r14
  __int64 window1; // rdi
  __int64 window2; // rax
  __int64 hwnd; // rsi
  __int64 window_exstyle; // r12
  __int64 user32; // rax
  unsigned int (__fastcall *IsWindowVisible)(__int64); // rax
  __int32 width; // er15
  __int32 height; // esi
  int window_style; // eax
  int tid; // eax
  int tid_2; // esi
  int tid_1; // eax
  tagRECT window_rect_1; // xmm1
  int tid_3; // edi
  int pid_2; // er15
  __int64 WindowText_count; // rax
  __int64 ClassName_count; // rax
  __int64 ClassName_1; // rax
  __int64 v29; // rcx
  __int64 v30; // rdx
  bool v31; // cf
  __int64 v32; // [rsp-20h] [rbp-1D8h]
  int pid_1; // [rsp+0h] [rbp-1B8h]
  __int128 v34; // [rsp+10h] [rbp-1A8h]
  __int128 v35; // [rsp+20h] [rbp-198h]
  tagRECT window_Rect; // [rsp+30h] [rbp-188h]
  tagRECT window_rect; // [rsp+40h] [rbp-178h]
  __int128 WindowText; // [rsp+50h] [rbp-168h]
  __int128 v39; // [rsp+60h] [rbp-158h]
  __int128 v40; // [rsp+70h] [rbp-148h]
  __int128 v41; // [rsp+80h] [rbp-138h]
  __int64 ClassName; // [rsp+90h] [rbp-128h]
  __int128 v43; // [rsp+A0h] [rbp-118h]
  __int128 v44; // [rsp+B0h] [rbp-108h]
  __int128 v45; // [rsp+C0h] [rbp-F8h]
  int height_1; // [rsp+D0h] [rbp-E8h]
  int width_1; // [rsp+D4h] [rbp-E4h]
  int window_style_1; // [rsp+D8h] [rbp-E0h]
  int window_exstyle_1; // [rsp+DCh] [rbp-DCh]
  int pid; // [rsp+E0h] [rbp-D8h]
  __int64 v51; // [rsp+F0h] [rbp-C8h]
  unsigned __int64 v52; // [rsp+170h] [rbp-48h]
  __int64 v53; // [rsp+180h] [rbp-38h]
  __int64 v54; // [rsp+188h] [rbp-30h]
  __int64 v55; // [rsp+190h] [rbp-28h]
  __int64 v56; // [rsp+198h] [rbp-20h]
  __int64 v57; // [rsp+1A0h] [rbp-18h]
  __int64 v58; // [rsp+1A8h] [rbp-10h]
  __int64 v59; // [rsp+1B0h] [rbp-8h]

  v59 = v3;
  v58 = v5;
  v57 = v4;
  v56 = v6;
  v55 = v7;
  v54 = v8;
  v53 = v9;
  v52 = (unsigned __int64)&v32 ^ 0x2B992DDFA232i64;
  v10 = v1;
  window1 = context;
  window2 = getGetForegroundWindow_pid(context, v2);
  hwnd = window2;
  if ( window2 )
  {
    if ( window2 == window1 )
      goto LABEL_44;
    eAc_Get_api_callback(&unk_D8CB8, Get_GetWindowLongPtrW, &GetWindowLongPtrW);
    if ( GetWindowLongPtrW )
      window_exstyle = GetWindowLongPtrW(window1, 0xFFFFFFECi64);// 获取拓展窗口样式
    else
      window_exstyle = 0i64;
    if ( _bittest64(&window_exstyle, 0x13u) )   // //这里不知道具体是哪个属性
    {
      user32 = get_user32();
      IsWindowVisible = (unsigned int (__fastcall *)(__int64))get_exp(user32, &unk_C9288, 0i64);
      if ( IsWindowVisible )
      {
        if ( IsWindowVisible(window1) )         // //窗口可见
        {
          eAc_Get_api_callback(&unk_D8CC0, Get_GetWindowRect, &GetWindowRect);
          if ( GetWindowRect )
          {
            if ( (unsigned int)GetWindowRect(window1, &window_rect) )
            {
              eAc_Get_api_callback(&unk_D8CC0, Get_GetWindowRect, &GetWindowRect);
              if ( GetWindowRect )
              {
                if ( (unsigned int)GetWindowRect(hwnd, &window_Rect) )
                {
                  width = window_rect.right - window_rect.left;
                  height = window_rect.bottom - window_rect.top;
                  if ( window_rect.right - window_rect.left > 0
                    && height > 0
                    && window_rect.left < window_Rect.right
                    && window_rect.right > window_Rect.left
                    && window_rect.top < window_Rect.bottom
                    && window_rect.bottom > window_Rect.top )
                  {                             // //检查窗口大小
                    sub_59E58(&WindowText, 0i64, 148i64);
                    if ( (signed int)imp_GetWindowTextW(window1, &v51, 0x40i64) > 0 )// //获取窗口名字
                      cus_memcpy(&WindowText, 0x40i64, &v51);
                    if ( (signed int)imp_GetClassNameW(window1, &v51, 0x40i64) > 0 )// //获取窗口类名
                      cus_memcpy(&ClassName, 0x40i64, &v51);
                    height_1 = height;
                    width_1 = width;
                    eAc_Get_api_callback(&unk_D8CB8, Get_GetWindowLongPtrW, &GetWindowLongPtrW);
                    if ( GetWindowLongPtrW )
                      window_style = GetWindowLongPtrW(window1, 0xFFFFFFF0i64);// 窗口名字 窗口类名 窗口线程id 窗口进程id  窗口样式
                    else
                      window_style = 0;
                    window_style_1 = window_style;
                    window_exstyle_1 = window_exstyle;
                    pid = 0;
                    tid = imp_GetWindowThreadProcessId(window1, &pid);
                    pid_1 = 0;
                    tid_2 = tid;
                    tid_1 = imp_GetWindowThreadProcessId(window1, &pid_1);
                    window_rect_1 = window_rect;
                    tid_3 = tid_1;
                    pid_2 = pid_1;
                    _mm_store_si128((__m128i *)&v34, (__m128i)window_Rect);
                    _mm_store_si128((__m128i *)&v35, (__m128i)window_rect_1);
                    WindowText_count = get_bytes_Count(&WindowText);
                    if ( (unsigned int)eAc_Crc_or_Xor(&WindowText, WindowText_count, 0i64) != 0x3BC41165// //窗口名字
                      || (ClassName_count = get_bytes_Count(&ClassName),
                          (unsigned int)eAc_Crc_or_Xor(&ClassName, ClassName_count, 0i64) != 0x3BC41165)// //窗口类名
                      || window_style_1 != 2483027968// 窗口样式
                      || window_exstyle_1 != 0x8280028// 窗口拓展样式
                      || pid != pid_2
                      || tid_2 != tid_3
                      || (unsigned int)cmp_window_size((unsigned __int8 *)&v35, (unsigned __int8 *)&v34, 16i64) )// //窗口大小
                    {
                      ClassName_1 = get_bytes_Count(&ClassName);
                      if ( (unsigned int)eAc_Crc_or_Xor(&ClassName, ClassName_1, 0i64) != 0x950C78DE
                        || width_1 != 1
                        || height_1 != 1
                        || window_style_1 != 2483027968
                        || window_exstyle_1 != 0x8280088 )
                      {
                        if ( pid )
                        {
                          v29 = v10->qword10;
                          v30 = *(_QWORD *)(v29 + 8);
                          if ( *(_QWORD *)(v29 + 0x10) == v30 )
                          {
                            sub_AB2E4(v29, v30, &WindowText);
                          }
                          else
                          {
                            *(_OWORD *)v30 = WindowText;
                            *(_OWORD *)(v30 + 16) = v39;
                            *(_OWORD *)(v30 + 32) = v40;
                            *(_OWORD *)(v30 + 48) = v41;
                            *(_OWORD *)(v30 + 64) = *(_OWORD *)&ClassName;
                            *(_OWORD *)(v30 + 80) = v43;
                            *(_OWORD *)(v30 + 96) = v44;
                            *(_OWORD *)(v30 + 112) = v45;
                            *(_OWORD *)(v30 + 128) = *(_OWORD *)&height_1;
                            *(_DWORD *)(v30 + 144) = pid;
                            *(_QWORD *)(v29 + 8) += 0x94i64;
                          }
                          ++v10->result_count;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  v31 = v10->result_count < 0x10ui64;
LABEL_44:
  sub_BCD40((unsigned __int64)&v32 ^ v52);
}

//将搜集到的窗口发送到eac服务器

__int64 __fastcall eAc_send_windowinfo(__int64 a1, __int64 *data)
{
  __int64 *data_1; // rdi
  __int64 result; // rax
  __int64 entry_count; // r14
  __int64 v5; // r15
  __int64 i; // rsi
  __int64 v7; // rbp
  __int64 v8; // rbx
  signed __int64 v9; // rbx
  __int64 v10; // rdi
  void *v11; // rbx
  int count; // eax
  __int64 v13; // [rsp+28h] [rbp-60h]
  __int64 v14; // [rsp+30h] [rbp-58h]
  __int64 v15; // [rsp+38h] [rbp-50h]
  __int64 v16; // [rsp+40h] [rbp-48h]
  __int128 v17; // [rsp+50h] [rbp-38h]
  __int64 v18; // [rsp+60h] [rbp-28h]

  data_1 = data;
  result = sub_A1974(eac_inc);
  entry_count = data_1[1];
  v5 = result;
  for ( i = *data_1; i != entry_count; i += 0x94i64 )// //遍历获取到的所有窗口数据
  {
    result = sub_56378(v5, *(_DWORD *)(i + 0x90));
    v7 = result;
    if ( result )
    {
      v8 = *(unsigned int *)(result + 10);
      v18 = 0i64;
      v9 = v8 + 512;
      _mm_storeu_si128((__m128i *)&v17, (__m128i)0i64);
      if ( (unsigned __int8)sub_1D7D0(&v17, v9) )
      {
        v10 = v17;
        sub_59E58(v17, 0i64, v9);
        *((_QWORD *)&v17 + 1) = v9 + v10;
      }
      sub_1D868((__int64 *)&v17, v7, v7 + *(unsigned int *)(v7 + 10));
      v11 = (void *)v17;
      LODWORD(v16) = *(_DWORD *)(i + 0x8C);
      LODWORD(v15) = *(_DWORD *)(i + 0x88);
      LODWORD(v14) = *(_DWORD *)(i + 0x80);
      LODWORD(v13) = *(_DWORD *)(i + 0x84);
      count = eAc_format_packet(
                v17 + *(unsigned int *)(v7 + 0xA),
                0x200i64,
                (__int64)&unk_CA148,
                i,
                i + 0x40,
                v13,
                v14,
                v15,
                v16);
      eAc_sendpacket(eac_inc, 0x129i64, v11, (unsigned int)(count + *(_DWORD *)(v7 + 0xA)));
      memset((void *)v7, 0, *(unsigned int *)(v7 + 10));
      memset(v11, 0, *((_QWORD *)&v17 + 1) - (_QWORD)v11);
      sub_59274(v7);
      result = sub_1DA74(&v17);
    }
  }
  return result;
}
0 0 vote
文章评分

由FAKE

Через тернии к звездам,
через радость и слезы
Мы проложим дорогу

Subscribe
提醒
guest
0 评论
Inline Feedbacks
View all comments