WELCOME TO INFOCHEATS.NET

INFOCHEATS is a community-driven platform focused on free game cheats, cheat development, and verified commercial software for a wide range of popular games. We provide a large collection of free cheats shared by the community. All public releases are checked for malicious code to reduce the risk of viruses, malware, or unwanted software before users interact with them.

Alongside free content, INFOCHEATS hosts an active marketplace with many independent sellers offering commercial cheats. Each product is discussed openly, with user feedback, reviews, and real usage experience available to help you make informed decisions before purchasing.

Whether you are looking for free cheats, exploring paid solutions, comparing sellers, or studying how cheats are developed and tested, INFOCHEATS brings everything together in one place — transparently and community-driven.

Guide EAC Kernel Driver — Screen Capture & Win32k Resolution

byte_corvus

Newbie
Newbie
Newbie
Newbie
Status
Offline
Joined
Mar 3, 2026
Messages
546
Reaction score
7
Anyone still thinking their external overlay is 100% safe just because it's "external" needs to look at what Easy Anti-Cheat (EAC) is actually doing inside their kernel driver. While digging through their latest mess of obfuscated code islands, it looks like they are still heavily relying on win32k exports to handle screen captures from ring 0.

Technical Breakdown

The logic below shows how the driver resolves critical GDI functions manually rather than relying on standard imports—likely to avoid simple import hooks and to maintain a low profile. They are targeting everything needed for a full pixel-data grab: NtUserGetDC, NtGdiBitBlt, and NtGdiGetDIBitsInternal.

Core Logic Flow:
  1. Resolves PsGetThreadWin32Thread to ensure they are in a context that can interact with the GUI subsystem.
  2. Dynamically resolves win32k.sys exports using a custom resolver (EacPeLocateLowCmpSpan).
  3. Grabs the DC, creates a compatible bitmap in memory, and triggers a BitBlt to copy the screen contents.
  4. Uses GetDIBits to dump the buffer, which is likely then phoning home or being analyzed for known ESP/overlay patterns.

