Files
maxDcb-DreamWalkers/docs/shellcode-bootstrap.md
2026-05-04 13:22:48 +02:00

2.1 KiB

Shellcode Bootstrap

DreamWalkers.py emits a small architecture-specific bootstrap before the extracted memoryModuleLoader bytes. Its only job is to pass the serialized INSTANCE pointer as the first argument, then transfer execution to Loader.

x64

The x64 bootstrap uses a call/pop pattern to discover the inline INSTANCE address without an absolute pointer. call after_instance pushes the address of the embedded instance blob, pop rcx moves it into the first Windows x64 argument register, and the wrapper aligns rsp plus reserves 32 bytes of shadow space before calling the loader.

call after_instance        ; pushes &INSTANCE
db   INSTANCE bytes
after_instance:
pop  rcx                   ; rcx = INSTANCE*
push rbp
mov  rbp, rsp
and  rsp, -16
sub  rsp, 20h              ; Windows x64 shadow space
call Loader
mov  rsp, rbp
pop  rbp
ret

x86

The x86 bootstrap also uses call/pop to get the inline INSTANCE address. The loader expects a normal stack argument at [esp+4], so the bootstrap preserves the caller return address, pushes INSTANCE*, then calls the loader. The call return address points to a cleanup stub that removes the synthetic argument and returns with ret 4, preserving the thread-start return layout used by the tester path.

call after_instance        ; pushes &INSTANCE
db   INSTANCE bytes
after_instance:
pop  ecx                   ; ecx = INSTANCE*
pop  edx                   ; save caller return address
push edx                   ; restore caller return address
push ecx                   ; stack arg: INSTANCE*
call Loader                ; return address is cleanup
cleanup:
add  esp, 4                ; drop INSTANCE*
ret  4

ARM64

The ARM64 bootstrap uses fixed-width instructions. adr x0, instance computes the inline INSTANCE address into the first Windows ARM64 argument register, then b Loader branches directly to the extracted loader bytes. The branch is not a link branch, so the loader returns through the link register already provided by the shellcode caller.

adr x0, instance           ; x0 = INSTANCE*
b   Loader
instance:
db  INSTANCE bytes
Loader: