Below, I written x64 assembly that prints 'Hello, World!' from a syscall on Mac OS X 10.8. It assembles and runs perfect when executed standalone.
; Assemble and link with:
; nasm -f macho64 -o HelloWorld.o HelloWorld.s
; ld -arch x86_64 -o HelloWorld HelloWorld.o
global start
section .text
start:
push rbp
mov rbp, rsp
jmp short String
xor rdi, rdi
mov di, 0x01
StringRet:
pop rsi
xor rdx, rdx
mov dl, 0xE
mov r8b, 0x02
shl r8, 24
or r8, 0x04
mov rax, r8
syscall ; System call for write(4)
xor edi, edi
mov r8b, 0x02
shl r8, 24
or r8, 0x01
mov rax, r8
syscall ; System call for exit(1)
mov rsp, rbp
pop rbp
String:
call StringRet
db 'Hello, World!'
The problem I'm having is when I try to run this code as shell code from a c program. I used otool to get the following machine opcodes.
otool -t HelloWorld.o
char code[] = "x55x48x89xe5x41xb0x02x49xc1xe0x18x49x83xc8x04x4c"
"x89xc0x48x31xffx66xbfx01x00xebx1ex5ex48x31xd2xb2"
"x0ex0fx05x41xb0x02x49xc1xe0x18x49x83xc8x01x4cx89"
"xc0x31xffx0fx05x48x89xecx5dxe8xddxffxffxffx48x65"
"x6cx6cx6fx2cx20x57x6fx72x6cx64x21";
And below is the c program I'm using to execute this. But I keep getting a Bus error: 10.
; Compile:
; gcc -o HelloWorldTest HelloWorldTest.c
char code[] = "x55x48x89xe5x41xb0x02x49xc1xe0x18x49x83xc8x04x4c"
"x89xc0x48x31xffx66xbfx01x00xebx1ex5ex48x31xd2xb2"
"x0ex0fx05x41xb0x02x49xc1xe0x18x49x83xc8x01x4cx89"
"xc0x31xffx0fx05x48x89xecx5dxe8xddxffxffxffx48x65"
"x6cx6cx6fx2cx20x57x6fx72x6cx64x21";
int main()
{
int (*ret)();
ret = (int(*)())code;
(int)(*ret)();
return 0;
}
When I step through with gdb I get KERN_PROTECTION_FAILURE right when execution is passed to the shellcode.
Updated Question:
The above was solved by Carl Norum, it was due to memory protection. I have a different problem but is similar to above. Instead of having the shell code in the same file, I want to read the shell code from a .txt file and execute it. Below I tried marking a section of memory as PROT_EXEC and read the contents of the .txt file into it and execute. But it won't work, I'm getting the same error, KERN_PROTECTION_FAILURE, I tried using mprotect and mmap to mark a section of memory as PROT_EXEC.
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
int (*ret)();
unsigned char* buf;
int main()
{
FILE* file;
file = fopen("text.txt", "rb");
unsigned int len = ftell(file);
buf = (char*)malloc(len);
fread(buf, 1, len, file);
fclose(file);
mprotect(&buf, len, PROT_EXEC);
// I also tried mmap, but same error.
/*void *ptr = mmap(0, 1024, PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
if (ptr == MAP_FAILED)
{
perror("mmap");
exit(-1);
}
memcpy(ptr, buf, 1024);*/
ret = buf;
ret();
return 0;
}
This is the text.txt file I'm reading in, its the same hello world code:
x55x48x89xe5xebx33x48x31xffx66xbfx01x00x5ex48x31xd2xb2x0ex41xb0x02x49xc1xe0x18x49x83xc8x04x4cx89xc0x0fx05x31xffx41xb0x02x49xc1xe0x18x49x83xc8x01x4cx89xc0x0fx05x48x89xecx5dxe8xc8xffxffxffx48x65x6cx6cx6fx2cx20x57x6fx72x6cx64x21x0a
Since I'm copying the contents of the txt file into PROC_EXEC memory, I don't understand why I'm getting KERN_PROTECTION_FAILURE.
See Question&Answers more detail:
os