このコードを c:__asm__("mov $10, %rsi"); printf("%x")
に入力すると、 が出力されますa
。
でデバッグしたgdb
ところ、結果ストア int が見つかりましたregister esi
。
質問: なぜ結果はesi
?
1850 次
2 に答える
12
printf("%x")
2 番目の引数を取得しようとしますが、そこにないため、本来あるべきメモリを読み取り、そこにあるゴミを見つけて出力します。
つまり、未定義の動作です。
編集:esi
レジスタと同じ値が表示される理由は、 System V AMD64 ABI (ほとんどの Unix が従う仕様) が、可能な場合はレジスタを介して最初のいくつかの引数を渡すためです。2 番目の引数は を介して渡されるrsi
ため、そこprintf
から読み取ります。
于 2013-04-23T08:31:11.083 に答える
2
を呼び出すとprintf("%x")
、必要な引数が (逆の順序で) スタックにプッシュされ、最終的にアセンブリ コマンドを使用して関数が呼び出されcall
ます。format string"%x"
をprintf()
指定すると、少なくとも 1 つの引数が続くことが期待されるため、スタックの次の値が読み取られます。これは何でもかまいません...
したがって、この動作は実際には未定義であり、多くの場合、スタックを破損する可能性があるため、エクスプロイトの原因となります。 .
たぶん、このトピックについて少し言い訳をします。
于 2013-04-23T08:36:22.737 に答える