I’m getting some strange behavior with shellcode that used to work on OS X 10.6. I noticed that if I don’t link with the “-static” option, I get a segfault.

; File: shell.s
; Author: Dustin Schultz - TheXploit.com
BITS 64

section .text
global start

start:
xor rdx, rdx
mov eax, 0x200003b
mov rdi, 0x68732f2f6e69622f
push rsi
push rdi
mov rdi, rsp
syscall

With static:

dustin@sholtz:~$ nasm -f macho64 shell.s 
dustin@sholtz:~$ ld -static -arch x86_64 shell.o
dustin@sholtz:~$ ./a.out 
dustin@sholtz:/Users/dustin$ exit

Without static

dustin@sholtz:~$ nasm -f macho64 shell.s 
dustin@sholtz:~$ ld -arch x86_64 shell.o
dustin@sholtz:~$ ./a.out 
Segmentation fault: 11
dustin@sholtz:~$ 

otool has the same output:

dustin@sholtz:~$ otool -tv static 
static:
(__TEXT,__text) section
start:
0000000100000fe7	xorq	%rdx,%rdx
0000000100000fea	movl	$0x0200003b,%eax
0000000100000fef	movq	$0x68732f2f6e69622f,%rdi
0000000100000ff9	pushq	%rsi
0000000100000ffa	pushq	%rdi
0000000100000ffb	movq	%rsp,%rdi
0000000100000ffe	syscall
dustin@sholtz:~$ otool -tv non-static 
non-static:
(__TEXT,__text) section
start:
0000000100000f9f	xorq	%rdx,%rdx
0000000100000fa2	movl	$0x0200003b,%eax
0000000100000fa7	movq	$0x68732f2f6e69622f,%rdi
0000000100000fb1	pushq	%rsi
0000000100000fb2	pushq	%rdi
0000000100000fb3	movq	%rsp,%rdi
0000000100000fb6	syscall

The headers on the files look way different but I’m not sure exactly what is causing the issue. For instance, the non-static version has several more Load commands like LC_LOAD_DYLINKER (which is expected).

Update
As pointed out in the comments, I was not initializing rsi correctly! Thanks for pointing that out. The fix was to add this before the last syscall:

push rdx
push rdi
mov rsi, rsp