Testen des Shellcodes vom C-Bus-Fehler 10

Unten habe ich eine x64-Assembly geschrieben, in der "Hello, World!" von einem Syscall unter Mac OS X 10.8. Es wird zusammengebaut und läuft einwandfrei, wenn es eigenständig ausgeführt wird.

; 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!'

Das Problem, das ich habe, ist, wenn ich versuche, diesen Code als Shell-Code aus einem C-Programm auszuführen. Ich habe otool verwendet, um die folgenden Maschinen-Opcodes zu erhalten.

otool -t HelloWorld.o

char code[] = "\x55\x48\x89\xe5\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x04\x4c"
              "\x89\xc0\x48\x31\xff\x66\xbf\x01\x00\xeb\x1e\x5e\x48\x31\xd2\xb2"
              "\x0e\x0f\x05\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x01\x4c\x89"
              "\xc0\x31\xff\x0f\x05\x48\x89\xec\x5d\xe8\xdd\xff\xff\xff\x48\x65"
              "\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21";

Und unten ist das C-Programm, das ich benutze, um dies auszuführen. Aber ich bekomme immer wieder einen Busfehler: 10.

; Compile:
; gcc -o HelloWorldTest HelloWorldTest.c

char code[] = "\x55\x48\x89\xe5\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x04\x4c"
              "\x89\xc0\x48\x31\xff\x66\xbf\x01\x00\xeb\x1e\x5e\x48\x31\xd2\xb2"
              "\x0e\x0f\x05\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x01\x4c\x89"
              "\xc0\x31\xff\x0f\x05\x48\x89\xec\x5d\xe8\xdd\xff\xff\xff\x48\x65"
              "\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21";

int main()
{
    int (*ret)();

    ret = (int(*)())code;

    (int)(*ret)();

    return 0;
}

Wenn ich mit gdb durchsteige, erhalte ich KERN_PROTECTION_FAILURE direkt, wenn die Ausführung an den Shellcode übergeben wird.

Aktualisierte Frage:

Das obige wurde von Carl Norum gelöst, es lag am Speicherschutz. Ich habe ein anderes Problem, aber es ist ähnlich wie oben. Anstatt den Shell-Code in derselben Datei zu haben, möchte ich den Shell-Code aus einer TXT-Datei lesen und ausführen. Unten habe ich versucht, einen Speicherabschnitt als PROT_EXEC zu markieren und den Inhalt der TXT-Datei einzulesen und auszuführen. Aber es wird nicht funktionieren, ich erhalte den gleichen Fehler, KERN_PROTECTION_FAILURE. Ich habe versucht, mit mprotect und mmap einen Abschnitt des Speichers als PROT_EXEC zu markieren.

#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;
}

Dies ist die text.txt-Datei, in der ich lese. Es ist derselbe Hallo-Welt-Code:

\x55\x48\x89\xe5\xeb\x33\x48\x31\xff\x66\xbf\x01\x00\x5e\x48\x31\xd2\xb2\x0e\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x04\x4c\x89\xc0\x0f\x05\x31\xff\x41\xb0\x02\x49\xc1\xe0\x18\x49\x83\xc8\x01\x4c\x89\xc0\x0f\x05\x48\x89\xec\x5d\xe8\xc8\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x20\x57\x6f\x72\x6c\x64\x21\x0a

Da ich den Inhalt der txt-Datei in den PROC_EXEC-Speicher kopiere, verstehe ich nicht, warum ich KERN_PROTECTION_FAILURE erhalte.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage