次のプログラムを実行するとクラッシュしないのに、GDB でセグメンテーション違反でクラッシュするのはなぜですか? 32 ビット x86 (重要な場合は Athlon 64) で GCC 4.5.2 でコンパイルされています。
#include <stdio.h>
#include <string.h>
int modify(void)
{
__asm__("mov $0x41414141, %edx"); // Stray value.
__asm__("mov $0xbffff2d4, %eax"); // Addr. of ret pointer for function().
__asm__("mov %edx, (%eax)");
}
int function(void)
{
modify();
return 0;
}
int main(int argc, char **argv)
{
function();
return 0;
}
mov $0xbffff2d4, %eax は、GDB を使用して決定され、「関数」関数の戻りポインタが格納されたアドレスを見つけました。これはおそらく別のシステムでは異なるでしょう。このため、ASLR は無効にされました。
プログラムを実行しても何も起こりません。dmesg でのクラッシュの報告もありません。ただし、GDB で同じプログラムを実行すると、次のようになります。
Program received signal SIGSEGV, Segmentation fault.
0x41414141 in ?? ()
=> 0x41414141: Cannot access memory at address 0x41414141
これは、プログラムを正常に実行したときにも起こるはずです。実際、他のプログラムがクラッシュすると、いつものように segfault が発生します。適切な segfault でクラッシュする小さなプログラムを簡単に作成できます。しかし、なぜこの特定のプログラムはセグメンテーション違反でクラッシュしないのでしょうか?