1

このコードの関数の戻りアドレスを変更して、プログラムの実行フローを変更しようとしています:

void s(int signum) {
    int b = 1;
    *(&b+3) = *(&b+3) + 4;
}

void f() {
    while(true);
    printf("f exit\n");
}

int main() {
    signal( SIGCONT, s );

    f();

    printf("end of prog");

    return 0;
}

この目的のために、f関数を呼び出します。そのため、 でスタックしwhile(true)ます。次に、コマンドSIGCONTを使用してプログラムにシグナルを送信しますkill -SIGCONT <PID>。ここで、プログラムは実行を中断while(true)し、関数fを実行する必要がありsます。関数では、ランタイムスタックで関数の戻りアドレスを見つけるようsに定義しました。この値を で変更して、 に戻ったときにの実行をスキップして を実行するようにします。しかし、それは行き詰まり続けており、これを機能させる方法がわかりません。bs*(&b+3)*(&b+3) = *(&b+3) + 4fwhile(true)printf("f exit\n")while

注: 以前に __builtin_return_address(0) によって返された値と比較して、*(&b+3) がリターン アドレスであることを確認しました。

関数の本体でmainありf、変更されていない必要があります。

ありがとう。

4

1 に答える 1

0

解決策は、何らかの変更があったことを while ループに伝えることです。例えば

volatile int flag = 0 ;

void s(int signum) {
    int b = 1;
    __sync_fetch_and_add( &flag, 1 ) ;
}

void f() {
    while(__sync_fetch_and_add( &flag, 0 ) == 0);
    printf("f exit\n");
}

アトミックな組み込み (関数 __sync_fetch_and_add) を追加して、ループが最適化されないようにします。単純な volatile で十分かどうかはわかりません。これについての自分自身のコメントを待っています....

于 2015-07-09T18:13:23.630 に答える