Code:
 *a1 = 0LL;
  *a2 = 0;
  CurrentThread = KeGetCurrentThread();
  v9 = EacDecodeNativeResolverPair(g_NativeImport_PsGetThreadWin32Thread_mod, g_NativeImport_PsGetThreadWin32Thread_enc);
  if ( !((__int64 (__fastcall *)(struct _KTHREAD *))((0x348CD615FA024567LL * v9) ^ 0xE2DFA06E1F229229uLL))(CurrentThread) )
    goto LABEL_13;
  if ( g_Win32kCaptureExportsReady )
    goto LABEL_3;
  if ( (KeGetCurrentIrql() & 0xFE) != 0 )
  {
LABEL_13:
    LODWORD(v10) = 0;
    return (unsigned int)v10;
  }
  LODWORD(v10) = 0;
  v22 = (_DWORD *)EacJumpThunk_1400F4074(11LL, 0LL);
  if ( !v22 )
    return (unsigned int)v10;
  v23 = v22;
  v58[0] = (__m128i)xmmword_1401D62F0;
  v58[1].m128i_i32[0] = 228626287;
  v24 = (char **)EacVmLowCmpTransform_1400FBE21(v58, v22);
  v58[0] = _mm_load_si128(xmmword_1401D6300);
  v58[1].m128i_i32[0] = -205954010;
  v25 = (char **)EacVmLowCmpTransform_1400FBE21(v58, v23);
  if ( v25 == 0LL || v24 == 0LL )
  {
    EacFreeTrackedBlock(v23);
    goto LABEL_13;
  }
  v58[0].m128i_i32[2] = 0;
  v58[0].m128i_i64[0] = 0LL;
  v26 = -2109794682;
  for ( i = 0LL; i != 3; ++i )
  {
    v26 = __ROL4__(1140671485 * v26 + 12820163, 1);
    v58[0].m128i_i32[i] = v26 ^ dword_1401D86DC[i];
  }
  g_Win32k_NtUserGetDC = (__int64 (__fastcall *)(_QWORD))EacPeLocateLowCmpSpan(
                                                           v24[2],
                                                           *((unsigned int *)v24 + 6),
                                                           (unsigned __int64)v58);
  v28 = 0LL;
  memset(v58, 0, 24);
  v29 = -604945222;
  do
  {
    v29 = __ROL4__(1140671485 * v29 + 12820163, 30);
    v58[0].m128i_i32[v28] = v29 ^ dword_1401D86E8[v28];
    ++v28;
  }
  while ( v28 != 6 );
  g_Win32k_NtGdiCreateCompatibleDC = (__int64 (__fastcall *)(_QWORD))EacPeLocateLowCmpSpan(
                                                                       v25[2],
                                                                       *((unsigned int *)v25 + 6),
                                                                       (unsigned __int64)v58);
  memset(v58, 0, 24);
  v30 = 570971763;
  for ( j = 0LL; j != 4; ++j )
  {
    v58[0].m128i_i32[j] = *((_DWORD *)&unk_1401D8700 + j) ^ v30;
    v30 = __ROL4__(1140671485 * v30 + 12820163, 29);
  }
  v32 = 1622400489;
  for ( k = 0LL; k != 3; ++k )
  {
    v58[1].m128i_i8[k] = v32 ^ *((_BYTE *)&unk_1401D8700 + k + 16);
    v32 >>= 8;
  }
  g_Win32k_NtGdiGetDeviceCaps = (__int64 (__fastcall *)(_QWORD, _QWORD))EacPeLocateLowCmpSpan(
                                                                          v24[2],
                                                                          *((unsigned int *)v24 + 6),
                                                                          (unsigned __int64)v58);
  memset(v58, 0, 28);
  v34 = 1207376218;
  for ( m = 0LL; m != 7; ++m )
  {
    v34 = -1140671485 * v34 - 12820164;
    v58[0].m128i_i32[m] = v34 ^ dword_1401D8713[m];
  }
  g_Win32k_NtGdiCreateCompatibleBitmap = (__int64 (__fastcall *)(_QWORD, _QWORD, _QWORD))EacPeLocateLowCmpSpan(
                                                                                           v25[2],
                                                                                           *((unsigned int *)v25 + 6),
                                                                                           (unsigned __int64)v58);
  memset(v58, 0, 28);
  v36 = -701610193;
  for ( n = 0LL; n != 4; ++n )
  {
    v58[0].m128i_i32[n] = *((_DWORD *)&unk_1401D872F + n) ^ v36;
    v36 = -1140671485 * v36 - 12820163;
  }
  v38 = 1482325863;
  for ( ii = 0LL; ii != 2; ++ii )
  {
    v58[1].m128i_i8[ii] = v38 ^ *((_BYTE *)&unk_1401D872F + ii + 16);
    v38 >>= 8;
  }
  g_Win32k_NtGdiSelectBitmap = (__int64 (__fastcall *)(_QWORD, _QWORD))EacPeLocateLowCmpSpan(
                                                                         v25[2],
                                                                         *((unsigned int *)v25 + 6),
                                                                         (unsigned __int64)v58);
  memset(v58, 0, 18);
  v58[0].m128i_i32[2] = 0;
  v58[0].m128i_i64[0] = 0LL;
  v40 = 58455018;
  for ( jj = 0LL; jj != 3; ++jj )
  {
    v40 = _byteswap_ulong(214013 * v40 + 2531011);
    v58[0].m128i_i32[jj] = v40 ^ dword_1401D8741[jj];
  }
  g_Win32k_NtGdiBitBlt = (__int64 (__fastcall *)(_QWORD, _QWORD, _QWORD, _QWORD, _DWORD, _QWORD, _DWORD, _DWORD, _DWORD, _DWORD, _DWORD))EacPeLocateLowCmpSpan(v25[2], *((unsigned int *)v25 + 6), (unsigned __int64)v58);
  v42 = 0LL;
  memset(v58, 0, 21);
  v43 = -1646841888;
  do
  {
    v58[0].m128i_i32[v42] = *((_DWORD *)&unk_1401D874D + v42) ^ v43;
    ++v42;
    v43 = __ROL4__(214013 * v43 + 2531011, 28);
  }
  while ( v42 != 5 );
  v58[1].m128i_i8[4] = *((_BYTE *)&unk_1401D874D + 20) ^ 0xEA;
  g_Win32k_NtGdiDeleteObjectApp = (__int64 (__fastcall *)(_QWORD))EacPeLocateLowCmpSpan(
                                                                    v24[2],
                                                                    *((unsigned int *)v24 + 6),
                                                                    (unsigned __int64)v58);
  memset(v58, 0, 21);
  v44 = -1627889142;
  for ( kk = 0LL; kk != 4; ++kk )
  {
    v44 = __ROL4__(214013 * v44 + 2531011, 29);
    v58[0].m128i_i32[kk] = v44 ^ dword_1401D8762[kk];
  }
  g_Win32k_NtUserReleaseDC = (__int64 (__fastcall *)(_QWORD))EacPeLocateLowCmpSpan(
                                                               v24[2],
                                                               *((unsigned int *)v24 + 6),
                                                               (unsigned __int64)v58);
  memset(v58, 0, 23);
  v46 = 510780929;
  for ( mm = 0LL; mm != 5; ++mm )
  {
    v58[0].m128i_i32[mm] = *((_DWORD *)&unk_1401D8772 + mm) ^ v46;
    v46 = __ROL4__(214013 * v46 + 2531011, 2);
  }
  v48 = 525754037;
  for ( nn = 0LL; nn != 3; ++nn )
  {
    v58[1].m128i_i8[nn + 4] = v48 ^ *((_BYTE *)&unk_1401D8772 + nn + 20);
    v48 >>= 8;
  }
  g_Win32k_NtGdiGetDIBitsInternal = (__int64 (__fastcall *)(_QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _QWORD, _DWORD, _DWORD, _DWORD))EacPeLocateLowCmpSpan(v25[2], *((unsigned int *)v25 + 6), (unsigned __int64)v58);
  memset(v58, 0, 23);
  v50 = g_Win32k_NtGdiGetDIBitsInternal != 0LL;
  v51 = _mm_cmpeq_epi32(
          _mm_unpacklo_epi64(
            _mm_loadl_epi64((const __m128i *)&g_Win32k_NtGdiDeleteObjectApp),
            _mm_loadl_epi64((const __m128i *)&g_Win32k_NtUserReleaseDC)),
          (__m128i)0LL);
  v52 = _mm_cmpeq_epi32(
          _mm_unpacklo_epi64(
            _mm_loadl_epi64((const __m128i *)&g_Win32k_NtGdiSelectBitmap),
            _mm_loadl_epi64((const __m128i *)&g_Win32k_NtGdiBitBlt)),
          (__m128i)0LL);
  v53 = _mm_cmpeq_epi32(
          _mm_unpacklo_epi64(
            _mm_loadl_epi64((const __m128i *)&g_Win32k_NtGdiGetDeviceCaps),
            _mm_loadl_epi64((const __m128i *)&g_Win32k_NtGdiCreateCompatibleBitmap)),
          (__m128i)0LL);
  v54 = _mm_cmpeq_epi32(
          _mm_unpacklo_epi64(
            _mm_loadl_epi64((const __m128i *)&g_Win32k_NtUserGetDC),
            _mm_loadl_epi64((const __m128i *)&g_Win32k_NtGdiCreateCompatibleDC)),
          (__m128i)0LL);
  v55 = (_mm_movemask_epi8(
           _mm_packs_epi32(
             _mm_packs_epi32(
               _mm_and_si128(_mm_shuffle_epi32(v54, 177), v54),
               _mm_and_si128(_mm_shuffle_epi32(v53, 177), v53)),
             _mm_packs_epi32(
               _mm_and_si128(_mm_shuffle_epi32(v52, 177), v52),
               _mm_and_si128(_mm_shuffle_epi32(v51, 177), v51)))) & 0xAAAA) == 0;
  g_Win32kCaptureExportsReady = g_Win32k_NtGdiGetDIBitsInternal != 0LL && v55;
  EacFreeTrackedBlock(v23);
  if ( !v50 || !v55 )
    goto LABEL_13;
