CVE-2026-50477 CVSS 8.8 July 14, 2026
← All reports

CVE-2026-50477: Heap Buffer Overflow in the Windows WHEA Error-Source Logging Path

Community check
      Suggest change

      Reports here are AI-generated and may be wrong. Edit the source directly on GitHub — saving opens a pull request. Add yourself to the report's editors: list in the same PR and your name will appear at the bottom once it's merged.

      ✎ Edit on GitHub (opens a PR)

      TL;DR

      WheapLogInitEvent in ntoskrnl.exe builds a diagnostic ETW/telemetry snapshot of every registered WHEA error source at boot. It sizes a NonPagedPoolNx buffer from a cached error-source count (dword_140CDB2DC) — 1072 * count bytes — and then, in one code path, walks the live error-source linked list (qword_140CDB2E8) writing a fixed 1072-byte record per node into buffer[1072 * i], incrementing i with no bound check against the count that sized the allocation. If the list holds more entries than the cached count, the copy runs off the end of the allocation into adjacent non-paged pool. The patch deletes the entire list-walk-and-copy path (and a second Size+32 allocation/RtlCopyMemory path), so the routine now unconditionally zeroes the buffer and emits only a fixed 32-byte event — removing the out-of-bounds write. Microsoft applied the same style of hardening to the sibling WheaAddErrorSource and WheaRemoveErrorSource loggers.

      Background

      The Windows Hardware Error Architecture (WHEA) is the kernel subsystem that receives, classifies, and logs machine-check exceptions, PCIe errors, ECC memory faults, and other platform hardware errors. Central to WHEA is the notion of an error source — a descriptor (WHEA_ERROR_SOURCE_DESCRIPTOR, 0x430 / 1072 bytes here) that tells the kernel where a class of errors comes from and how to handle it. Some sources are enumerated from firmware via the ACPI HEST (Hardware Error Source Table); others — the “non-HEST” sources — are registered dynamically, including by drivers through the documented WheaAddErrorSource/WheaAddErrorSourceDeviceDriver interface.

      Registered error sources live in a kernel table (WheapErrorSourceTable) and are also threaded onto a linked list rooted at qword_140CDB2E8. A running count of registered sources is cached in the global dword_140CDB2DC. During WHEA bring-up, WheaInitialize calls WheapLogInitEvent to emit a telemetry event that captures the full set of error-source descriptors for diagnostics — essentially serializing every 1072-byte descriptor into one contiguous buffer and shipping it through WheaLogInternalEvent / ETW (EVENT_WHEA_INIT_OP).

      The critical assumption baked into that serialization is that the number of nodes on the qword_140CDB2E8 list exactly equals dword_140CDB2DC — because the allocation is sized from the count, but the copy is driven by the list.

      Root Cause

      Here is the vulnerable core of the pre-patch WheapLogInitEvent:

      Size = 1072 * dword_140CDB2DC;
      PoolWithTag = (char *)ExAllocatePoolWithTag(NonPagedPoolNx, 1072 * dword_140CDB2DC, 0x61656857u); // 'Whea'
      if ( PoolWithTag )
      {
        if ( Feature_1162080569__private_IsEnabledDeviceUsage() )
        {
          memset(PoolWithTag, 0, Size);
        }
        else
        {
          v1 = (__int64 *)qword_140CDB2E8;
          for ( i = 0; v1 != &qword_140CDB2E8; v1 = (__int64 *)*v1 )  // walk the list
          {
            v3 = v1;
            v5 = &PoolWithTag[1072 * i];                              // destination indexed by i
            /* ... unrolled 1072-byte descriptor copy into v5 ... */
            ++i;                                                      // no comparison to dword_140CDB2DC
          }
        }
      

      The allocation size is 1072 * dword_140CDB2DC, a snapshot of the cached count. The copy loop, however, terminates only when the list walk returns to the sentinel (v1 != &qword_140CDB2E8). The destination pointer for iteration i is computed as &PoolWithTag[1072 * i], and i is incremented once per list node with nothing bounding it against dword_140CDB2DC. The inner unrolled sequence writes a full 1072-byte record (_OWORD stores stepping v5 by 128 bytes, eight times) each pass.

      So the buffer is sized by one quantity (the cached counter) and filled by another (the actual list length). Any divergence where the list is longer than the counter — a source added to the list without the counter having been incremented to match at snapshot time, or more generally a TOCTOU between “read count → allocate” and “walk list → copy” — sends the copy loop straight past the end of the allocation. Because i keeps climbing, this is not a fixed one-record overrun; each extra node adds another 1072 bytes of linear, attacker-influenced write into adjacent non-paged pool.

      The same design appears a second time later in the function. After emitting the ETW event, the routine allocates a second buffer whose size again depends on Size:

      v8 = 32;
      if ( Feature_3858493753__private_IsEnabledDeviceUsage() )
        v9 = 32;
      else
        v9 = Size + 32LL;                                   // Size = 1072 * dword_140CDB2DC
      v10 = ExAllocatePoolWithTag(NonPagedPoolNx, v9, 0x61656857u);
      ...
      if ( !Feature_3858493753__private_IsEnabledDeviceUsage() )
        memmove(v10 + 8, PoolWithTag, Size);               // copies the (already-overflowed) buffer
      

      The else path here appends the entire serialized descriptor blob to a 32-byte header and hands it to WheaLogInternalEvent. It inherits the same Size derived from the cached count, and it copies out of the buffer that the first loop may have overrun — propagating corrupted or over-read content into the logged event as well.

      Per the repo’s Feature_* rule set, note the polarity carefully: the CFR killswitches here (Feature_1162080569, Feature_3858493753) return true by default, and the safe behavior (memset / the fixed 32-byte v9 = 32 path) is what runs when they are enabled. The dangerous list-copy is the else/disabled branch — the legacy behavior the killswitch was already steering traffic away from. The GA patch finishes the job by deleting the legacy path outright.

      The Patch

      WheapLogInitEvent

      The post-patch function collapses dramatically — the decompiler renders it as a jump thunk into the reorganized body, and the diff shows the real shape: the entire error-source-list copy loop and the second Size+32 allocation/RtlCopyMemory path are gone. The changed call set makes the deletion explicit — RtlCopyMemory, Feature_1162080569__private_IsEnabledDeviceUsage, and Feature_3858493753__private_IsEnabledDeviceUsage all disappear from WheapLogInitEvent’s callee list, and the function length drops from 621 to 379 bytes.

      Before, the first buffer was conditionally either zeroed or filled by the unbounded loop:

          iVar5 = Feature_1162080569__private_IsEnabledDeviceUsage();
          if (iVar5 == 0) {
            /* ...walk DAT_1 list, copy 0x430 bytes at (uVar13 * 0x430 + _Dst) per node... */
          }
          else {
            memset(_Dst,0,(ulonglong)local_68[0]);
          }
      

      After, the branch is gone — the buffer is always just zeroed, and the list is never walked:

          _Dst = (void *)ExAllocatePoolWithTag(0x200,local_68[0],0x61656857);
          if (_Dst != (void *)0x0) {
            memset(_Dst,0,(ulonglong)local_68[0]);
            ...
      

      The second allocation is likewise reduced to a fixed 32-byte event with no data payload copied out of _Dst:

          // pre-patch: size = Size+32 (or 32), then RtlCopyMemory(puVar9+8, _Dst, Size)
          // post-patch:
          puVar3 = (undefined4 *)ExAllocatePoolWithTag(0x200,0x20,0x61656857);
          if (puVar3 != (undefined4 *)0x0) {
            puVar3[3] = 0;
            puVar3[7] = 0;
            *puVar3 = 0x674c6857;   // 'WhLg'
            puVar3[1] = 1;
            puVar3[2] = 0x20;
            puVar3[5] = 0x80000002;
            puVar3[4] = 0x4c4e524b; // 'KRNL'
            puVar3[6] = 2;
            WheaLogInternalEvent(puVar3);
            ExFreePool(puVar3,0x61656857);
          }
          ExFreePool(_Dst,0x61656857);
      

      The event still records the count (_Dst is allocated and zeroed, and DAT_0 / local_68[0] still feed the earlier EVENT_WHEA_INIT_OP ETW write), but the descriptors themselves are no longer serialized into a count-sized buffer via a list-driven loop. With no loop indexed by list length writing into a count-sized allocation, the mismatch that produced the overflow simply cannot occur. Microsoft chose to remove the feature rather than add a bound check — the descriptor blob in the init event was diagnostic, and dropping it is cheaper and safer than reconciling the counter and the list under a lock.

      WheaAddErrorSource and WheaRemoveErrorSource

      These two are co-patched but are not where the heap overflow lived. Both build a 0x430-byte descriptor snapshot on the stack for their own WheaLogInternalEvent telemetry, and both previously gated a field-zeroing step behind Feature_2504257848:

      // pre-patch WheaAddErrorSource
      iVar17 = Feature_2504257848__private_IsEnabledDeviceUsage();
      if ((iVar17 != 0) && (*(int *)(param_1 + 1) == 0x10)) {
        local_3c8 = 0; uStack_3c0 = 0; local_3b8 = 0; uStack_3d0 = 0; local_388 = 0;
      }
      

      Post-patch, the killswitch is removed and the zeroing runs unconditionally whenever the descriptor type is 0x10:

      // post-patch
      if (iVar1 == 0x10) {   // iVar1 = *(int *)(param_1 + 1)
        local_3c8 = 0; uStack_3c0 = 0; local_3b8 = 0; uStack_3d0 = 0; local_388 = 0;
      }
      

      WheaRemoveErrorSource receives the identical treatment (Feature_2504257848 dropped from its callee list, the *(int *)(lVar9 + 0x68) == 0x10 zeroing made unconditional). Per Rule 1 of the Feature_* semantics, removing a killswitch that already defaulted on is behavior-preserving cleanup — the actual hardening (zeroing specific descriptor fields for type-0x10 sources before they are logged, an info-leak mitigation preventing stale kernel data from riding along in the telemetry event) shipped earlier under the flag and is simply being made permanent here. These are consistency fixes across the WHEA logging family, not the CVE’s root-cause fix.

      Exploitability

      The primitive is a linear heap overflow in NonPagedPoolNx with the Whea (0x61656857) pool tag: each error-source node beyond the cached count writes an additional 1072 bytes of descriptor-shaped data past the end of the 1072 * dword_140CDB2DC allocation. Because the overrun grows one full descriptor per excess node and the descriptor content is derived from the attacker-registered error source, an attacker who controls how many sources are on the list versus the counter used to size the buffer gets a controllable-length, controllable-content pool overwrite — the classic setup for corrupting an adjacent pool object’s header or a function/_OBJECT pointer and pivoting to arbitrary execution or a privileged token swap.

      Reachability is local, matching the CVSS 8.8 AV:L vector and the MSRC “authorized attacker … elevate privileges locally” language. Non-HEST error sources are registrable from driver-adjacent kernel paths (WheaAddErrorSourceDeviceDriver), and WheapLogInitEvent fires from WheaInitialize during WHEA bring-up — so practical exploitation hinges on influencing the error-source list length relative to dword_140CDB2DC at the moment the init event is serialized, i.e. winning the count-vs-list race or otherwise inflating the list past the cached count. The complexity rating stays modest despite the boot-time trigger because the vulnerable copy has no bounds check at all: any divergence, however achieved, overflows deterministically once reached, and non-paged pool grooming for adjacent-object corruption is well-understood. The fix’s completeness — deleting the loop rather than clamping i — reflects that there was no safe count to clamp to without also fixing the counter/list synchronization, so Microsoft removed the serialization entirely.

      Pre patch functions

      Full decompilation of WheapLogInitEvent before the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      /* WARNING: Type propagation algorithm not settling */
      
      void WheapLogInitEvent(void)
      
      {
        undefined8 uVar1;
        undefined8 *puVar2;
        undefined8 *puVar3;
        char cVar4;
        int iVar5;
        int iVar6;
        uint uVar7;
        void *_Dst;
        undefined8 *puVar8;
        undefined4 *puVar9;
        undefined8 *puVar10;
        undefined8 *puVar11;
        longlong lVar12;
        ulonglong uVar13;
        undefined1 auStack_98 [32];
        undefined4 **local_78;
        uint local_68 [4];
        undefined4 *local_58;
        undefined4 local_50;
        undefined4 local_4c;
        uint *local_48;
        undefined4 local_40;
        undefined4 local_3c;
        uint *local_38;
        undefined4 local_30;
        undefined4 local_2c;
        void *local_28;
        uint local_20;
        undefined4 local_1c;
        ulonglong local_18;
        
        local_18 = __security_cookie ^ (ulonglong)auStack_98;
        local_68[0] = DAT_0 * 0x430;
        _Dst = (void *)ExAllocatePoolWithTag(0x200);
        if (_Dst != (void *)0x0) {
          iVar5 = Feature_1162080569__private_IsEnabledDeviceUsage();
          if (iVar5 == 0) {
            uVar13 = 0;
            puVar11 = DAT_1;
            if ((undefined8 **)DAT_1 != &DAT_1) {
              do {
                lVar12 = 8;
                puVar2 = (undefined8 *)(uVar13 * 0x430 + (longlong)_Dst);
                puVar3 = puVar11;
                do {
                  puVar10 = puVar3;
                  puVar8 = puVar2;
                  uVar1 = puVar10[1];
                  *puVar8 = *puVar10;
                  puVar8[1] = uVar1;
                  uVar1 = puVar10[3];
                  puVar8[2] = puVar10[2];
                  puVar8[3] = uVar1;
                  uVar1 = puVar10[5];
                  puVar8[4] = puVar10[4];
                  puVar8[5] = uVar1;
                  uVar1 = puVar10[7];
                  puVar8[6] = puVar10[6];
                  puVar8[7] = uVar1;
                  uVar1 = puVar10[9];
                  puVar8[8] = puVar10[8];
                  puVar8[9] = uVar1;
                  uVar1 = puVar10[0xb];
                  puVar8[10] = puVar10[10];
                  puVar8[0xb] = uVar1;
                  uVar1 = puVar10[0xd];
                  puVar8[0xc] = puVar10[0xc];
                  puVar8[0xd] = uVar1;
                  uVar1 = puVar10[0xf];
                  puVar8[0xe] = puVar10[0xe];
                  puVar8[0xf] = uVar1;
                  lVar12 = lVar12 + -1;
                  puVar2 = puVar8 + 0x10;
                  puVar3 = puVar10 + 0x10;
                } while (lVar12 != 0);
                uVar1 = puVar10[0x11];
                uVar13 = (ulonglong)((int)uVar13 + 1);
                puVar8[0x10] = puVar10[0x10];
                puVar8[0x11] = uVar1;
                uVar1 = puVar10[0x13];
                puVar8[0x12] = puVar10[0x12];
                puVar8[0x13] = uVar1;
                uVar1 = puVar10[0x15];
                puVar8[0x14] = puVar10[0x14];
                puVar8[0x15] = uVar1;
                puVar11 = (undefined8 *)*puVar11;
              } while ((undefined8 **)puVar11 != &DAT_1);
            }
          }
          else {
            memset(_Dst,0,(ulonglong)local_68[0]);
          }
          uVar1 = WheapEtwHandle;
          local_4c = 0;
          local_3c = 0;
          local_2c = 0;
          local_1c = 0;
          local_58 = &DAT_0;
          local_48 = local_68 + 1;
          local_38 = local_68;
          local_20 = local_68[0];
          local_50 = 4;
          local_68[1] = 10;
          local_40 = 4;
          local_30 = 4;
          local_28 = _Dst;
          cVar4 = EtwEventEnabled(WheapEtwHandle,&EVENT_WHEA_INIT_OP);
          if (cVar4 == '\x01') {
            local_78 = &local_58;
            EtwWrite(uVar1,&EVENT_WHEA_INIT_OP,0,4);
          }
          iVar6 = Feature_3858493753__private_IsEnabledDeviceUsage();
          iVar5 = 0x20;
          if (iVar6 == 0) {
            lVar12 = (ulonglong)local_68[0] + 0x20;
          }
          else {
            lVar12 = 0x20;
          }
          puVar9 = (undefined4 *)ExAllocatePoolWithTag(0x200,lVar12,0x61656857);
          if (puVar9 != (undefined4 *)0x0) {
            iVar6 = Feature_3858493753__private_IsEnabledDeviceUsage();
            if (iVar6 == 0) {
              iVar5 = local_68[0] + 0x20;
              uVar7 = local_68[0];
            }
            else {
              uVar7 = 0;
            }
            *puVar9 = 0x674c6857;
            puVar9[1] = 1;
            puVar9[2] = iVar5;
            puVar9[3] = 0;
            puVar9[5] = 0x80000002;
            puVar9[4] = 0x4c4e524b;
            puVar9[6] = 2;
            puVar9[7] = uVar7;
            iVar5 = Feature_3858493753__private_IsEnabledDeviceUsage();
            if (iVar5 == 0) {
              RtlCopyMemory(puVar9 + 8,_Dst,(ulonglong)local_68[0]);
            }
            WheaLogInternalEvent(puVar9);
            ExFreePool(puVar9,0x61656857);
          }
          ExFreePool(_Dst,0x61656857);
        }
        return;
      }
      

      Full decompilation of WheaAddErrorSource before the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      
      int WheaAddErrorSource(undefined8 *param_1,undefined8 param_2)
      
      {
        undefined8 uVar1;
        undefined4 uVar2;
        undefined4 uVar3;
        undefined4 uVar4;
        undefined4 uVar5;
        undefined4 uVar6;
        undefined4 uVar7;
        undefined4 uVar8;
        undefined4 uVar9;
        undefined8 uVar10;
        undefined8 uVar11;
        undefined8 uVar12;
        undefined8 *puVar13;
        undefined8 *puVar14;
        char cVar15;
        int iVar16;
        int iVar17;
        void *_Dst;
        longlong lVar18;
        undefined8 *puVar19;
        undefined8 *puVar20;
        longlong lVar21;
        undefined4 extraout_XMM0_Da;
        undefined1 auStack_458 [32];
        undefined4 local_438;
        undefined4 local_434;
        undefined4 local_430;
        undefined4 local_42c;
        undefined4 local_428;
        undefined4 local_424;
        undefined4 local_420;
        undefined4 local_41c;
        undefined8 local_418 [9];
        undefined8 uStack_3d0;
        undefined8 local_3c8;
        undefined8 uStack_3c0;
        undefined8 local_3b8;
        undefined8 local_388;
        int local_4c;
        undefined1 local_48;
        ulonglong local_38;
        
                          /* 0x7af4c0  2657  WheaAddErrorSource */
        local_38 = __security_cookie ^ (ulonglong)auStack_458;
        cVar15 = WheapIsNonHestErrorSource(*(int *)(param_1 + 1));
        lVar21 = 7;
        if (cVar15 == '\0') {
          iVar16 = -0x3fffff45;
        }
        else {
          _Dst = (void *)ExAllocatePoolWithTag(0x200,0x430,0x61656857);
          if (_Dst == (void *)0x0) {
            iVar16 = -0x3fffff66;
          }
          else {
            memset(_Dst,0,0x430);
            lVar18 = 7;
            puVar13 = (undefined8 *)((longlong)_Dst + 0x60);
            puVar14 = param_1;
            do {
              puVar20 = puVar14;
              puVar19 = puVar13;
              uVar1 = puVar20[1];
              *puVar19 = *puVar20;
              puVar19[1] = uVar1;
              uVar1 = puVar20[3];
              puVar19[2] = puVar20[2];
              puVar19[3] = uVar1;
              uVar1 = puVar20[5];
              puVar19[4] = puVar20[4];
              puVar19[5] = uVar1;
              uVar1 = puVar20[7];
              puVar19[6] = puVar20[6];
              puVar19[7] = uVar1;
              uVar1 = puVar20[9];
              puVar19[8] = puVar20[8];
              puVar19[9] = uVar1;
              uVar1 = puVar20[0xb];
              puVar19[10] = puVar20[10];
              puVar19[0xb] = uVar1;
              uVar1 = puVar20[0xd];
              puVar19[0xc] = puVar20[0xc];
              puVar19[0xd] = uVar1;
              uVar1 = puVar20[0xf];
              puVar19[0xe] = puVar20[0xe];
              puVar19[0xf] = uVar1;
              lVar18 = lVar18 + -1;
              puVar13 = puVar19 + 0x10;
              puVar14 = puVar20 + 0x10;
            } while (lVar18 != 0);
            uVar1 = puVar20[0x11];
            puVar19[0x10] = puVar20[0x10];
            puVar19[0x11] = uVar1;
            uVar1 = puVar20[0x13];
            puVar19[0x12] = puVar20[0x12];
            puVar19[0x13] = uVar1;
            uVar2 = *(undefined4 *)((longlong)puVar20 + 0xa4);
            uVar3 = *(undefined4 *)(puVar20 + 0x15);
            uVar4 = *(undefined4 *)((longlong)puVar20 + 0xac);
            *(undefined4 *)(puVar19 + 0x14) = *(undefined4 *)(puVar20 + 0x14);
            *(undefined4 *)((longlong)puVar19 + 0xa4) = uVar2;
            *(undefined4 *)(puVar19 + 0x15) = uVar3;
            *(undefined4 *)((longlong)puVar19 + 0xac) = uVar4;
            uVar2 = *(undefined4 *)((longlong)puVar20 + 0xb4);
            uVar3 = *(undefined4 *)(puVar20 + 0x17);
            uVar4 = *(undefined4 *)((longlong)puVar20 + 0xbc);
            *(undefined4 *)(puVar19 + 0x16) = *(undefined4 *)(puVar20 + 0x16);
            *(undefined4 *)((longlong)puVar19 + 0xb4) = uVar2;
            *(undefined4 *)(puVar19 + 0x17) = uVar3;
            *(undefined4 *)((longlong)puVar19 + 0xbc) = uVar4;
            puVar19[0x18] = puVar20[0x18];
            *(undefined4 *)(puVar19 + 0x19) = *(undefined4 *)(puVar20 + 0x19);
            iVar16 = WheapInitializeErrorSource(_Dst);
            if (iVar16 == 0) {
              *(undefined8 *)((longlong)_Dst + 0x38) = param_2;
              WheapAddErrorSource(extraout_XMM0_Da,_Dst);
              iVar16 = 0;
              if (WheapInitializationComplete != '\0') {
                *(undefined4 *)((longlong)_Dst + 0x6c) = 2;
                iVar16 = WheapCallErrorSourceInitialize(_Dst,1);
                if (iVar16 < 0) {
                  *(undefined4 *)((longlong)_Dst + 0x6c) = 1;
                }
              }
            }
            else {
              ExFreePool(_Dst,0x61656857);
            }
          }
        }
        local_42c = 0;
        local_438 = 0x674c6857;
        local_434 = 1;
        local_430 = 0x3f1;
        local_424 = 0x8000000c;
        local_428 = 0x4c4e524b;
        local_420 = 2;
        local_41c = 0x3d1;
        puVar13 = local_418;
        puVar14 = param_1;
        do {
          puVar20 = puVar14;
          puVar19 = puVar13;
          uVar1 = puVar20[1];
          uVar10 = puVar20[2];
          uVar11 = puVar20[3];
          *puVar19 = *puVar20;
          puVar19[1] = uVar1;
          uVar1 = puVar20[4];
          uVar12 = puVar20[5];
          puVar19[2] = uVar10;
          puVar19[3] = uVar11;
          uVar10 = puVar20[6];
          uVar11 = puVar20[7];
          puVar19[4] = uVar1;
          puVar19[5] = uVar12;
          uVar1 = puVar20[8];
          uVar12 = puVar20[9];
          puVar19[6] = uVar10;
          puVar19[7] = uVar11;
          uVar10 = puVar20[10];
          uVar11 = puVar20[0xb];
          puVar19[8] = uVar1;
          puVar19[9] = uVar12;
          uVar1 = puVar20[0xc];
          uVar12 = puVar20[0xd];
          puVar19[10] = uVar10;
          puVar19[0xb] = uVar11;
          uVar10 = puVar20[0xe];
          uVar11 = puVar20[0xf];
          puVar19[0xc] = uVar1;
          puVar19[0xd] = uVar12;
          puVar19[0xe] = uVar10;
          puVar19[0xf] = uVar11;
          lVar21 = lVar21 + -1;
          puVar13 = puVar19 + 0x10;
          puVar14 = puVar20 + 0x10;
        } while (lVar21 != 0);
        uVar10 = puVar20[0x11];
        uVar1 = puVar20[0x18];
        uVar11 = puVar20[0x12];
        uVar12 = puVar20[0x13];
        puVar19[0x10] = puVar20[0x10];
        puVar19[0x11] = uVar10;
        uVar2 = *(undefined4 *)(puVar20 + 0x14);
        uVar3 = *(undefined4 *)((longlong)puVar20 + 0xa4);
        uVar4 = *(undefined4 *)(puVar20 + 0x15);
        uVar5 = *(undefined4 *)((longlong)puVar20 + 0xac);
        puVar19[0x12] = uVar11;
        puVar19[0x13] = uVar12;
        uVar6 = *(undefined4 *)(puVar20 + 0x16);
        uVar7 = *(undefined4 *)((longlong)puVar20 + 0xb4);
        uVar8 = *(undefined4 *)(puVar20 + 0x17);
        uVar9 = *(undefined4 *)((longlong)puVar20 + 0xbc);
        *(undefined4 *)(puVar19 + 0x14) = uVar2;
        *(undefined4 *)((longlong)puVar19 + 0xa4) = uVar3;
        *(undefined4 *)(puVar19 + 0x15) = uVar4;
        *(undefined4 *)((longlong)puVar19 + 0xac) = uVar5;
        *(undefined4 *)(puVar19 + 0x16) = uVar6;
        *(undefined4 *)((longlong)puVar19 + 0xb4) = uVar7;
        *(undefined4 *)(puVar19 + 0x17) = uVar8;
        *(undefined4 *)((longlong)puVar19 + 0xbc) = uVar9;
        puVar19[0x18] = uVar1;
        *(undefined4 *)(puVar19 + 0x19) = *(undefined4 *)(puVar20 + 0x19);
        iVar17 = Feature_2504257848__private_IsEnabledDeviceUsage();
        if ((iVar17 != 0) && (*(int *)(param_1 + 1) == 0x10)) {
          local_3c8 = 0;
          uStack_3c0 = 0;
          local_3b8 = 0;
          uStack_3d0 = 0;
          local_388 = 0;
        }
        local_48 = 0;
        local_4c = iVar16;
        WheaLogInternalEvent(&local_438);
        return iVar16;
      }
      

      Full decompilation of WheaRemoveErrorSource before the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      
      void WheaRemoveErrorSource(undefined4 param_1)
      
      {
        undefined4 uVar1;
        undefined4 uVar2;
        undefined8 uVar3;
        undefined8 *puVar4;
        undefined8 *puVar5;
        char cVar6;
        undefined4 uVar7;
        int iVar8;
        longlong lVar9;
        longlong lVar10;
        undefined8 *puVar11;
        undefined8 *puVar12;
        undefined1 auStack_448 [32];
        undefined8 local_428 [2];
        undefined4 local_418;
        undefined4 local_414;
        undefined4 local_410;
        undefined4 local_40c;
        undefined4 local_408;
        undefined4 local_404;
        undefined4 local_400;
        undefined4 local_3fc;
        undefined8 local_3f8 [9];
        undefined8 uStack_3b0;
        undefined8 local_3a8;
        undefined8 uStack_3a0;
        undefined8 local_398;
        undefined8 local_368;
        undefined4 local_2c;
        undefined1 local_28;
        ulonglong local_18;
        
                          /* 0x95d1f0  2680  WheaRemoveErrorSource */
        local_18 = __security_cookie ^ (ulonglong)auStack_448;
        lVar9 = WheapGetErrorSource(&WheapErrorSourceTable,param_1);
        if (((lVar9 != 0) &&
            (cVar6 = WheapIsNonHestErrorSource(*(undefined4 *)(lVar9 + 0x68)), cVar6 != '\0')) &&
           (1 < *(int *)(lVar9 + 0x6c) - 3U)) {
          lVar10 = 7;
          local_428[0] = 0xfffffffffffffc18;
          puVar4 = (undefined8 *)(lVar9 + 0x60);
          puVar5 = local_3f8;
          do {
            puVar12 = puVar5;
            puVar11 = puVar4;
            uVar3 = puVar11[1];
            *puVar12 = *puVar11;
            puVar12[1] = uVar3;
            uVar3 = puVar11[3];
            puVar12[2] = puVar11[2];
            puVar12[3] = uVar3;
            uVar3 = puVar11[5];
            puVar12[4] = puVar11[4];
            puVar12[5] = uVar3;
            uVar3 = puVar11[7];
            puVar12[6] = puVar11[6];
            puVar12[7] = uVar3;
            uVar3 = puVar11[9];
            puVar12[8] = puVar11[8];
            puVar12[9] = uVar3;
            uVar3 = puVar11[0xb];
            puVar12[10] = puVar11[10];
            puVar12[0xb] = uVar3;
            uVar3 = puVar11[0xd];
            puVar12[0xc] = puVar11[0xc];
            puVar12[0xd] = uVar3;
            uVar3 = puVar11[0xf];
            puVar12[0xe] = puVar11[0xe];
            puVar12[0xf] = uVar3;
            lVar10 = lVar10 + -1;
            puVar4 = puVar11 + 0x10;
            puVar5 = puVar12 + 0x10;
          } while (lVar10 != 0);
          uVar3 = puVar11[0x11];
          puVar12[0x10] = puVar11[0x10];
          puVar12[0x11] = uVar3;
          uVar3 = puVar11[0x13];
          puVar12[0x12] = puVar11[0x12];
          puVar12[0x13] = uVar3;
          uVar7 = *(undefined4 *)((longlong)puVar11 + 0xa4);
          uVar1 = *(undefined4 *)(puVar11 + 0x15);
          uVar2 = *(undefined4 *)((longlong)puVar11 + 0xac);
          *(undefined4 *)(puVar12 + 0x14) = *(undefined4 *)(puVar11 + 0x14);
          *(undefined4 *)((longlong)puVar12 + 0xa4) = uVar7;
          *(undefined4 *)(puVar12 + 0x15) = uVar1;
          *(undefined4 *)((longlong)puVar12 + 0xac) = uVar2;
          uVar3 = puVar11[0x17];
          puVar12[0x16] = puVar11[0x16];
          puVar12[0x17] = uVar3;
          puVar12[0x18] = puVar11[0x18];
          *(undefined4 *)(puVar12 + 0x19) = *(undefined4 *)(puVar11 + 0x19);
          *(undefined4 *)(lVar9 + 0x6c) = 4;
          while( true ) {
            LOCK();
            iVar8 = *(int *)(lVar9 + 0x5c);
            if (iVar8 == 0) {
              *(int *)(lVar9 + 0x5c) = -1;
              iVar8 = 0;
            }
            UNLOCK();
            if (iVar8 < 1) break;
            KeDelayExecutionThread(0,0,local_428);
          }
          uVar7 = WheapCallErrorSourceUninitialize(lVar9);
          *(undefined4 *)(lVar9 + 0x6c) = 3;
          if (*(longlong *)(lVar9 + 0x30) != 0) {
            ExFreePool(*(longlong *)(lVar9 + 0x30),0x61656857);
            *(undefined8 *)(lVar9 + 0x30) = 0;
          }
          local_40c = 0;
          local_418 = 0x674c6857;
          local_414 = 1;
          local_410 = 0x3f1;
          local_404 = 0x8000000c;
          local_408 = 0x4c4e524b;
          local_400 = 2;
          local_3fc = 0x3d1;
          iVar8 = Feature_2504257848__private_IsEnabledDeviceUsage();
          if ((iVar8 != 0) && (*(int *)(lVar9 + 0x68) == 0x10)) {
            local_3a8 = 0;
            uStack_3a0 = 0;
            local_398 = 0;
            uStack_3b0 = 0;
            local_368 = 0;
          }
          local_28 = 1;
          local_2c = uVar7;
          WheaLogInternalEvent(&local_418);
        }
        return;
      }
      

      Post patch functions

      Full decompilation of WheapLogInitEvent after the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      /* WARNING: Type propagation algorithm not settling */
      
      void WheapLogInitEvent(void)
      
      {
        undefined8 uVar1;
        char cVar2;
        void *_Dst;
        undefined4 *puVar3;
        undefined1 auStack_98 [32];
        undefined4 **local_78;
        uint local_68 [4];
        undefined4 *local_58;
        undefined4 local_50;
        undefined4 local_4c;
        uint *local_48;
        undefined4 local_40;
        undefined4 local_3c;
        uint *local_38;
        undefined4 local_30;
        undefined4 local_2c;
        void *local_28;
        uint local_20;
        undefined4 local_1c;
        ulonglong local_18;
        
        local_18 = __security_cookie ^ (ulonglong)auStack_98;
        local_68[0] = DAT_0 * 0x430;
        _Dst = (void *)ExAllocatePoolWithTag(0x200,local_68[0],0x61656857);
        if (_Dst != (void *)0x0) {
          memset(_Dst,0,(ulonglong)local_68[0]);
          uVar1 = WheapEtwHandle;
          local_4c = 0;
          local_3c = 0;
          local_2c = 0;
          local_1c = 0;
          local_58 = &DAT_0;
          local_48 = local_68 + 1;
          local_38 = local_68;
          local_20 = local_68[0];
          local_50 = 4;
          local_68[1] = 10;
          local_40 = 4;
          local_30 = 4;
          local_28 = _Dst;
          cVar2 = EtwEventEnabled(WheapEtwHandle,&EVENT_WHEA_INIT_OP);
          if (cVar2 == '\x01') {
            local_78 = &local_58;
            EtwWrite(uVar1,&EVENT_WHEA_INIT_OP,0,4);
          }
          puVar3 = (undefined4 *)ExAllocatePoolWithTag(0x200,0x20,0x61656857);
          if (puVar3 != (undefined4 *)0x0) {
            puVar3[3] = 0;
            puVar3[7] = 0;
            *puVar3 = 0x674c6857;
            puVar3[1] = 1;
            puVar3[2] = 0x20;
            puVar3[5] = 0x80000002;
            puVar3[4] = 0x4c4e524b;
            puVar3[6] = 2;
            WheaLogInternalEvent(puVar3);
            ExFreePool(puVar3,0x61656857);
          }
          ExFreePool(_Dst,0x61656857);
        }
        return;
      }
      

      Full decompilation of WheaAddErrorSource after the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      
      int WheaAddErrorSource(undefined8 *param_1,undefined8 param_2)
      
      {
        int iVar1;
        undefined8 uVar2;
        undefined4 uVar3;
        undefined4 uVar4;
        undefined4 uVar5;
        undefined4 uVar6;
        undefined4 uVar7;
        undefined4 uVar8;
        undefined4 uVar9;
        undefined4 uVar10;
        undefined8 uVar11;
        undefined8 uVar12;
        undefined8 uVar13;
        undefined8 *puVar14;
        undefined8 *puVar15;
        char cVar16;
        int iVar17;
        void *_Dst;
        longlong lVar18;
        undefined8 *puVar19;
        undefined8 *puVar20;
        longlong lVar21;
        undefined4 extraout_XMM0_Da;
        undefined1 auStack_458 [32];
        undefined4 local_438;
        undefined4 local_434;
        undefined4 local_430;
        undefined4 local_42c;
        undefined4 local_428;
        undefined4 local_424;
        undefined4 local_420;
        undefined4 local_41c;
        undefined8 local_418 [9];
        undefined8 uStack_3d0;
        undefined8 local_3c8;
        undefined8 uStack_3c0;
        undefined8 local_3b8;
        undefined8 local_388;
        int local_4c;
        undefined1 local_48;
        ulonglong local_38;
        
                          /* 0x7af4c0  2657  WheaAddErrorSource */
        local_38 = __security_cookie ^ (ulonglong)auStack_458;
        cVar16 = WheapIsNonHestErrorSource(*(int *)(param_1 + 1));
        lVar21 = 7;
        if (cVar16 == '\0') {
          iVar17 = -0x3fffff45;
        }
        else {
          _Dst = (void *)ExAllocatePoolWithTag(0x200,0x430,0x61656857);
          if (_Dst == (void *)0x0) {
            iVar17 = -0x3fffff66;
          }
          else {
            memset(_Dst,0,0x430);
            lVar18 = 7;
            puVar14 = (undefined8 *)((longlong)_Dst + 0x60);
            puVar15 = param_1;
            do {
              puVar20 = puVar15;
              puVar19 = puVar14;
              uVar2 = puVar20[1];
              *puVar19 = *puVar20;
              puVar19[1] = uVar2;
              uVar2 = puVar20[3];
              puVar19[2] = puVar20[2];
              puVar19[3] = uVar2;
              uVar2 = puVar20[5];
              puVar19[4] = puVar20[4];
              puVar19[5] = uVar2;
              uVar2 = puVar20[7];
              puVar19[6] = puVar20[6];
              puVar19[7] = uVar2;
              uVar2 = puVar20[9];
              puVar19[8] = puVar20[8];
              puVar19[9] = uVar2;
              uVar2 = puVar20[0xb];
              puVar19[10] = puVar20[10];
              puVar19[0xb] = uVar2;
              uVar2 = puVar20[0xd];
              puVar19[0xc] = puVar20[0xc];
              puVar19[0xd] = uVar2;
              uVar2 = puVar20[0xf];
              puVar19[0xe] = puVar20[0xe];
              puVar19[0xf] = uVar2;
              lVar18 = lVar18 + -1;
              puVar14 = puVar19 + 0x10;
              puVar15 = puVar20 + 0x10;
            } while (lVar18 != 0);
            uVar2 = puVar20[0x11];
            puVar19[0x10] = puVar20[0x10];
            puVar19[0x11] = uVar2;
            uVar2 = puVar20[0x13];
            puVar19[0x12] = puVar20[0x12];
            puVar19[0x13] = uVar2;
            uVar3 = *(undefined4 *)((longlong)puVar20 + 0xa4);
            uVar4 = *(undefined4 *)(puVar20 + 0x15);
            uVar5 = *(undefined4 *)((longlong)puVar20 + 0xac);
            *(undefined4 *)(puVar19 + 0x14) = *(undefined4 *)(puVar20 + 0x14);
            *(undefined4 *)((longlong)puVar19 + 0xa4) = uVar3;
            *(undefined4 *)(puVar19 + 0x15) = uVar4;
            *(undefined4 *)((longlong)puVar19 + 0xac) = uVar5;
            uVar3 = *(undefined4 *)((longlong)puVar20 + 0xb4);
            uVar4 = *(undefined4 *)(puVar20 + 0x17);
            uVar5 = *(undefined4 *)((longlong)puVar20 + 0xbc);
            *(undefined4 *)(puVar19 + 0x16) = *(undefined4 *)(puVar20 + 0x16);
            *(undefined4 *)((longlong)puVar19 + 0xb4) = uVar3;
            *(undefined4 *)(puVar19 + 0x17) = uVar4;
            *(undefined4 *)((longlong)puVar19 + 0xbc) = uVar5;
            puVar19[0x18] = puVar20[0x18];
            *(undefined4 *)(puVar19 + 0x19) = *(undefined4 *)(puVar20 + 0x19);
            iVar17 = WheapInitializeErrorSource(_Dst);
            if (iVar17 == 0) {
              *(undefined8 *)((longlong)_Dst + 0x38) = param_2;
              WheapAddErrorSource(extraout_XMM0_Da,_Dst);
              iVar17 = 0;
              if (WheapInitializationComplete != '\0') {
                *(undefined4 *)((longlong)_Dst + 0x6c) = 2;
                iVar17 = WheapCallErrorSourceInitialize(_Dst,1);
                if (iVar17 < 0) {
                  *(undefined4 *)((longlong)_Dst + 0x6c) = 1;
                }
              }
            }
            else {
              ExFreePool(_Dst,0x61656857);
            }
          }
        }
        local_42c = 0;
        local_438 = 0x674c6857;
        local_434 = 1;
        local_430 = 0x3f1;
        local_424 = 0x8000000c;
        local_428 = 0x4c4e524b;
        local_420 = 2;
        local_41c = 0x3d1;
        puVar14 = local_418;
        puVar15 = param_1;
        do {
          puVar20 = puVar15;
          puVar19 = puVar14;
          uVar2 = puVar20[1];
          uVar11 = puVar20[2];
          uVar12 = puVar20[3];
          *puVar19 = *puVar20;
          puVar19[1] = uVar2;
          uVar2 = puVar20[4];
          uVar13 = puVar20[5];
          puVar19[2] = uVar11;
          puVar19[3] = uVar12;
          uVar11 = puVar20[6];
          uVar12 = puVar20[7];
          puVar19[4] = uVar2;
          puVar19[5] = uVar13;
          uVar2 = puVar20[8];
          uVar13 = puVar20[9];
          puVar19[6] = uVar11;
          puVar19[7] = uVar12;
          uVar11 = puVar20[10];
          uVar12 = puVar20[0xb];
          puVar19[8] = uVar2;
          puVar19[9] = uVar13;
          uVar2 = puVar20[0xc];
          uVar13 = puVar20[0xd];
          puVar19[10] = uVar11;
          puVar19[0xb] = uVar12;
          uVar11 = puVar20[0xe];
          uVar12 = puVar20[0xf];
          puVar19[0xc] = uVar2;
          puVar19[0xd] = uVar13;
          puVar19[0xe] = uVar11;
          puVar19[0xf] = uVar12;
          lVar21 = lVar21 + -1;
          puVar14 = puVar19 + 0x10;
          puVar15 = puVar20 + 0x10;
        } while (lVar21 != 0);
        iVar1 = *(int *)(param_1 + 1);
        uVar11 = puVar20[0x11];
        uVar2 = puVar20[0x18];
        uVar12 = puVar20[0x12];
        uVar13 = puVar20[0x13];
        puVar19[0x10] = puVar20[0x10];
        puVar19[0x11] = uVar11;
        uVar3 = *(undefined4 *)(puVar20 + 0x14);
        uVar4 = *(undefined4 *)((longlong)puVar20 + 0xa4);
        uVar5 = *(undefined4 *)(puVar20 + 0x15);
        uVar6 = *(undefined4 *)((longlong)puVar20 + 0xac);
        puVar19[0x12] = uVar12;
        puVar19[0x13] = uVar13;
        uVar7 = *(undefined4 *)(puVar20 + 0x16);
        uVar8 = *(undefined4 *)((longlong)puVar20 + 0xb4);
        uVar9 = *(undefined4 *)(puVar20 + 0x17);
        uVar10 = *(undefined4 *)((longlong)puVar20 + 0xbc);
        *(undefined4 *)(puVar19 + 0x14) = uVar3;
        *(undefined4 *)((longlong)puVar19 + 0xa4) = uVar4;
        *(undefined4 *)(puVar19 + 0x15) = uVar5;
        *(undefined4 *)((longlong)puVar19 + 0xac) = uVar6;
        *(undefined4 *)(puVar19 + 0x16) = uVar7;
        *(undefined4 *)((longlong)puVar19 + 0xb4) = uVar8;
        *(undefined4 *)(puVar19 + 0x17) = uVar9;
        *(undefined4 *)((longlong)puVar19 + 0xbc) = uVar10;
        puVar19[0x18] = uVar2;
        *(undefined4 *)(puVar19 + 0x19) = *(undefined4 *)(puVar20 + 0x19);
        if (iVar1 == 0x10) {
          local_3c8 = 0;
          uStack_3c0 = 0;
          local_3b8 = 0;
          uStack_3d0 = 0;
          local_388 = 0;
        }
        local_48 = 0;
        local_4c = iVar17;
        WheaLogInternalEvent(&local_438);
        return iVar17;
      }
      

      Full decompilation of WheaRemoveErrorSource after the patch:

      /* WARNING: Function: __security_check_cookie replaced with injection: security_check_cookie */
      
      void WheaRemoveErrorSource(undefined4 param_1)
      
      {
        undefined4 uVar1;
        undefined4 uVar2;
        undefined4 uVar3;
        undefined8 uVar4;
        undefined8 *puVar5;
        undefined8 *puVar6;
        char cVar7;
        int iVar8;
        longlong lVar9;
        longlong lVar10;
        undefined8 *puVar11;
        undefined8 *puVar12;
        undefined1 auStack_448 [32];
        undefined8 local_428 [2];
        undefined4 local_418;
        undefined4 local_414;
        undefined4 local_410;
        undefined4 local_40c;
        undefined4 local_408;
        undefined4 local_404;
        undefined4 local_400;
        undefined4 local_3fc;
        undefined8 local_3f8 [9];
        undefined8 uStack_3b0;
        undefined8 local_3a8;
        undefined8 uStack_3a0;
        undefined8 local_398;
        undefined8 local_368;
        undefined4 local_2c;
        undefined1 local_28;
        ulonglong local_18;
        
                          /* 0x95d100  2680  WheaRemoveErrorSource */
        local_18 = __security_cookie ^ (ulonglong)auStack_448;
        lVar9 = WheapGetErrorSource(&WheapErrorSourceTable,param_1);
        if (((lVar9 != 0) &&
            (cVar7 = WheapIsNonHestErrorSource(*(undefined4 *)(lVar9 + 0x68)), cVar7 != '\0')) &&
           (1 < *(int *)(lVar9 + 0x6c) - 3U)) {
          lVar10 = 7;
          local_428[0] = 0xfffffffffffffc18;
          puVar5 = (undefined8 *)(lVar9 + 0x60);
          puVar6 = local_3f8;
          do {
            puVar12 = puVar6;
            puVar11 = puVar5;
            uVar4 = puVar11[1];
            *puVar12 = *puVar11;
            puVar12[1] = uVar4;
            uVar4 = puVar11[3];
            puVar12[2] = puVar11[2];
            puVar12[3] = uVar4;
            uVar4 = puVar11[5];
            puVar12[4] = puVar11[4];
            puVar12[5] = uVar4;
            uVar4 = puVar11[7];
            puVar12[6] = puVar11[6];
            puVar12[7] = uVar4;
            uVar4 = puVar11[9];
            puVar12[8] = puVar11[8];
            puVar12[9] = uVar4;
            uVar4 = puVar11[0xb];
            puVar12[10] = puVar11[10];
            puVar12[0xb] = uVar4;
            uVar4 = puVar11[0xd];
            puVar12[0xc] = puVar11[0xc];
            puVar12[0xd] = uVar4;
            uVar4 = puVar11[0xf];
            puVar12[0xe] = puVar11[0xe];
            puVar12[0xf] = uVar4;
            lVar10 = lVar10 + -1;
            puVar5 = puVar11 + 0x10;
            puVar6 = puVar12 + 0x10;
          } while (lVar10 != 0);
          uVar4 = puVar11[0x11];
          puVar12[0x10] = puVar11[0x10];
          puVar12[0x11] = uVar4;
          uVar4 = puVar11[0x13];
          puVar12[0x12] = puVar11[0x12];
          puVar12[0x13] = uVar4;
          uVar1 = *(undefined4 *)((longlong)puVar11 + 0xa4);
          uVar2 = *(undefined4 *)(puVar11 + 0x15);
          uVar3 = *(undefined4 *)((longlong)puVar11 + 0xac);
          *(undefined4 *)(puVar12 + 0x14) = *(undefined4 *)(puVar11 + 0x14);
          *(undefined4 *)((longlong)puVar12 + 0xa4) = uVar1;
          *(undefined4 *)(puVar12 + 0x15) = uVar2;
          *(undefined4 *)((longlong)puVar12 + 0xac) = uVar3;
          uVar4 = puVar11[0x17];
          puVar12[0x16] = puVar11[0x16];
          puVar12[0x17] = uVar4;
          puVar12[0x18] = puVar11[0x18];
          *(undefined4 *)(puVar12 + 0x19) = *(undefined4 *)(puVar11 + 0x19);
          *(undefined4 *)(lVar9 + 0x6c) = 4;
          while( true ) {
            LOCK();
            iVar8 = *(int *)(lVar9 + 0x5c);
            if (iVar8 == 0) {
              *(int *)(lVar9 + 0x5c) = -1;
              iVar8 = 0;
            }
            UNLOCK();
            if (iVar8 < 1) break;
            KeDelayExecutionThread(0,0,local_428);
          }
          local_2c = WheapCallErrorSourceUninitialize(lVar9);
          *(undefined4 *)(lVar9 + 0x6c) = 3;
          if (*(longlong *)(lVar9 + 0x30) != 0) {
            ExFreePool(*(longlong *)(lVar9 + 0x30),0x61656857);
            *(undefined8 *)(lVar9 + 0x30) = 0;
          }
          local_40c = 0;
          local_418 = 0x674c6857;
          local_414 = 1;
          local_410 = 0x3f1;
          local_404 = 0x8000000c;
          local_408 = 0x4c4e524b;
          local_400 = 2;
          local_3fc = 0x3d1;
          if (*(int *)(lVar9 + 0x68) == 0x10) {
            local_3a8 = 0;
            uStack_3a0 = 0;
            local_398 = 0;
            uStack_3b0 = 0;
            local_368 = 0;
          }
          local_28 = 1;
          WheaLogInternalEvent(&local_418);
        }
        return;
      }