typetechniqueconfidencehighcreated2026-06-13updated2026-06-13obfuscationevasioncompilerpe

XMM Word-Wise Payload Decryption

What It Does

A payload-decryption technique that uses SSE2 XMM registers to operate on 128-bit blocks of encrypted data in-place. The typical sequence is:

  1. Load a 16-byte chunk from .data or .rsrc into xmm0 via movdqa.
  2. Add a hardcoded constant word-wise using paddw.
  3. Mask the result with pand using a second constant.
  4. Store the decrypted chunk back to the same buffer.

This produces a deceptively high entropy section (6.0–6.8) that is not random enough for true AES but too structured for simple XOR. The use of SIMD instructions confuses static disassemblers that do not reconstruct the effective data flow across paddw/pand pairs.

Detection / Fingerprint

  • Look for .text sections containing paddw followed by pand within 10 bytes, repeated in a tight loop.
  • The loop often iterates over a .data or .rsrc section whose raw size exceeds 1 MB with entropy in the 6.0–7.0 range.
  • Constants seen in the wild:
    • paddw addend: 0x00cd (205) or 0x00bf (191)
    • pand mask: 0x00ff patterns or 0xffff saturation masks
  • A secondary indicator is the presence of MinGW-w64 pseudo-relocation strings ("Unknown pseudo relocation protocol version") inside an MSVC PE, because the decrypted payload often needs RVA fixups before execution.

Implementation Patterns Observed

; Typical loop body (x64)
movdqa xmm0, [rip+0x2b9f0d]      ; load ciphertext
paddw  xmm0, [rip+0x8e25]        ; word-wise add constant
pand   xmm0, [rip+0x8e2d]        ; mask to valid range
movdqa [rip+0x2b9ef5], xmm0      ; store plaintext

The loop is usually preceded by a byte flag check (cmpb $0x0, ... ; je skip) that allows the malware to decrypt only once or to gate decryption across multiple execution phases.

Reproduce on Your Own VMs

  1. Create a Visual Studio C++ x64 project.
  2. Add a large uint16_t buffer in .data initialized with pseudo-random values.
  3. Implement the decryption loop using _mm_add_epi16 and _mm_and_si128.
  4. Compile with /O2 /arch:SSE2.
  5. Observe the resulting .text disassembly — it should contain 66 0f fd (paddw) and 66 0f db (pand) opcodes.

Defensive Countermeasures

  • Emulation-aware unpacking: Emulate SSE2 instructions in the unpacker; the payload is only plaintext after the full paddw/pand pass completes.
  • Entropy heuristics: Flag PEs whose .data entropy is between 6.0 and 7.0 and whose .text is unusually small relative to .data.
  • Behavioral sandbox: The decryption loop may be gated by a flag; forcing the flag to true during emulation can reveal the decrypted payload without needing full SSE2 emulation.

Pages Where Observed

  • 54e64e — Sample 6e0ef3af, MSVC x64 morph with 2.8 MB encrypted .data ^[/intel/analyses/6e0ef3af90cd3e4a8d48b6e5fee62e5d88f69d007135314f9014e63cfb179e93.html]