Didier Stevens

Thursday 2 February 2012

x64 Windows Shellcode

Filed under: My Software,Shellcode — Didier Stevens @ 20:00

Last year I found great x64 shellcode for Windows on McDermott’s site. Not only is it dynamic (lookup API addresses), but it even handles forwarded functions.

But it’s written for MASM, and I prefer to use NASM. Hence I translated it, but also normalized it to adhere to the x64 calling convention and fixed a bug in the error handling.

And I modularized it so you can use it like my 32-bit shellcode.

Here’s the classic MessageBox example:

; x64 shellcode to display a "Hello from injected shell code!" MessageBox, then return to caller
; Written for NASM assembler (http://www.nasm.us) by Didier Stevens
; Source code put in public domain by Didier Stevens, no Copyright
; https://DidierStevens.com
; Use at your own risk
; History:
;   2011/12/27: Refactored functions to include file sc-x64-api-functions.asm

%include "sc-x64-macros.asm"

INDEX_MESSAGEBOXA                            equ 1 * POINTERSIZE + STACKSPACE
APIFUNCTIONCOUNT                            equ 2

segment .text

; Setup environment
sub rsp, STACKSPACE + ROUND_EVEN(APIFUNCTIONCOUNT) * POINTERSIZE        ;reserve stack space for called functions and for API addresses


lea rcx, [rel USER32DLL]


; Display MessageBox
xor r9, r9
lea r8, [rel TITLE]
lea rdx, [rel HELLO]
xor rcx, rcx


%include "sc-x64-api-functions.asm"

KERNEL32DLL                            db    "KERNEL32.DLL", 0
KERNEL32_LOADLIBRARYA        db    "LoadLibraryA", 0

USER32DLL                                db    "USER32.DLL", 0
USER32_MESSAGEBOXA            db    "MessageBoxA", 0

HELLO                                        db    "Hello from injected shell code!", 0
TITLE                                        db    "Message", 0

Here’s what I changed exactly from the original MASM code:
1) non-volatile registers are preserved (by storing them on the stack)
2) building the DLL name for forwarded functions is done with a variable on the stack frame of lookup_api, and not of the caller
3) the address of LoadLibraryA is passed via r9, and no longer r15
4) lookup_api not only returns the function address in rax, but also stores it in memory at an address provided in r8
5) fixed the error handling bug (stack restoration)
6) added some EQUs to make it easier to use this code as a “library” (include)

You can get the code from my shellcode page. Look for filenames starting with sc-x64 in the zip file.


  1. I see we have similar ideas – http://code.google.com/p/corkami/source/browse/trunk/asm/ports/mcdermott64.asm?r=959

    Comment by ange — Friday 3 February 2012 @ 20:44

  2. yep, same source

    Comment by Didier Stevens — Saturday 4 February 2012 @ 6:57

  3. Sorry, but where is the link to the zip file? I checked the shellcode page, but don’t see any *sc-x64*.zip files linked there.

    Comment by Mike Myers — Tuesday 7 February 2012 @ 23:40

  4. @Mike It’s in ZIP file my-shellcode_v0_0_6.zip

    Comment by Didier Stevens — Wednesday 8 February 2012 @ 19:23

  5. Dear all.. I need your help .. I have compiled the shellcode with NASM in a cygwin environment (gcc version 4.9.2) adding the shellcode HEXes in simple c routine like this: /*shellcodetest.c*/
    char code[] = “XXXXXXXXX”;
    int main(int argc, char **argv)
    int (*func)();
    func = (int (*)()) code;

    but when I run the exe I get Segmentation fault (core dumped)
    Exception: STATUS_ACCESS_VIOLATION at rip=00100402040

    Any help really appreciated

    Comment by Anonymous — Saturday 7 March 2015 @ 12:42

RSS feed for comments on this post. TrackBack URI

Leave a Reply (comments are moderated)

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.