5

次のプログラムを実行するとクラッシュしないのに、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 でクラッシュする小さなプログラムを簡単に作成できます。しかし、なぜこの特定のプログラムはセグメンテーション違反でクラッシュしないのでしょうか?

4

1 に答える 1

2

完全な ASLR を無効にしても、ランダム化されたスタックとヒープが得られる場合があります。norandmapsカーネル ブート パラメータを使用してグローバルにオフにするか、/proc/sys/kernel/randomize_va_spaceゼロに設定して実行時にオフにすることができます。それはまた、プロセスパーソナリティの一部でもあります。

disable-randomizationGDB では、次の設定を使用してこれを微調整できます。

(gdb) help set disable-randomization
Set disabling of debuggee's virtual address space randomization.
When this mode is on (which is the default), randomization of the virtual
address space is disabled.  Standalone programs run with the randomization
enabled by default on some platforms.

これを説明するための小さなテスト プログラムとして、次のようなローカル変数のアドレスを出力できます。

#include <stdio.h>

int main(int argc, char **argv)
{
    printf("%p\n", &argc);
    return 0;
}
于 2012-11-04T01:24:36.600 に答える