質問: 雑な文章で申し訳ないです。回答お願いします>< ### 前提・実現したいこと スタックベースのバッファオーバーフローについて書かれている書籍を読み、理解できない点があったので、それを理解することを目的とする。 スタックフレームにグローバル変数がどのように影響しているのかを理解する。 私はスタックフレームはこのようなものと考えており、グローバル変数はスタックではなく静的領域に存在すると考えている。 以下に簡単な例を示す。 低位アドレス ... local variable saved ebp return address next frame 高位アドレス ### 発生している問題・エラーメッセージ スタックベースのバッファオーバーフローという前提があるにもかかわらず、グローバル変数をオーバーフローさせているように見える。 しかし、しっかりとオーバーフローは起こり、スタックフレームに影響していることが確認できる。(つまり私の理解が及んでいない?) ### 該当のソースコード ``` #include #include char buffer[32]; int main(int argc, char *argv) { char local[32]; printf("buffer: 0x%x\n", buffer); fgets(local, 128, stdin); strcpy(buffer, local); return 0; } ``` ### 試したこと gdbにpedaを導入してレジスタの値などをチェックした。 実行してから、入力を求められ、bufferの容量を超える文字を入力した。 結果としては、しっかりとオーバーフローを起こし、スタックフレームに干渉していた。 以下に実行結果を貼る。 --- ./bof3 buffer: 0x804a060 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Segmentation fault --- gdb-peda$ r Starting program: /home/setsu/Desktop/bof3 buffer: 0x804a060 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Program received signal SIGSEGV, Segmentation fault. [----------------------------------registers-----------------------------------] EAX: 0x0 EBX: 0xf7fbc000 --> 0x1b9d9c ECX: 0xffffd150 --> 0xa4141 (AA ) EDX: 0x804a0a0 --> 0xa4141 (AA ) ESI: 0x0 EDI: 0x0 EBP: 0x41414141 (AAAA) ESP: 0xffffd140 ('A' ...) EIP: 0x41414141 (AAAA) [-------------------------------------code-------------------------------------] Invalid $PC address: 0x41414141 --- EIPの値を見るとわかるが、しっかりとAの文字コードである41が表示されている。 bufferがローカル変数なら納得がいくのですが。。。 回答お待ちしております。 ### 補足情報(言語/FW/ツール等のバージョンなど) CentOS Linux release 7.3.1611 (Core) gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11) GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-94.el7
回答: おやりになりたいことの意図がいまいちわかりませんが、単純なバグです。 ``` char local[32]; ... fgets(local, 128, stdin); ``` 32バイトしかない配列local[]に128バイトまで格納して構わない、としてます。ここが根本的なバグです。 'A'を32個以上入力したら、もうその時点でlocal[]がバッファ・オーバーフローします。バッファ・オーバーフローはbuffer[]にコピーする以前に、既に起きているのです。 そのlocal[]はスタックフレームに在りますよね。local[]がバッファオーバーフローすれば、スタックフレームに在る他のメモリを破壊する、即ち「スタックフレームに干渉」するのは当然です。 local[]のサイズを128に変更して、もう一度試してみて下さい。 ``` char local[128]; ```