4

さて、私たち全員がC / C ++プログラマーが一度に私たちのタイムリーでない敵、悪魔のような信号SIGSEGV、セグメンテーション違反に遭遇したことを理解しています。さて、これは(過去形を強調して)魔法のGCC(またはg ++)コンパイラーによって吐き出されたマシンコードの一部内のフェイルセーフ/チェックシステムの形式であると理解しました。

だが!今日、私は仮想化されたArch Linuxシステム上で古き良きNASMを備えたx86アセンブラーをいじくり回していましたが、驚いたことに、そして残念なことに、悪意のあるSegFaultによってコーディング作業が再び妨げられました。

恐ろしい信号を生成したコードは次のとおりです。

mov eax, 0x7
mov [0xB8000], eax

Linuxカーネルがアセンブルされたプログラムをシェルにロードし、そこから実行することを理解しましたが、このMOV命令はプロセッサと1対1で相互作用すると思いました。カーネルは、私がアクセスしようとしていることをカーネルがどのように検出できるのでしょうか。少しのメモリで、命令を停止しますか?

プログラムがシェルにロードされたときに正確に何が起こるか、シェルに一度持っている権限、さらにはシェルとは何か、またはそれがどのように機能するかを理解するふりはしませんが、ASMがあなたに与えたと確信していましたプロセッサを完全に制御します。この魔法のカーネルは、プロセッサへの直接コマンドをどのように妨害しますか。また、本質的に純粋なマシンコードを作成するときに、このオペレーティングシステムコマンドのチェーンを実行しなければならないのはなぜですか。:O

4

2 に答える 2

5

Linuxは、プログラムがユーザーモードで実行されていることを実行します(x86のリング3)。さらに、ページベースのメモリ保護を使用して、プログラムがアクセスできるメモリ位置を制限しています。特に、プログラムは、変更する権限がない(VGAフレームバッファ)に書き込もうとします。プロセッサのMMUはこれを検出し、 CPU例外をスローします。Linuxカーネルはこの例外を処理し、それをセグメント違反シグナルに変換します 0xB8000。シグナルのカスタムハンドラーを設定していないと仮定すると、カーネルはプロセスを強制終了します。これを回避してハードウェアへのフルアクセスを取得するには、完全なアクセス許可でカーネルモード(x86ではリング0)で実行されるLinuxデバイスドライバーを作成するか、独自のオペレーティングシステムを作成してLinuxを完全にバイパスする必要があります。

于 2010-08-04T03:26:42.033 に答える
4

MMUはアクセスしようとしているメモリを保護しているため、一部のアクセス許可に違反する命令を実行すると、割り込み/プロセッサ例外が生成されます。その例外はカーネルによって処理され、セグメンテーション違反信号としてアプリケーションに転送されます。アプリケーションはSIGSEGVを処理しないため、アプリケーションは終了し、制御がシェルに戻ります。

探している「プロセッサを完全に制御」したい場合は、より低いレベルでコードを記述する必要があります(OSを実行し続けたい場合はカーネルで、必要な場合は独自のOSまたはエグゼクティブ)自分で起動することからすべてを処理するため)。

アセンブリプログラムを作成することは、Cプログラムを作成することと同じですが、Cコンパイラが出力しない奇妙な命令を生成できる可能性がある点が異なります。プログラムが書かれている言語だけに基づいてプログラムに付与される特別な許可や能力はありません。

于 2010-08-04T03:21:27.137 に答える