問題タブ [got]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c - GOT に加えられた変更は、リバース デバッグ中に元に戻されることが予想されますか?
プログラムのアドレス空間に加えられた変更は、リバース デバッグ中に元に戻されないと予想されますか?
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
) は、逆の実行中に元の値に復元されないことが予想されますか?
gcc - 最初に 16($fp) に格納せずに、MIPS GCC が関数呼び出し (GOT ポインター) の後に 16($fp) から $28 をリロードするのはなぜですか?
長く見えますが、コード全体を貼り付ける必要があると思います。
テスト用の簡単なコードを書きます。
組み立て後:
各関数呼び出しの後に、lw $28,16($fp)
命令があることに気付きました。しかし、呼び出し元または呼び出し先のいずれかに最初に値を格納するコードは見当たりません。
MIPS アセンブリを読み取ることができます。lw
それがロード ワードであり、$fp と $sp がフレーム ポインターとスタック ポインターであることはわかっています。
から何かをロードすることがどのように理にかなっているのか理解できません16($fp)
。初期化されていないスペースがあるようです。
私は知って$28
おり$gp
、呼び出しの前に関数アドレスをロードするためのGOTポインターとして使用されていることがわかりますが、関数で使用される前にそのレジスタを初期化するものは何もないようです。
MIPS 呼び出し規則$28
では、関数のエントリで GOT を既に指している必要がありますか?