Indirect Waffles: Shellcode Loader to Evade EDRs
A shellcode loader with advanced techniques such as HellHall's indirect syscalls, Early Bird APC injection, and more, to evade EDR detection.

While preparing for CRTO 2 and learning from Maldev Academy, I wanted to put everything I had learned into practice. That’s when I created Indirect Waffles, a custom shellcode loader designed for EDR evasion and enhanced by many of the advanced techniques I’ve been studying.
Demo
Key Features
- Enumeration: Uses
NtQuerySystemInformation
to enumerate processes for PPID spoofing andNtOpenProcess
syscall to obtain process handles. - Custom Dynamic HTTP/s Payload Staging
- Check it out on my GitHub.
- Shellcode Decryption: RC4 with runtime key brute-forcing.
- Process Creation with
NtCreateUserProcess
and the following enhancements:- Suspended process creation for APC Injection.
- Parent Process ID (PPID) spoofing.
- Block DLL injection policy, preventing third-party DLLs (non-Microsoft signed) from being injected, mitigating some EDR hooking techniques.
- Injection: Remote Mapped Injection via syscalls with RX (Read Execute) permissions for improved evasion from memory scanners.
- Execution: Early Bird APC Injection using syscalls to queue the payload for execution before the target thread resumes execution.
- Resumes process via
NtResumeThread
syscall. - Extra Enhancements:
- Custom string literal obfuscation: Works on both normal and wide strings.
-
- Compile-time IAT API hashing using
MurmurHash
to evade static API detection techniques. - HellHalls’ Indirect Syscall implementation with compile-time hashing via
MurmurHash
. -
- Custom string literal obfuscation: Works on both normal and wide strings.
- Anti-Debugging:
- Checks the PEB flag for the
IsDebugged
flag to detect the presence of a debugger. - Anti-debug loop (30 seconds total):
- 3-second sleep intervals using
NtWaitForSingleObject
. - API hammering to make the sleep appear more benign.
- 3-second sleep intervals using
- Uses
QueryPerformanceCounter
to measure total loop time; if it exceeds 35 seconds, it is likely being debugged.
- Checks the PEB flag for the
- Spoofed Binary Metadata:
.DLL
: Spoofed as Notepad++’slibcurls.dll
..EXE
: Spoofed as Notepad++’sgup.exe
.
Learn how to spoof a binary’s metadata here