Hallo,
ich beschäftige mich gerade mal wieder mit dem, was unter der Haube der modernen Rechentechnik steckt. Inspiriert, von dem etwas in die Jahre gekommen Artikel Erstellen eines Shellcode - HackerWiki, wollte ich Maschinencode ausführen.
So einfach wie wie im o.g. Artikel geht es leider nicht (mehr), dass man Maschinencode von einem Characterarray in ein Funktionspointer castet und abfeuert.
Ich habe schon herausgefunden, dass man einen seitenalignierten (page aligned klingt doch besser) Speicherbereich benötigt, in welchem man die Daten kopiert und ihn via mprotect ausführbar macht. Dieses minimale Szenario segfaultet bei mir und leider habe ich in diesem Bereich noch nicht so viel Ahnung, dass ich mir selbst zu helfen weiß. Deshalb kommt jetzt hier mein Setup und ich hoffe auf interessante Tipps.
Für die Vollständigkeit die Bedeutung meines Maschinencodes:
Übersetzt mit nasm -f bin -o hello.bin hello.asm.
Mein C-Code:
Übersetzt mit gcc -o loader loader.c.
Ausgabe des Programmes (und meiner Shell):
Also meiner Meinung nach sollte es funktionieren, vielleicht habe ich auch einen trivialen Fehler gemacht und seh ihn nur nicht. Aber viele Augen sehen ja bekanntlich mehr als zwei.
Gruß, Thul
ich beschäftige mich gerade mal wieder mit dem, was unter der Haube der modernen Rechentechnik steckt. Inspiriert, von dem etwas in die Jahre gekommen Artikel Erstellen eines Shellcode - HackerWiki, wollte ich Maschinencode ausführen.
So einfach wie wie im o.g. Artikel geht es leider nicht (mehr), dass man Maschinencode von einem Characterarray in ein Funktionspointer castet und abfeuert.
Ich habe schon herausgefunden, dass man einen seitenalignierten (page aligned klingt doch besser) Speicherbereich benötigt, in welchem man die Daten kopiert und ihn via mprotect ausführbar macht. Dieses minimale Szenario segfaultet bei mir und leider habe ich in diesem Bereich noch nicht so viel Ahnung, dass ich mir selbst zu helfen weiß. Deshalb kommt jetzt hier mein Setup und ich hoffe auf interessante Tipps.

% nasm -v
NASM version 2.09.10 compiled on Jul 19 2011
% gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/src/gcc-4.6-20111125/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --enable-gnu-unique-object --enable-linker-build-id --with-ppl --enable-cloog-backend=isl --enable-lto --enable-gold --enable-ld=default --enable-plugin --with-plugin-ld=ld.gold --enable-multilib --disable-libssp --disable-libstdcxx-pch --enable-checking=release --with-fpmath=sse
Thread model: posix
gcc version 4.6.2 20111125 (prerelease) (GCC)
% uname -vr
3.1.5-1-ARCH #1 SMP PREEMPT Sat Dec 10 14:43:09 CET 2011
NASM version 2.09.10 compiled on Jul 19 2011
% gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.2/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: /build/src/gcc-4.6-20111125/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://bugs.archlinux.org/ --enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --enable-gnu-unique-object --enable-linker-build-id --with-ppl --enable-cloog-backend=isl --enable-lto --enable-gold --enable-ld=default --enable-plugin --with-plugin-ld=ld.gold --enable-multilib --disable-libssp --disable-libstdcxx-pch --enable-checking=release --with-fpmath=sse
Thread model: posix
gcc version 4.6.2 20111125 (prerelease) (GCC)
% uname -vr
3.1.5-1-ARCH #1 SMP PREEMPT Sat Dec 10 14:43:09 CET 2011
Für die Vollständigkeit die Bedeutung meines Maschinencodes:
Code:
; hello.asm
mov ecx,msg
mov edx,msglen
mov ebx,1 ; STDOUT
mov eax,4 ; Funktionsnummer: Ausgabe
int 80h
mov ebx,0 ; EXITCODE
mov eax,1 ; Funknr: Exit
int 80h
msg: db "Hello ya encrypted world!"
msglen: equ $ - msg
Mein C-Code:
Code:
// loader.c
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
int main(){
// der als hex codierte Inhalt der eben erstellten .bin Datei
const char *hello = "\x66\xb9\x28\x00\x00\x00\x66\xba\x19\x00\x00\x00\x66\xbb\x01\x00"
"\x00\x00\x66\xb8\x04\x00\x00\x00\xcd\x80\x66\xbb\x00\x00\x00\x00"
"\x66\xb8\x01\x00\x00\x00\xcd\x80\x48\x65\x6c\x6c\x6f\x20\x79\x61"
"\x20\x65\x6e\x63\x72\x79\x70\x74\x65\x64\x20\x77\x6f\x72\x6c\x64"
"\x21";
const int len = 65;
size_t size = sizeof(char) * len;
printf("pos-hello: %08x\n", (long) hello);
void* mem = memalign(sysconf(_SC_PAGESIZE), size);
if(mem == NULL) {
perror(0);
return 1;
}
printf("pos-mem: %08x\n", (long) mem);
memcpy(mem, hello, size);
if(mprotect(mem, size, PROT_READ|PROT_WRITE|PROT_EXEC) == -1){
perror(0);
return 1;
}
int (*F)() = mem;
printf("pos-F: %08x\n", (long) F);
F();
}
Ausgabe des Programmes (und meiner Shell):
% ./loader
pos-hello: 00400880
pos-mem: 00fb7000
pos-F: 00fb7000
[1] 27673 segmentation fault ./loader
pos-hello: 00400880
pos-mem: 00fb7000
pos-F: 00fb7000
[1] 27673 segmentation fault ./loader
Also meiner Meinung nach sollte es funktionieren, vielleicht habe ich auch einen trivialen Fehler gemacht und seh ihn nur nicht. Aber viele Augen sehen ja bekanntlich mehr als zwei.
Gruß, Thul
Zuletzt bearbeitet: