バッファオーバーフローは上書きする変数のデータ型を変更しますか?[閉まっている]


8

Cの文字配列があるとしchar buf[15]ます。たとえば、変数のint set_me = 0直後のメモリ位置にデータが保存されているとしますchar buf[15]bufstring "aaabbbcccdddeee\xef\xbe\xad\xde"でオーバーフローした場合、set_meデータ型は整数から文字配列に変更されますか?


3
誰がデータを解釈しているかによります。最後に、すべてがバイナリです。したがって、それを解釈する方法は、有効な整数値であるか、キャストエラーを引き起こす可能性があります
Ganesh R.

回答:


33

番号。

変数の「データ型」は、ソースコードにのみ関連します(一部の言語にのみ関連します)。変数の処理方法をコンパイラーに指示します。

これらの高レベルのデータ型は、コンパイルされた(ネイティブ)コードには存在しません。コンパイラが生成する命令に影響を与える可能性がありますが、命令自体は、データが文字または数値を表すかどうかは関係ありません。


変数はハードウェアには存在しません。ハードウェアでは、メモリの場所とそれらを操作する命令があります。

変数は、メモリの場所にあるデータのビュー見なすことができます。同じメモリを少しだけ細かく見れば(同じ場所を参照する異なるタイプの異なる変数)、同じバイナリ値は異なる意味を持つ可能性があります。

たとえば、バイト0x41はUTF-8でエンコードされた文字として解釈されますA。また、1バイト整数として解釈されることもあります65。また、マルチバイト整数または浮動小数点数の1バイト、またはマルチバイト文字エンコーディングの1バイトとして解釈することもできます。それはビットセットかもしれません0b1000001。同じメモリ位置の同じバイトからすべて。C言語では、これらの異なる型にキャストすることでこの効果を確認できます。

「バッファオーバーフロー」が発生すると、コンパイラや言語が予期する範囲を超えて何かをしていることになります。ただし、ハードウェアに関する限り1、バイト(単一または複数)をメモリの場所に書き込みます。メモリーロケーションには「タイプ」はありません。実際、ハードウェアは、特定のバイトのセットがコード内で配列またはバッファになることさえ知りません。

次にコード内のそのメモリ位置にアクセスするときはいつでも、命令は最初に定義されたとおりに実行されます。例えば、彼らはそこに番号を期待していたならば、彼らはデータのバイト何に作用しているかのよう彼らは数でした。


この例を使用するにintは、符号付きの4バイト(32ビット)整数であると想定します。

+-------------+--------------------------------------------+-----------+
| Source code |                  char[15]                  |    int    |
+-------------+--------------------------------------------------------+
| Memory      |61|61|61|62|62|62|63|63|63|64|64|64|65|65|65|EF|BE|AD|DE|
+-------------+--------------------------------------------------------+

ビッグエンディアンシステムを想定すると、intのメモリロケーションにが含まれていることがわかり0xEFBEADDEます2。これは、署名された32ビットint -272716322です。同じメモリをunsigned int(uint)と解釈すると、4022250974代わりに解釈されます。メモリ内のまったく同じデータの場合、意味は完全にデータの表示方法に依存します。


1保護されたメモリ領域への書き込みを妨げるメカニズムがいくつかあり、そうしようとするとプログラムがクラッシュします。

2 x86は実際にはリトルエンディアンです。つまり、大きな値を構成するバイトを逆方向に解釈します。したがって、x86では代わりに0xDEADBEEF、署名付き-559038737または署名なしを指定し3735928559ます。


それで0xdeadbeef、x86アーキテクチャでは、10進数の対応よりもメモリ内のスペースが少なくなり3735928559ますか?
Darien Springer、

2
@DarienSpringerどちらも4バイトのメモリを使用します—これらは同じ4バイトシーケンスです。それらはメモリ内で同一です。必要に応じて、すべてをメモリ内でベース2(バイナリ)と見なすことができます。次に、それらを表示する(出力用の文字列に変換する)ときに、表示する基数を選択できます。16進数は16進数、10進数は10進数です。文字列表現は別のメモリロケーションに保存され、さまざまな量を使用できますメモリの(各文字が個別のバイトであるため)。文字列は、 0xDEADBEEFとしてメモリに記憶されます0x30 0x78 0x44 0x45 0x41 0x44 0x42 0x45 0x45 0x46
ボブ

5
@DarienSpringer別の言い方をすると、数値は、その基数が何であっても同じ数値です。16進数は、バイナリを表示するための便利な(コンパクトな)方法です。物理的には、バイナリです。人間は小数が好きなので、数値を小数で表示することがよくあります。しかし、表示ステップに到達するまで、すべての数値演算(加算、減算、乗算など)はメモリ内の同じバイナリデータで機能します。
ボブ

1
「あなたはint型のメモリ位置が今0xEFBEADDEであることがわかります」 Nitpick:私はあなたがこれを意図していなかったけど、あなたはint型が配置されていると言っているように聞こえるメモリロケーション0xEFBEADDE。たぶんそれを少し言い換えます。そうでなければ、これは素晴らしい答えです-私は特に「ビュー」のアナロジーと「目を細める」アイデアが好きです:)
レース

@LightnessRacesinOrbit良い点。編集。
ボブ

2

Cの観点からは、答えは「だれが知っているか、それは未定義の動作です」です。

タイプはCの概念であり、ハードウェアではありません。ただし、プログラムに未定義の動作がある場合、Cの規則は適用されません。これは、C標準における未定義の動作の文字通りの意味です。バッファオーバーフローはその1つの形式です。

私は最初に「Cルールは適用されなくなりました」と書きましたが、実際には、未定義の動作は遡及的です。Cの規則は、将来未定義の動作が発生するプログラムには適用されません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.