LABEL_3:
  LODWORD(v10) = 0;
  v11 = g_Win32k_NtUserGetDC(0LL);
  if ( v11 )
  {
    v12 = v11;
    v13 = g_Win32k_NtGdiCreateCompatibleDC(v11);
    if ( v13 )
    {
      v14 = v13;
      *a3 = g_Win32k_NtGdiGetDeviceCaps(v12, 8LL);
      v15 = g_Win32k_NtGdiGetDeviceCaps(v12, 10LL);
      *a4 = v15;
      v16 = g_Win32k_NtGdiCreateCompatibleBitmap(v12, (unsigned int)*a3, v15);
      if ( v16 )
      {
        v17 = v16;
        LODWORD(v10) = 0;
        if ( g_Win32k_NtGdiSelectBitmap(v14, v16)
          && (unsigned __int8)g_Win32k_NtGdiBitBlt(v14, 0LL, 0LL, (unsigned int)*a3, *a4, v12, 0, 0, 13369376, -1, 0) )
        {
          v18 = EacJumpThunk_1400B4883(0LL, 40LL, 4LL);
          if ( v18 )
          {
            v10 = v18;
            v19 = 4 * *a4 * *a3;
            *a2 = v19;
            v20 = EacJumpThunk_1400B4883(0LL, v19, 4LL);
            if ( v20 )
            {
              *(_DWORD *)v10 = 40;
              *(_DWORD *)(v10 + 4) = *a3;
              *(_DWORD *)(v10 + 8) = -*a4;
              *(_DWORD *)(v10 + 12) = 2097153;
              *(_QWORD *)(v10 + 16) = 0LL;
              v57 = *a2;
              v21 = v20;
              if ( (unsigned int)g_Win32k_NtGdiGetDIBitsInternal(v14, v17, 0LL, *a4, v20, v10, 0, v57, 0) == *a4 )
                *a1 = v21;
              else
                EacJumpThunk_1400B4A15(v21);
            }
            EacJumpThunk_1400B4A15(v10);
          }
          LOBYTE(v10) = *a1 != 0;
        }
        g_Win32k_NtGdiDeleteObjectApp(v17);
      }
      else
      {
        LODWORD(v10) = 0;
      }
      g_Win32k_NtGdiDeleteObjectApp(v14);
    }
    else
    {
      LODWORD(v10) = 0;
    }
    g_Win32k_NtUserReleaseDC(v12);
  }
  return (unsigned int)v10;

Anti-Cheat Context

This isn't just for checking if you have a colorful menu open. EAC uses these screenshots to catch ESP box boundaries, chams that aren't properly hidden from GDI calls, and external overlays that don't use more advanced hijacking techniques to stay invisible. If your overlay is just a top-most transparent window, they already have you.

The code islands are heavily split. EAC uses mutated resolvers and displacement-heavy jumps to make static analysis a nightmare. If you are reversing the driver, look for the EacVmLowCmpTransform calls—that is where the real magic happens for their internal protection.

Has anyone else been tracking their win32k traversal in the latest builds? It seems they are getting more aggressive with how often they trigger these captures during Premier matches in CS2 and high-tier Tarkov raids.

Drop your findings or crash logs if you're hitting BSODs while trying to hook these resolvers.
 
Top