2010-03-13 16 views
5

Hola, estoy tratando de cargar el código máquina sin procesar en la memoria y ejecutarlo desde un programa C, ahora cuando el programa se ejecuta se rompe al intentar ejecutar Protege en la memoria para que sea ejecutable. Tampoco estoy completamente seguro de que si la memoria se establece correctamente se ejecutará. Actualmente estoy ejecutando esto en Ubuntu x86 Linux (Tal vez el problema es la sobreprotección de Ubuntu?)Cargando MachineCode From File en la Memoria y Ejecutando en C - mprotect Failing

Lo que tengo actualmente es la siguiente:

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

me pongo la advertencia del compilador:

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

No he conseguido que el programa llegue a este código todavía, así que no puedo ver si mi código de ensamblador está haciendo lo que debería.

+0

¿Qué sistema operativo? –

+0

Disculpe, esto es para Linux x86 específicamente Ubuntu. (Supongo que la sobreprotección de Ubuntu podría tener algo que ver con eso) – ChartreuseKitsune

+0

¿Qué tipo de falla es? ¿Has intentado simplemente ejecutarlo bajo gdb y viendo qué pasa después? –

Respuesta

5

Ok, aquí está la respuesta, de acuerdo con nuestra discusión en los comentarios :)

La región de memoria debe estar alineado con el tamaño de la página del sistema. La llamada posix_memalign() es una manera correcta de asignar memoria en tal caso :)

+0

Así que tiene que asignarse en múltiplos del tamaño de página que asumo, y no a partir de una longitud de archivo – ChartreuseKitsune

+0

Bueno, si lo hago bien, solo la dirección está alineada, no el tamaño. El tamaño se da en bytes (acc.para el hombre) –

+0

De acuerdo, parece haber pasado el error mprotect. Usando: membuf = (char *) memalign (pagesize, sz * sizeof (char)); en lugar de malloc. – ChartreuseKitsune

1

Agregue un 0xc3 (instrucción de retorno) después de sus bytes 0x90 (noop). Es posible que su programa falle porque se ejecuta al final de los NOOP y en la memoria no inicializada, quién sabe qué se esconde allí o en el final de la página ejecutable. Realmente no puedo decir sin mirar lo que está en el archivo que estás cargando.

BTW strace es muy útil para este tipo de programas. Te habría dicho cuál era el error en mprotect.

1

Uso de todas las permanentes PROT_EXEC | PROT_READ | PROT_WRIT tampoco es necesario y es un poco peligroso. No necesita PROT_WRITE en general, solo exec y leer es suficiente.

Algunos kernels asegurados ni siquiera permiten PROT_EXEC | PROT_WRIT.

Cuestiones relacionadas