#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;
}
Вы можете использовать libtcc
для компиляции и запуска исходного кода на 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);
Пара проблем:
libtcc
только на поддерживаемой архитектуре. main
. Вроде того, но не совсем, в c нет eval()
, как во многих скриптовых языках.
Однако то, что вы описываете, похоже на эксплойт переполнения буфера.
Где вы используете строку для записи "кода" (не синтаксиса языка Си, а машинного кода) в адресное пространство после буфера. Вот небольшой учебник по этой теме.
Не используйте эту информацию для написания вируса :(
Конечно, это возможно. Эксплойты переполнения буфера используют его.
Смотрите Shellcode, чтобы узнать, какие строки вы можете разместить.
По сути, вы можете поместить машинный код в стек и перейти по адресу. Это вызовет выполнение (если ОС/машина это позволяет, см. NX bit).
Возможно, вы даже можете попытаться выполнить memcpy из адреса некоторой функции в строку на стеке, а затем попытаться перепрыгнуть по адресу на стеке.