2017-10-06 10 views
0

なぜこのプログラムはsegfaultを引き起こしますか?私は現在、スタックオーバーフローについて書くと(参考のために、私は32ビットのLinuxマシンを使用しています)の下に次のプログラムを作成しています

#include <stdio.h> 
#include <string.h> 

int main() { 
    char foo[16]; 
    strcpy(foo, "AAAAAAAAAAAAAAAABBBBC"); 
} 

このプログラムは

gcc stack_buffer_2.c -g -o stack_buffer_2 -fno-stack-protector 

何でコンパイルされましたこのプログラムはあるん

  • フィルが「A」を持つすべての「foo」という配列は
  • 塗りつぶしの文字私はGDB andhereで、このプログラムの動作を検証し

ESP保存に 'B' 文字

  • 書き込み 'C' CHAR(プラスヌル文字)でaved EBPは、私が得たものである:

    (gdb) run 
    
    Program received signal SIGSEGV, Segmentation fault. 
    0xb7e30043 in ??() from /lib/i386-linux-gnu/libc.so.6 
    

    プログラムは、このコンテキストでは、__libc_start_mainからの戻りポイントである元の値0xb7e31637の代わりに、0xb7e30043(0x43およびヌルターミネータでオーバーフローした値)にジャンプしようとしました。

    ここで私にとって厄介なものがあります。 "info proc mappings"を実行すると、0xb7e30043が "有効な"メモリのように見えることがわかります(/lib/i386-linux-gnu/libc.so.6内)

    私はsegfaultsが私は「所有していない」、またはマップされていないセグメントにしかし、この場合、これは私のアプリケーションのメモリ空間の中にあり、libcはそれにマップされているので、なぜsegfaultを取得していますか?

    これは、オーバーフローEIPがlibc内のランダムな命令を指しているため、これは何らかのミスアライメントによるものと思われます。そうなら、どうすれば調整できますか?その背後にある制約とそれを強制するのは何ですか?カーネル、MMU?

  • +0

    glibcシンボルをロードしていない限り、 '0xb7e30043 in ?? 'はあなたが' glibc'関数の中にいないことを暗示しているようです。 EIPアドレスを重視する理由は何ですか。実行されている命令については何も言わない。 segfaultのトレースではあまり考えないでください。 'main'からの' return'の 'stepi'だけでなく、レジスタを見て、アセンブリコードを調べて、正確に何が起こるかを見てください。さらに、この質問はおそらくStackOverflowに最適です(意図しない言い訳なし) – xhienne

    +0

    _0xb7e30043 in ??あなたがglibc関数の中にいないことを暗示しているように思えます_ - ランタイムは、私がglinc関数の中にいないことをどのように知っていますか?実行する前にシンボルテーブルを見ていますか? –

    +0

    私は確信していませんが、メッセージにはそのアドレスにアクセスするためのsegfaultであるとは言えませんが、そのアドレスでコードを実行するとsegfaultが発生します。これは、レジスタを適切に設定せずにランダムなコードを実行する場合に起こります。または、実際のオペコードへのバイトオフセットがあり、完全に混乱した結果を得る別のオペコードを取得します。あなたは逆アセンブラを見ましたか? – Philippos

    答えて

    0

    0xb7e30043の命令が無効であるという問題がありました。ここで

    は現在の命令です:

    0xb7e30043: add %cl,(%eax) 
    

    私はEAX値に見て、それがゼロです。そこから、物事は簡単です。プロセスは0x0でメモリにアクセスしようとしましたが、segfaultで失敗しました。

    関連する問題