typetechniqueconfidencehighcreated2026-07-05updated2026-07-05injectionshellcodeprocess-injectiont1055evasion

CallWindowProc Shellcode Injection

A process-injection technique that abuses the CallWindowProcW API from user32.dll. Because CallWindowProc accepts a callback address (lpPrevWndFunc) and up to four arguments, it can be repurposed to transfer execution to arbitrary shellcode with controlled arguments.

Pattern Definition

  1. Allocate buffer: A DllStructCreate("byte[N]") is created with RWX-compatible memory.
  2. Write shellcode: The shellcode bytes are copied into the struct.
  3. Get pointer: DllStructGetPtr returns the raw memory address.
  4. CallWindowProc: The address is passed as lpPrevWndFunc; the API jumps directly to shellcode.
Global $PARATIM = DllStructCreate("byte[" & BinaryLen($PBDWLMZ) & "]")
DllStructSetData($PARATIM, 1, $PBDWLMZ)
Global $NUVEFSJM = DllStructGetPtr($PARATIM)
DllCall("user32.dll", "ptr", "CallWindowProc", "ptr", $NUVEFSJM + 9136, ...)

The + 9136 offset skips the shellcode prologue and lands execution at the real entry point. ^[script.au3:1291-1295]

Detection / Fingerprint

  • CallWindowProcW called from processes that do not own windows (e.g., console or hidden AutoIt processes).
  • The first argument (lpPrevWndFunc) points to memory outside any loaded module — a strong signal of injection.
  • Memory allocated by DllStructCreate with PAGE_EXECUTE_READWRITE protections.

ATT&CK Mapping

  • T1055 — Process Injection
  • T1055.001 — Dynamic-link Library Injection (conceptually similar — arbitrary code execution in process context)

Defensive Countermeasures

  • ETW/Sysmon: monitor CallWindowProc with a first argument that does not resolve to a known module.
  • Memory integrity: flag RWX allocations in processes with no legitimate JIT requirement.

Pages Where Observed