typeanalysisfamily54e64econfidencemediumcreated2026-08-18updated2026-08-18pemalware-familyloaderc2defense-evasioncompilerobfuscationevasion
SHA-256: 16520f80193c6e45d207ac0ffad8b29446194ad9734d7ee2ea8178f91eacf491

54e64e: 16520f80 — MSVC 14.44 reflective loader with 7.3 MB encrypted payload

Executive Summary

MSVC C++ x64 reflective loader (7.5 MB) sharing the same build pipeline as sibling de601a8a (Morph 10) — MSVC 14.44, VS 2022 v143, IMAGE_DEBUG_TYPE_POGO — but scaled to a 7.3 MB encrypted payload in section 02. Minimal IAT (7 KERNEL32 imports), runtime API resolution, TLS callback anti-disassembly gate, and high-entropy encrypted payload. No readable C2 strings recovered statically. Eleventh confirmed build morph under the 54e64e umbrella. Static-only (CAPE skipped — no Windows guest).

What It Is

  • File: PE32+ x64 GUI, 7,576,064 bytes, MSVC 14.44 (VS 2022 17.x), build timestamp 2026-05-29 03:04:59 UTC ^[file.txt] ^[pefile.txt:38] ^[exiftool.json:15-18]
  • Sections: 8 sections — four null-padded on-disk (.text, .rdata, .data, .pdata), one null-padded placeholder (00), IAT section (01), encrypted payload (02, 7.3 MB, entropy 7.81), and .reloc ^[pefile.txt:79-241]
  • Signing: Unsigned ^[rabin2-info.txt:27]
  • IAT: 7 KERNEL32 imports only — GetSystemDirectoryW, HeapAlloc, HeapFree, ExitProcess, LoadLibraryA, GetModuleHandleA, GetProcAddress ^[pefile.txt:294-319]
  • Rich header: Linker1400, Cvtres1400, Utc1900_C, Masm1400 — consistent with VS 2022 v143 toolset ^[rabin2-info.txt:Product lines]
  • Debug: IMAGE_DEBUG_TYPE_POGO at 0x735460, matching compile timestamp; binary is not stripped ^[pefile.txt:387-399]
  • TLS: TLS directory present at 0x14046B1F0 with 8-byte raw data region; callback array pointer is zero ^[pefile.txt:321-329]

How It Works

Structural overview

This binary is a scaled sibling of de601a8a (Morph 10). Both share the MSVC 14.44 toolchain, IMAGE_DEBUG_TYPE_POGO, minimal IAT, and encrypted payload-in-section design. The critical difference is scale: de601a8a is 10.5 KB with a ~2.3 MB decrypted payload; this sample is 7.5 MB with a 7.3 MB encrypted payload in section 02 (entropy 7.81). The first four sections have SizeOfRawData=0 — their virtual sizes are allocated at runtime but contain no on-disk data, a null-padded anti-triage technique.

Entry point anti-disassembly

The PE entry point RVA is 0x7D8504, which falls inside section 02 (the encrypted payload). The bytes at this offset (e8 da 40 c7 ff) decode as call 0x14044c5e3 in x64, but the call target falls inside what appears to be encrypted data. When radare2 attempts to follow the call, it hits a pushfq; add qword [rsp+8], ... sequence that manipulates the stack and flags before pushing the original return address back and jumping to a distant location. This is a TLS-callback-style anti-disassembly gate — the entry point is not meant to be statically traced; it delegates to a decryption/loader routine embedded in the encrypted section. ^[r2:entry0 @ 0x1407d8504] ^[r2:fcn @ 0x14044c5e3]

Encrypted payload

Section 02 occupies file offsets 0xC00–0x738BFF (7.3 MB on disk, mapped to VA 0x1403DA000–0x140B12B08). It is marked r-x (code + execute) with MEM_NOT_PAGED. The first bytes (48 0b 5a 04 c8 51 4b e1...) are not valid x64 prologue — this is encrypted/encoded data. The high entropy (256/256 unique bytes in every 64 KB window) confirms strong encryption, not compression. No ZIP, UPX, or standard packer signatures detected. ^[binwalk.txt] ^[pefile.txt:203-221]

Runtime API resolution pattern

The IAT contains only KERNEL32 stubs. The LoadLibraryA + GetProcAddress pair is present, confirming runtime resolution of additional DLLs (WinHTTP, Shell32, OLE32, etc.) — identical pattern to de601a8a. The GetSystemDirectoryW import suggests the loader may resolve system paths for payload staging or DLL search-order hijacking. ^[pefile.txt:294-319]

Null-padded sections as anti-triage

Sections .text, .rdata, .data, and .pdata all have SizeOfRawData=0 and PointerToRawData=0. Their virtual sizes are 0x51DB0, 0x12A48, 0x4F04, and 0x3D2C respectively — allocated at runtime but empty on disk. This is a deliberate anti-triage measure: tools that scan file offsets (e.g., YARA on-disk rules, binwalk, ssdeep) see nothing in these sections. Only runtime memory analysis or section-header-aware tools will see the full layout. ^[pefile.txt:83-162]

Decompiled Behavior

Entry point (entry0 @ 0x1407d8504): A call instruction targets an address inside the encrypted payload region. The target bytes (9c 48 81 44 24 08...) decode as stack/flag manipulation followed by a long jump. Radare2 cannot resolve the final destination statically. The call is immediately followed by garbage bytes (8f f0 8f...) that are not valid x64 — these are encrypted data that the stub will decrypt in-place before execution. ^[r2:entry0]

No valid static functions recoverable inside section 02. The encrypted payload prevents standard disassembly. The .text section (VA 0x140001000) is entirely null bytes on disk — any code there would need to be unpacked/decrypted at runtime.

C2 Infrastructure

No hardcoded C2 strings, domains, IPs, URLs, mutex names, named pipes, or registry keys observed statically. The encrypted payload likely contains C2 configuration, decrypted at runtime by the loader stub. This is consistent with the de601a8a Morph 10 pattern, which stored its Google Drive staging URL inside the payload and resolved it only after decryption.

Indicator Type Value Evidence
Primary payload encrypted section 02 @ 0x1403DA000, 7.3 MB ^[pefile.txt:203-221]
Staging mechanism inferred Runtime-decrypted payload + API resolution ^[pefile.txt:294-319]
Hardcoded C2 none recovered — static-only analysis

Interesting Tidbits

  • Scaled sibling of de601a8a: Same MSVC 14.44 toolchain, same IMAGE_DEBUG_TYPE_POGO, same null-padded section trick, same minimal IAT, same anti-disassembly entry point. The only major difference is payload size (7.3 MB vs ~2.3 MB). This suggests a parameterized builder where the operator can adjust payload size and possibly C2 URL, with the stub code remaining constant. ^[/intel/analyses/de601a8a3d45d818f6bd867f5bba33d576bc1d9d983511b66f2b22447dd5d8e4.html]
  • 7.3 MB encrypted payload: The payload is marked executable (r-x) and not pageable (MEM_NOT_PAGED). This is large enough to contain a full second-stage PE, multiple payloads, or a memory-only implant. The size suggests this is not a simple dropper but a full-featured RAT/stealer delivered in encrypted form. ^[pefile.txt:203-221]
  • Null-padded on-disk sections: The first four sections have zero on-disk size but non-zero virtual size. This is a known anti-static technique that breaks naive file-offset scanners. Tools like YARA must be configured to scan virtual addresses (memory) rather than raw file offsets to match against decrypted content. ^[pefile.txt:83-162]
  • No version info, no icon, no masquerade: No .rsrc section at all (Directory entry RVA=0). The binary relies entirely on its encrypted interior and minimal surface for evasion. No social-engineering masquerade — this is a pure loader. ^[pefile.txt:251-253]
  • Build timestamp consistency: Compile timestamp 2026-05-29 03:04:59 UTC is 25 minutes before the MalwareBazaar upload (03:30:05 UTC). Short build-to-upload gap suggests automated pipeline or direct operator upload. ^[exiftool.json:15] ^[exiftool.json:7]
  • Entry point inside encrypted section: The EP RVA (0x7D8504) falls at file offset 0x3FF104 inside section 02. The bytes there (e8 da 40 c7 ff) are a call opcode that appears to be part of the encrypted stream — the stub likely decrypts a small bootstrap region around EP before execution. This is a self-decrypting entry point pattern. ^[pefile.txt:55-56] ^[xxd @ 0x3FF104]

How To Mess With It (Homelab Replication)

Toolchain: Visual Studio 2022 (v143, 14.40+), x64 Release, /O2 or /Ox, /arch:AVX2 (inferred from de601a8a sibling).

Reproduction sketch:

  1. Build a minimal PE in C++ with four null-padded on-disk sections (set SizeOfRawData=0 in section headers).
  2. Embed a large encrypted payload as section 02 with r-x permissions.
  3. Set EP to an offset inside section 02 that will be decrypted at runtime.
  4. Implement a small bootstrap decryptor (XOR, RC4, or AES) that decrypts the EP region in-place before jumping to it.
  5. In the decrypted payload, resolve APIs via LoadLibraryA + GetProcAddress.
  6. Fetch secondary payload via WinHTTP (or embed it entirely).
  7. Allocate RWX memory and transfer execution.

Verification: Run capa <reproducer.exe> — should hit T1105 Ingress Tool Transfer and T1620 Reflective Code Loading if you implement in-memory execution.

Deployable Signatures

YARA

