2010-07-11 23 views
8
#include <stdio.h> 

int main(int argc, char** argv) 
{ 
    void (*p) (void); 
    /* this obviously won't work, but what string could I put in 
     here (if anything) to make this execute something meaningful? 
     Does any OS allow instructions to be read from 
     the stack rather than text area of the process image? */ 
    char *c = "void f() { printf(\"Hello, world!\"); }"; 
    p = (void (*)())c; 
    p(); 
    return 0; 
} 

Respuesta

2

Sure it is posible. Buffer Overflow exploits usarlo.

Consulte Shellcode para saber qué tipo de cadenas puede colocar.

Básicamente lo que puede hacer es poner el código de la máquina en la pila y saltar a la dirección. Esto causará la ejecución (si el OS/máquina lo permite, vea NX bit).

Incluso podrías intentar hacer una memcpy desde alguna dirección de función en una cadena en la pila y luego intentar saltar a la dirección en la pila.

+0

Gracias, ¿podrían darme más información sobre cómo saltaría a la dirección después de memcpy? ¿Y qué tan grande sería un pedazo de memoria memcpy? ¿Tendría que saber cómo se representa la función en lenguaje ensamblador para eso? – user389094

+0

Tenga en cuenta que estamos hablando de insertar código ejecutable binario aquí; no solo podrá almacenar el desbordamiento de C y esperar que el procesador conozca la WTF de la que está hablando. –

+0

@ rahulkumar42: Puedes intentar convertir la dirección de la cadena como un puntero a la función e intentar llamarlo. Realmente no necesita saber cómo se representa la función, la máquina hará la interpretación por usted. El tamaño para copiar depende de la función que está copiando y puede ser difícil de averiguar. –

8

Más o menos, no hay eval() en c, como en muchos lenguajes de scripting.

Sin embargo, lo que está describiendo es una especie de Buffer Overflow exploit.

Donde, utiliza una cadena para escribir "código" (no la sintaxis c, sino el código de máquina) en el espacio de direcciones después del búfer. Aquí hay un pequeño y agradable tutorial del tema.

No utilice esta información para escribir un virus :(

+2

Hay una especie de 'eval()': escribe un compilador de C, compila la cadena en código máquina y luego ejecútalo. –

+0

Gracias, mi intención es escribir un programa que se modifique durante la ejecución, quizás incluso de forma impredecible. Nada malicioso, solo como un ejercicio de aprendizaje. – user389094

+0

@Chris: buen punto;) @rahul: Definitivamente una buena experiencia de aprendizaje, suena divertido :) – Stephen

5

Usted podría utilizar libtcc para compilar y ejecutar el código fuente C:

const char *code = "int main(int argc, char**argv) { printf(\"Hello, world!\"); return 0; }"; 
TCCState *tcc = tcc_new(); 

if (tcc_compile_string(tcc, code)) 
{ 
    // an error occurred compiling the string (syntax errors perhaps?) 
} 

int argc = 1; 
char *argv[] = { "test" }; 

int result = tcc_run (tcc, argc, argv); 

// result should be the return value of the compiled "main" function. 
// be sure to delete the memory used by libtcc 

tcc_delete(tcc); 

Un coouple de cuestiones:

  1. Solo puede compilar libtcc en una arquitectura compatible.
  2. Debe tener un main funciones.
Cuestiones relacionadas