[C] Inline Assembler

Hallo liebe HaBo Community,

in meinem Programm habe ich mit malloc Speicher reserviert und in diesen OP Codes geschrieben. Die Startadresse des Codes ist in der int Adresse gespeichert.
Schaue ich mit TSearch an der Speicherstelle nach finde ich dort meine OP Codes wie erwartet. Am Ende meines Programmes versuche ich mit dem Inline Assembler einen JMP zu _Adresse, also zu den OP Codes zu machen. Compiliert wird alles korrekt undlaufen tut es auch - bis zu dem JMP. Dann stürzt das Programm ab (Fehlerberichterstattung) - beim Debugging zeigt sich dann "Segementation Faul" obwohl ich den Speicher reserviert habe. Ich benutze DevC++ mit GCC. Vielen Dank für eure Hilfe.

Speicherreservierung:
Code:
 buffer = (char*) malloc (length+1);    
 if (buffer==NULL) exit (1);

Jump:
Code:
AdressPointer = (int**)&buffer; //Offset von *buffer   
Adresse = (int)*AdressPointer;  // Hole aus Offset von *buffer Offset
asm volatile("jmp _Adresse");

MfG, Frohest Fest!
 
Im Moment springst Du scheinbar zum Label _Adresse (also zur Adresse, an der "_Adresse" steht).
Sowas sollte funktionieren: "jmp dword ptr[_Adresse]" oder "jmp [_Adresse]" oder "jmp dword [_Adresse" - was GCC genau für eine Syntax haben will, weiß ich nicht mehr.
 
Mhm, genau das hatte ich befürchtet darum habe ich sowas vorhin auch ausprobiert.

Compilieren kann ich es nun fehlerfrei, allerdings ist der Segmentation Fault immernoch nicht weg :(


Hier einmal der ganze Code:
Code:
#include <stdio.h> 
#include <stdlib.h> 

char *buffer;
 int **AdressPointer;
 int Adresse; 

int main(void){ 	
int i=0;

char code[] = "\0x90\0xb8\0x04\0x00\0x00\0x00\0xba\0x0e\0x00\0x00\0x00\0xb9\0xb8\0x90\0x04\0x08\0xbb\0x01\0x00\0x00\0x00\0xcd\0x80\0xb8\0x01\0x00\0x00\0x00\0xbb\0x00\0x00\0x00\0x00\0xcd\0x80";  	

long length =  sizeof(code)/sizeof(char); 	     
buffer = (char*) malloc (length+1);     
if (buffer==NULL) exit (1); 	 	 	

for(i=0; i < length; i++){ 		
buffer[i] = code[i];    
 }         

// AdressPointer = (int**)&buffer; //Offset von *buffer    
// Adresse = (int)*AdressPointer;  // Hole aus Offset von *buffer Offset von Codebeginn 
 _asm { jmp dword ptr [buffer] }; //JMP zu Codebeginn 
}
MfG, frohest Fest
 
ich hab das mal "minimalistisch" gemacht (gcc version 3.3.2):
das funktioniert:
Code:
#include <stdio.h> 
#include <stdlib.h> 

char *buffer;
 int **AdressPointer;
 static int Adresse; 

int main(void){ 	
int i=0;

char code[] = "\x90\x90\x90\x90\xc3";  	
     
buffer = (char*) malloc (5+1);     
if (buffer==NULL) exit (1); 	 	 	

for(i=0; i < 5; i++){ 		
buffer[i] = code[i];    
 }         

// Adresse = (int)*AdressPointer;  // Hole aus Offset von *buffer Offset von Codebeginn 
asm(".intel_syntax noprefix\n");
 asm ("call [_buffer]"); //JMP zu Codebeginn 
}
(wie man sieht, habe ich die assemblysyntax auf Intel gestellt) ;)
Allerdings:
egentuell lag Dein Fehler auch nur hier:
Code:
char code[] = "\0x90\0xb8\...
also nicht \0x sondern \x schreiben.
 
oh ja, tatsächlich^^ Genial!

aber die sache nimmt kein end, dein code geht einwandfrei, sobald ich aber
Code:
char code[] = "\x90\xb8\x04\x00\x00\x00\xba\x0e\x00\x00\x00\xb9\xb8\x90\x04\x08\xbb\x01\x00\x00\x00\xcd\x80\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80\xc3";
einfüge kommt wieder:

Unbehandelte Ausnahme bei 0x0033331e in test.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xffffffff.

obwohl ich doch wieder mit C3 zurückspringe oder muss ich vorher erst irgend ein Register popen *lol*, sry bin nich so das genie in Assembler^^?

MfG
 
1.rufst du auch fleißig den code über CALL auf ?
2.
Unbehandelte Ausnahme bei 0x0033331e in -->test.exe<--
ich sehe am Ende des shellcodes CD 80 - das wäre ein INT 80 -> und das wäre wiederum irgendwas Linuxmäßiges -> Linuxshellcode ist nicht Windowskompatibel ;)
 
ja, per call^^ Also ich habe jetzt in VC++ ein Hello World Programm gezaubert, Disassembler aufgerufen und die OP Codes von der ersten zeile bis zur schluss } kopiert, formatiert und bei char code[] eingefügt. jetzt kommt auch nichtmehr an Position 0xffffffff sondern:
Unbehandelte Ausnahme bei 0x00332fc7 in test.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x58474e49.
:-P

