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

3 に答える 3

11

eval()多くのスクリプト言語のように、cにはありませんが、実際にはありません。

ただし、説明しているのは、バッファオーバーフローエクスプロイトのようなものです。

ここで、文字列を使用して、バッファの後のアドレス空間に「コード」(c構文ではなくマシンコード)を書き込みます。これがこのトピックのちょっとしたチュートリアルです。

この情報をウイルスの作成に使用しないでください:(

于 2010-07-12T00:03:06.203 に答える
8

libtccC ソース コードをコンパイルして実行するために使用できます。

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);

いくつかの問題:

  1. libtccサポートされているアーキテクチャでのみコンパイルできます。
  2. 関数を持つ必要がありmainます。
于 2010-07-12T00:38:40.287 に答える
3

確かにそれは可能です。バッファ オーバーフロー エクスプロイトはこれを使用します。

配置できる文字列の種類については、シェルコードを参照してください。

基本的にできることは、マシンコードをスタックに置き、アドレスにジャンプすることです。これにより実行が行われます (OS/マシンで許可されている場合は、NX ビットを参照してください)。

おそらく、関数アドレスからスタック上の文字列に memcpy を実行してから、スタック上のアドレスにジャンプすることもできます。

于 2010-07-11T23:57:43.997 に答える