2010-03-13 17 views
5

Ciao Sto cercando di caricare il codice macchina raw in memoria ed eseguirlo da un programma C, in questo momento quando il programma viene eseguito si interrompe quando si cerca di eseguire mprotect sulla memoria per renderlo eseguibile. Inoltre, non sono del tutto sicuro che se la memoria viene impostata correttamente verrà eseguita. Attualmente sto facendo funzionare questo su x86 Ubuntu Linux (Forse il problema è eccessiva protezione di Ubuntu?)Caricamento MachineCode da file in memoria ed esecuzione in C - mprotect Failing

Quello che ho attualmente è la seguente:

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

io capisco l'avviso del compilatore:

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

Non ho ancora ottenuto il programma per raggiungere questo codice, quindi non sono in grado di vedere se il mio codice assembler sta facendo ciò che dovrebbe.

+0

Quale sistema operativo? –

+0

Siamo spiacenti, questo è per Linux x86 in particolare per Ubuntu. (Suppongo che l'eccessiva protezione di Ubuntu possa avere qualcosa a che fare con esso) – ChartreuseKitsune

+0

Che tipo di errore è? Hai provato a eseguirlo semplicemente sotto gdb e guardando, cosa succede dopo? –

risposta

5

Ok, ecco la risposta, secondo la nostra discussione nei commenti :)

La regione di memoria dovrebbe essere allineato le dimensioni della pagina del sistema. la chiamata posix_memalign() è un modo giusto per allocare la memoria in questo caso :)

+0

Quindi deve essere assegnato in multipli della dimensione della pagina presumo, e non da una lunghezza del file – ChartreuseKitsune

+0

Bene, se ho capito bene, solo l'indirizzo è allineato, non la dimensione. La dimensione è espressa in byte (acc.per l'uomo) –

+0

Ok, sembra averlo superato l'errore mprotect. Utilizzo: membuf = (char *) memalign (pagesize, sz * sizeof (char)); Invece di malloc. – ChartreuseKitsune

1

Aggiungere un 0xc3 (istruzione di ritorno) dopo i byte 0x90 (noop). Il tuo programma potrebbe andare in crash perché si esaurisce la fine degli NOOP e nella memoria non inizializzata, chissà cosa si nasconde lì, o alla fine della pagina eseguibile. Non posso davvero dirlo senza guardare cosa c'è nel file che stai caricando.

BTW strace è molto utile per questi tipi di programmi. Ti avrebbe detto qual era l'errore in mprotect.

1

Utilizzo di tutti i permessi PROT_EXEC | PROT_READ | Anche PROT_WRIT non è necessario e un po 'pericoloso. Generalmente non è necessario PROT_WRITE, basta eseguire exec e read.

Alcuni kernel protetti non consentono nemmeno PROT_EXEC | PROT_WRIT.