Code:
char code[] = "\x55\x8B\xEC\x81\xEC\xC0\x00\x00\x00\x53\x56\x57\x8D\xBD\x40\xFF\xFF\xFF\xB9\x30\x00\x00\x00\xB8\xCC\xCC\xCC\xCC\xF3\xAB\x68\x00\x68\x41\x00\xA1\x38\x93\x41\x00\x50\xE8\x81\xFC\xFF\xFF\x83\xC4\x08\x8B\xF4\x8B\x0D\x3C\x93\x41\x00\xFF\x15\x20\x93\x41\x00\x3B\xF4\xE8\xB4\xFC\xFF\xFF\x33\xC0\x5F\x5E\x5B\x81\xC4\xC0\x00\x00\x00\x3B\xEC\xE8\xA2\xFC\xFF\xFF\x8B\xE5\x5D\xC3";

:(

MfG
 
Du erwartest doch nicht etwa, dass VC++ adressunabhängigen Code generiert? Mit Opcodes kopieren ist es nicht getan - auch eine einfache HelloWorld Anwendung hat zig Abhängigkeiten (calls zu externen Bibliotheken) . Externe Funktionen (printf,getc, exit usw) werden in einer Executable i.R nicht direkt, sondern über Import Adress Tabelle aufgerufen - heißt: der Compiler biegt beim kompilieren erstmal alle externen Aufrufe auf eine Tabelle um und macht die Aufrufe "indirekt" (also in etwa: call [1235_tabellenadresse]). Erst beim starten wird die Tabelle vom PE-Loader mit konkreten Werten/Adressen der Funktionen gefüllt (da diese sich je nach System, C-Runtimeversion usw sehr sehr unterscheiden können).
Wenn man nun so eine Anwendung kopiert und sie selbst startet, muss man auch selber PE-Loader spielen und die Werte eintragen.
Geschweige denn, dass du auch Datasecton nicht mitkopiert hast - und überhaupt viele Aufrufe sich auf bestimmte Adressen beziehen, die dann natürlich nicht mehr stimmen (siehe den Fehler - es wird versucht sonstwohin zu schreiben) ;).
Daher: shellcode in Assembly schreiben und gleich die ganze Fummelei mit der Umwandlung eines "echten" C/Sonstwas Programms vermeiden.
hier mal der IDA Auszug deines Shellcodes:
Code:
 push    ebp
.text:000015E1                 mov     ebp, esp
.text:000015E3                 sub     esp, 0C0h
.text:000015E9                 push    ebx
.text:000015EA                 push    esi
.text:000015EB                 push    edi
.text:000015EC                 lea     edi, [ebp-0C0h]  <---- adresse stimmt nicht mehr
.text:000015F2                 mov     ecx, 30h
.text:000015F7                 mov     eax, 0CCCCCCCCh
.text:000015FC                 rep stosd
.text:000015FE                 push    416800h
.text:00001603                 mov     eax, ds:419338h  <---- hier auch
.text:00001608                 push    eax
.text:00001609                 call    sub_128F   <---- call nach "nirgendwo" (denn neue Executable hat da bestimmt andere Sachen stehen, als erwartet)
.text:0000160E                 add     esp, 8
.text:00001611                 mov     esi, esp
.text:00001613                 mov     ecx, ds:41933Ch
.text:00001619                 call    dword ptr ds:419320h  <--- indirekter Call einer externen Funktion, Adresse sowie Wert stimmen natürlich nicht mehr
.text:0000161F                 cmp     esi, esp
.text:00001621                 call    sub_12DA   <--- dasselbe
.text:00001626                 xor     eax, eax
.text:00001628                 pop     edi
.text:00001629                 pop     esi
.text:0000162A                 pop     ebx
.text:0000162B                 add     esp, 0C0h
.text:00001631                 cmp     ebp, esp
.text:00001633                 call    sub_12DA  <--- dasselbe
.text:00001638                 mov     esp, ebp
.text:0000163A                 pop     ebp
.text:0000163B                 retn
 
Mann, du antwortest immer schneller als ich mich korrigieren kann :-D
also afaik werden in COM dateien NUR OP Codes gespeichert.


Code:
 org 100h  
start:   
mov dx,hello_world  
mov ah,09h   
int 21h  
mov al, 0   
mov ah,4Ch   
int 21h  
section .data  
hello_world: db 'hello, world', 13, 10, '$'
? wird zu:
Code:
char code[] = "\xBA\x10\x01\xB4\x09\xCD\x21\xB0\x00\xB4\x4C\xCD\x21\x00\x00\x00\x68\x65\x6C\x6C\x6F\x2C\x20\x77\x6F\x72\x6C\x64\x0D\x0A\x24\xC3";

oder hab ich wieder was vergessen?^^ So langsam wirds peinlich^^

Naja trotzdem: Segmentation Fault bei 0xffffffff:

// Adresse = (int)*AdressPointer; // Hole aus Offset von *buffer Offset von Codebeginn
_asm{ call [buffer] }; //JMP zu Codebeginn
0041144B FF 15 70 75 41 00 call dword ptr [_buffer (417570h)]
}
-> 00411451 52 push edx <- hier stoppt er beim debugging im disassembler
00411452 8B CD mov ecx,ebp
00411454 50 push eax
...

MfG
 
also afaik werden in COM dateien NUR OP Codes gespeichert.
jep, aber COM==16-Bit => wird unter Windows nur noch im Emulatior ausgeführt.
d.h 16-Bit Opcodes samt DOS-Interrupts in einer 32-Bit Anwendung versuchten auszuführen ist vielleicht keine so gute Idee ;)
 
;( X( :( Sag mir was ich tun kann! :-D Die ganze exe vom MZ bis zur letzten 0 in speicher klatschen und starten, oder was um himmels willen? :-D

MfG
 
Au es klappt, wie geil! Zwar nicht ganz Fehlerfrei, aber mein Shutdown führts aus :-D

Nochmal Vielen Dank CDW ;-)

noch ein frohes Fest!
 
Zurück
Oben