2010-03-13 9 views
5

Hallo Ich versuche, router Maschinencode in den Speicher zu laden und aus einem C-Programm ausführen, gerade jetzt, wenn das Programm ausgeführt wird bricht es beim Versuch zu laufen mprotect auf den Speicher, um es ausführbar zu machen. Ich bin mir auch nicht ganz sicher, ob der Speicher korrekt ausgeführt wird, wenn er richtig eingestellt ist. Ich bin mit dieser derzeit auf Ubuntu Linux x86 (Vielleicht ist das Problem Ubuntu über Schutz?)Laden von MachineCode aus Datei in den Speicher und Ausführen in C - mprotect Failing

Was ich zur Zeit haben, ist die folgende:

#include <memory.h> 
#include <sys/mman.h> 
#include <stdio.h> 

int main (int argc, char **argv) 
{ 
FILE *fp; 
int sz = 0; 
char *membuf; 
int output = 0; 

fp = fopen(argv[1],"rb"); 

if(fp == NULL) 
{ 
    printf("Failed to open file, aborting!\n"); 
    exit(1); 
} 

fseek(fp, 0L, SEEK_END); 
sz = ftell(fp); 
fseek(fp, 0L, SEEK_SET); 


membuf = (char *)malloc(sz*sizeof(char)); 
if(membuf == NULL) 
{ 
    printf("Failed to allocate memory, aborting!\n"); 
    exit(1); 
} 

    memset(membuf, 0x90, sz*sizeof(char)); 

if(mprotect(membuf, sz*sizeof(char), PROT_EXEC | PROT_READ | PROT_WRITE) == -1) 
{ 
    perror("mprotect"); 
    printf("mprotect failed!!! aborting!\n"); 
    exit(1); 
} 



if(!(fread(membuf, sz*sizeof(char), 1, fp))) 
{ 
    perror("fread"); 
    printf("Read failed, aborting!\n"); 
    exit(1); 
} 
__asm__ 
( 
    "call %%eax;" 
    : "=a" (output) 
     : "a" (membuf) 
); 
printf("Output = %x\n", output); 

return 0; 
} 

ich die Compiler-Warnung zu tun bekommen:

/tmp/ccVnhHak.s: Assembler messages: 
/tmp/ccVnhHak.s:107: Warning: indirect call without `*' 

Ich habe das Programm noch nicht bekommen, um diesen Code zu erreichen, also kann ich nicht sehen, ob mein Assembler-Code tut, was er sollte.

+0

Welches Betriebssystem? –

+0

Sorry, das ist für x86 Linux speziell Ubuntu. (Ich vermute Ubuntu's Überschutz könnte etwas damit zu tun haben) – ChartreuseKitsune

+0

Was für ein Fehler ist das? Haben Sie versucht, es einfach unter gdb laufen zu lassen und zuzusehen, was als nächstes passiert? –

Antwort

5

Ok, hier ist die Antwort, nach der Diskussion in den Kommentaren :)

Der Speicherbereich auf der Systemseite Größe ausgerichtet werden sollte. posix_memalign() - Aufruf ist ein richtiger Weg, um in diesem Fall Speicher zuzuweisen :)

+0

Also muss es in Vielfachen der Seitengröße zugewiesen werden, die ich vermute, und nicht von einer Dateilänge – ChartreuseKitsune

+0

Nun, wenn ich es richtig mache, ist nur die Adresse ausgerichtet, nicht die Größe. Die Größe wird in Bytes angegeben (acc.zu dem Mann) –

+0

Okay, das scheint den mprotect-Fehler hinter sich zu haben. Verwendung: membuf = (char *) memalign (Seitengröße, sz * sizeof (char)); Statt malloc. – ChartreuseKitsune

1

Fügen Sie eine 0xc3 (Rückgabeanweisung) nach Ihren 0x90 (noop) Bytes hinzu. Ihr Programm stürzt möglicherweise ab, weil es am Ende der NOOPs und entweder in nicht initialisiertem Speicher läuft, wer weiß, was dort lauert, oder in das Ende der ausführbaren Seite. Ich kann nicht wirklich sagen, ohne zu sehen, was in der Datei ist, die Sie laden.

BTW Strace ist sehr nützlich für diese Art von Programmen. Es hätte dir gesagt, was der Fehler in mprotect war.

1

Verwendung aller Dauerwellen PROT_EXEC | PROT_READ | PROT_WRIT wird auch nicht benötigt und ist irgendwie gefährlich. Sie brauchen im Allgemeinen nicht PROT_WRITE, nur Exec und Read ist genug.

Einige gesicherte Kernel erlauben nicht einmal PROT_EXEC | PROT_SCHRITT.