プログラムのアドレス空間に加えられた変更は、リバース デバッグ中に元に戻されないと予想されますか?
strlen
実行中に GOT 内のポインタが壊れるとセグメンテーション違反になるプログラムをデバッグしています。この質問へのコメントからのアドバイスのおかげで、-z relro
オプションとリンクすることで、このプログラムの GOT を読み取り専用にしました。ただし、問題のポインタが上書きされるのを防ぐことはできません。つまり、start
gdb のプログラムで、最初に出現する にステップしstrlen
、ポインターが有効であることを確認し (例: x/g 0x5555555d10a8 ==> 0x5555555d10a8 <strlen@got.plt>: 0x00007ffff7e8d1e0
)、continue
実行し、ポインターが無効になるのを待ちます (プログラム; 例: x/g 0x5555555d10a8 ==>
0x5555555d10a8 <strlen@got.plt>: 0x0000000000002156
)、プロンプトを表示するsegv
.
ただし、record full
実行全体 (最初の行からプログラムの segfault まで) と、その後awatch
へのポインターを含むアドレスstrlen
duringreverse-continue
の場合、ウォッチポイントはトリガーされません。そして、プログラムが最終的に命令 #0 に戻ったとき、ポインターは、セグメンテーション違反が発生したときに持っていた無効なアドレスを指しているままです。
これは 2 つの疑問につながります。-z relro
まず、リンカー オプションがあるにもかかわらず GOT が変更可能なのはなぜですか? 第 2 に、プログラムの実行中に変更されたメモリ内の場所 (へのポインタstrlen
) は、逆の実行中に元の値に復元されないことが予想されますか?