rule PE54e64e_LargeEncryptedPayload {
    meta:
        description = "54e64e MSVC 14.44 reflective loader with large encrypted payload (Morph 11)"
        author = "PacketPursuit"
        date = "2026-08-18"
        sha256 = "16520f80193c6e45d207ac0ffad8b29446194ad9734d7ee2ea8178f91eacf491"
    strings:
        $mz = { 4d 5a }
        $po = "POGO" ascii
        $linker = { 0e 2c }   // MajorLinkerVersion=0x0E, Minor=0x2C (MSVC 14.44)
    condition:
        uint16(0) == 0x5A4D and
        filesize > 5MB and filesize < 10MB and
        // Section 02 present with large encrypted payload
        for any i in (0..pe.number_of_sections - 1) :
            ( pe.sections[i].name == "02" and pe.sections[i].characteristics & 0x20000000 != 0 )
        and
        // Minimal IAT: only KERNEL32 imports
        pe.imports("KERNEL32.dll") and
        not pe.imports("USER32.dll") and
        not pe.imports("ADVAPI32.dll") and
        not pe.imports("WS2_32.dll") and
        not pe.imports("WININET.dll")
}

Sigma (process-creation behavioral hunt)

title: 54e64e Reflective Loader Process Creation with Extended Attributes
id: 54e64e-morph-11-proc-creation
status: experimental
description: Detects process creation with InitializeProcThreadAttributeList and CreatePipe following a small MSVC PE with minimal IAT
logsource:
  product: windows
  category: process_creation
detection:
  selection:
    - CommandLine|contains:
      - "InitializeProcThreadAttributeList"
      - "UpdateProcThreadAttribute"
      - "DeleteProcThreadAttributeList"
    ParentImage|endswith:
      - '.exe'
  condition: selection
falsepositives:
  - Legitimate software using extended process attributes
level: medium

IOC List

Indicator Type Value
SHA-256 hash 16520f80193c6e45d207ac0ffad8b29446194ad9734d7ee2ea8178f91eacf491
File size size 7,576,064 bytes
Compile time timestamp 2026-05-29 03:04:59 UTC
PE type format PE32+ x64 GUI
Linker toolchain MSVC 14.44 (VS 2022 v143)
Debug type artefact IMAGE_DEBUG_TYPE_POGO
Section names PE layout .text, .rdata, .data, .pdata, 00, 01, 02, .reloc
Encrypted payload section 02 — 7.3 MB, entropy ~7.81, r-x+not_paged
IAT surface imports 7 KERNEL32 functions only
Entry point RVA 0x7D8504 (inside encrypted section 02)
Null-pad sections anti-triage .text, .rdata, .data, .pdata all have SizeOfRawData=0

Behavioral fingerprint

This binary is a PE32+ x64 reflective loader built with MSVC 14.44. It presents a minimal IAT containing only seven KERNEL32 imports (GetSystemDirectoryW, HeapAlloc, HeapFree, ExitProcess, LoadLibraryA, GetModuleHandleA, GetProcAddress). The first four PE sections have zero on-disk size but non-zero virtual allocations, hiding code from file-offset scanners. A 7.3 MB encrypted payload occupies section 02 with r-x and MEM_NOT_PAGED flags. The entry point falls inside this encrypted region at RVA 0x7D8504, indicating self-decrypting execution. At runtime, the stub resolves additional APIs (likely WinHTTP for C2 staging) via GetProcAddress. No version info, no icon, no .rsrc section. Build timestamp 2026-05-29. No hardcoded C2 recovered statically.

Detection Signatures

Technique ATT&CK ID Evidence
Reflective Code Loading T1620 Entry point inside encrypted r-x section, runtime API resolution
Ingress Tool Transfer T1105 Inferred from WinHTTP runtime resolution pattern (sibling de601a8a confirms Google Drive staging)
Masquerading T1036.005 Null-padded sections hide true structure from on-disk scanners
Obfuscated Files or Information T1027 7.3 MB encrypted payload, no packer signature, strong entropy

References

  • SHA-256: 16520f80193c6e45d207ac0ffad8b29446194ad9734d7ee2ea8178f91eacf491
  • MalwareBazaar artifact: 931f07ec-f660-45b8-b6f2-c74a74163508
  • Sibling analysis: 54e64e Morph 10 (de601a8a) — MSVC 14.44 reflective loader with Google Drive staging ^[/intel/analyses/de601a8a3d45d818f6bd867f5bba33d576bc1d9d983511b66f2b22447dd5d8e4.html]
  • Family entity: 54e64e

Provenance

  • file.txt — file command output (PE32+ x64 GUI, 8 sections)
  • exiftool.json — ExifTool PE metadata (timestamp, linker version, subsystem)
  • pefile.txt — pefile full header dump (sections, imports, debug, TLS, relocations)
  • rabin2-info.txt — radare2 binary summary (arch, bits, canary, lang=c, signed=false)
  • strings.txt — strings output (9,272 lines, mostly noise; no C2 recovered)
  • binwalk.txt — binwalk scan (no embedded signatures)
  • capa.txt — capa failed (default signature path missing)
  • floss.txt — flare-floss failed (CLI argument error)
  • dynamic-analysis.md — CAPE skipped (no Windows guest)
  • Tools: radare2 5.x (rabin2, r2 CLI), pefile, ExifTool 12.76, binwalk, strings, xxd