| Code Kitchen Allgemeines Coder-Forum rund um das Programmieren eigenständiger, ausführbarer Programme. |
Diskussion: [solved] C: Maschinen-Code ausführen / Speicherzugriffskontrolle im Forum Code Kitchen, in der Kategorie Software Home; Anzeige Hallo, ich beschäftige mich gerade mal wieder mit dem, was unter der Haube der modernen Rechentechnik steckt. Inspiriert, von ...
![]() |
| | #1 (permalink) |
| Registriert seit: 29.06.10 ![]() Likes: 0 | [solved] C: Maschinen-Code ausführen / Speicherzugriffskontrolle Anzeige 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. ![]() Software 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): Ausgabe 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 Geändert von Thulsadum (03.01.12 um 23:24 Uhr) Grund: solved |
| | |
| | #2 (permalink) |
| Registriert seit: 24.12.08 ![]() Likes: 2 | Hi, Nach einem kurzen Blick darauf fallen mir zwei Sachen auf: 1.) Die vielen 0x66 Prefixes in deinem Shellcode deuten darauf hin, dass du BITS 32 in der hello.asm vergessen hast der Assembler 16-Bit Code generiert. 2.) Shellcode sollte immer positionsunabhängig sein. Dein mov ecx,msg führt dazu, dass ecx dann bei der Ausführung im C-Programm nicht mehr auf die richtige Adresse zeigt. Du kannst das für den Anfang z.b. so lösen Code: call over_txt msg db "Hello SC-World!",0 over_txt: pop ecx Ich hoffe, du kommst dem Ziel damit ein Stück näher. Mfg |
| | |
| HaBOT | - Anzeige - |
| |
| | #3 (permalink) |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 202 | \x66\xb9\x28\x00\x00\x00 66:16/32 Bit Prefix b9 28: mov ecx, 0x28 <-- String befindet sich also an Adresse 0x28 ? int 80h <-- 32-bit Interface. Bei 64-bit sollte SYSCALL verwendet werden Sprich: der Code sollte bei einem 64-bit System auch selbst 64-bittig sein linuxsyscalls bzw. in "kurz": Low-Level Assembler unter Linux Code: Syscallnummern SYSCALL ; FILE syscall_64_syscall.inc %define _syscall syscall %define _nr rax %define _arg1 rdi %define _arg2 rsi %define _arg3 rdx %define _arg4 rcx %define _arg5 r8 %define _arg6 r9 %define _sys_read 0 %define _sys_write 1 ... %define _sys_exit 60 Code: jmp my_code
msg: db "Hello ya encrypted world!"
msglen equ $ - msg
my_code:
mov rax,1
mov rdi,1 ;stdout
lea rsi,[rel msg]
mov rdx, msglen
syscall
mov rdi,0
mov rax,60h ; Funknr: Exit
syscall
ret
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. |
| | |
| | #4 (permalink) |
| Themenstarter Registriert seit: 29.06.10 ![]() Likes: 0 | Danke Ihr beiden, ss5s bemerkte Auffälligkeiten haben abhilfe geschaffen. Tatsächlich bräuchte ich die 64 Bit variante, aber die 32 Bit variante tut auch und irgendwie war es doch ein offensichtlicher Fehler den Code nicht frei von Positionierung zu halten. Jedenfalls funktioniert es jetzt und ich freue mich. Werd mir dann mal die 64 Bit variante zu Gemüte führen.Thul |
| | |
| | #5 (permalink) |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 202 | 64-bit erlaubt eben die RIP-Adressierung, wodurch der "delta-call" zur Positionsermittlung überflüssig wird: Codegurus.be - About RIP relative addressing (Win64 / x64 / x86-64 / AMD64 / EM64T / AA-64) Code: lea rsi,[rel msg]
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. |
| | |
| | #6 (permalink) |
| Themenstarter Registriert seit: 29.06.10 ![]() Likes: 0 | Also dein Code funktioniert einwandfrei, wobei das return tatsächlich wichtig ist, da es sonst zu nem segfault kommt, sollte der syscall an exit nicht schon das Programm beenden? |
| | |
| | #7 (permalink) |
| Moderator ![]() Registriert seit: 20.07.05 ![]() ![]() ![]() ![]() ![]() ![]() Likes: 202 | der erste Link sollte eigentlich zu sowas führen: 64-bit Linux system call list und sys_exit = 60d = 0x3c (in meinem Code steht 60h, was falsch ist)
__________________ Noch mal, für alle Pseudo-Geeks: 1+1=0. -> 10 wäre Überlauf! Selig, wer nichts zu sagen hat und trotzdem schweigt. |
| | |
![]() |
| - Anzeige - | |
| |
| Themen-Optionen | |
| Ansicht | |
| |
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| [JAVA] Wie in Abhängigkeit vom Datentyp in einem Object-Array code Ausführen? | BlackPanter | Code Kitchen | 3 | 26.05.10 17:18 |
| EXE Code während der Laufzeit ausführen | _SharK_ | Code Kitchen | 5 | 18.12.06 20:50 |
| Code direkt ausführen | Nick H. | Code Kitchen | 11 | 03.12.05 17:56 |
| Linux 2.6.13 mit Suspend auf SMP-Maschinen | non | News & Ankündigungen | 0 | 30.08.05 12:53 |
| PHP Code aus Datenbank ausführen | the-hermi | (Web-) Design und webbasierte Sprachen | 2 | 20.06.04 22:23 |