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:
- Load a 16-byte chunk from
.dataor.rsrcintoxmm0viamovdqa. - Add a hardcoded constant word-wise using
paddw. - Mask the result with
pandusing a second constant. - 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
.textsections containingpaddwfollowed bypandwithin 10 bytes, repeated in a tight loop. - The loop often iterates over a
.dataor.rsrcsection whose raw size exceeds 1 MB with entropy in the 6.0–7.0 range. - Constants seen in the wild:
paddwaddend:0x00cd(205) or0x00bf(191)pandmask:0x00ffpatterns or0xffffsaturation 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
- Create a Visual Studio C++ x64 project.
- Add a large
uint16_tbuffer in.datainitialized with pseudo-random values. - Implement the decryption loop using
_mm_add_epi16and_mm_and_si128. - Compile with
/O2 /arch:SSE2. - Observe the resulting
.textdisassembly — it should contain66 0f fd(paddw) and66 0f db(pand) opcodes.
Defensive Countermeasures
- Emulation-aware unpacking: Emulate SSE2 instructions in the unpacker; the payload is only plaintext after the full
paddw/pandpass completes. - Entropy heuristics: Flag PEs whose
.dataentropy is between 6.0 and 7.0 and whose.textis 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]