1

次のようなコードは、シェルコードを「テスト」、つまり実行できるはずです。

char shellcode[] = "...";

int main(int argc, char **argv)
{
    int (*func)();
    func = (int (*)()) shellcode;
    (int)(*func)();
}

ただし、これらの例を使用しようとすると、シェルコードの最初の命令でセグメンテーション違反を受け取るため、コードが実行可能ではないメモリで実行されているように見えることがわかります。

代わりにシェルコード宣言を a に変更すると#define、シェルコードを実行できます。ただし、シェルコードは、独自のメモリに書き込もうとすると停止します (このシェルコードは、スタック上で実行されることを前提としています)。

だから私の質問は、実行可能(明らかに)および書き込み可能なメモリを想定しているシェルコードをテストする最も簡単で信頼できる方法は何ですか?コードをスタックまたはヒープに割り当ててそこにジャンプしようとすると、NX ビット保護に遭遇し、再び失敗します。明らかにNXビットを無効にすることができましたが、このテストを行うためのより良い方法はありませんか?

4

2 に答える 2

1

書き込み可能で実行可能なメモリ領域を割り当て (たとえばmmapand を使用mprotect)、そこにコードを配置し、それを呼び出しますmain。W^X、PaX などの実行可能領域の保護の場合、最初にメモリ領域を書き込み可能にしてシェルコードをコピーし、次に実行可能にしてそれを実行することができますが、マイレージは適切な保護によって異なる場合があります.

于 2013-03-12T12:51:53.603 に答える
0

機能をテストすることだけが必要な場合は、対応するアセンブリを関数に記述できます。ただし、これはシェルコードをバイト文字列としてではなくアセンブリをテストするだけであり、シェルコードがアセンブリによって厳密に生成されていない場合 (たとえば、「存在しない」命令の途中にジャンプする場合) は機能しません。この場合、コードを実行可能メモリにプッシュする必要があります。自分で割り当てるか、既存の .text セクションを上書きできます (ただし、読み取り専用を無効にする必要があります)。

于 2015-01-19T13:03:45.927 に答える