仮想マシンのロードメカニズム(検証)

検証

検証テストフェーズの最初のステップであるこのステップの目的は、クラスファイルのバイトストリームに含まれる情報が現在の仮想マシンの要件を満たしていることを確認することです。また、仮想マシン自体のセキュリティを危険にさらすことはありません

Java言語自体は、純粋なJava言語コードを使用した比較的安全な言語です。できません。配列の境界外のデータにアクセスし、オブジェクトを配列に変換する方法など。そして、実装されたタイプの存在しないコード行にジャンプします。これが行われると、境界は安価になることを拒否しますが、Jieは前に、クラスファイルは必ずしもJavaソースコードをコンパイルする必要はないと述べました。任意のメソッドを使用して、16進エディターで直接記述されたクラスファイルを生成または含めることができます。言語レベルでJavaコードを再度削除することによって実行できないことをデコードすることは可能ですが、少なくともそれは起こります。表現可能な仮想マシンが入力バイトストリームをチェックせず、完全に信頼している場合、有害なバイトストリームのロードによりシステムクラッシュが発生する可能性が高いため、仮想マシンが自身を保護するための重要なタスクは検証です。

検証フェーズは非常に重要です。このフェーズが厳密であるかどうかによって、仮想マシンが悪意のあるコード攻撃と通信しているかどうかが直接決まります。実行パフォーマンスの観点から、検証フェーズのワークロードは仮想マシンのクラスロードです。これはシステムはかなりの部分を占めています。このメカニズムの制限は、クラスファイル形式の静的および構造上の制約にリストされているいくつかの一般的な仕様で知られています。入力バイトストリームがクラスファイル形式の制約を満たしていないことが確認された場合、仮想マシンはJava。ランダム検証、例外、またはそのような異常ですが、具体的にどの側面をチェックする必要があるか、チェック、検証、およびチェックの方法は、2011年にリリースされたJava仮想マシン仕様Java seの第7版まで、十分な要件と明確な指示ではありません。検証プロセスの説明の長さが10ページ未満から100ページに大幅に増加しました。30ページ。この時点で、制約と検証ルールが具体的になり、スペースによって制限されます。当初はルールをひとつひとつカットすることはできませんでしたが、全体として見ると、検証フェーズは次の4フェーズの検証アクションを大まかに完了します。ファイル形式チェック、メタデータチェック、バイトコードチェック、シンボル参照チェック。

ファイル形式の検証

最初の段階は、予約がクラスファイル形式の仕様に準拠しており、仮想マシンの現在のバージョンで処理できるかどうかを確認することです。この段階には、次の確認ポイントが含まれる場合があります。
1.マジックナンバーxcafebabeで始まるかどうか
2.メジャーバージョン番号とマイナーバージョン番号が現在の仮想マシンの処理範囲内にあるかどうか。
3.
定数の定数値にサポートされていない定数タイプがありますか4.定数を指すさまざまなインデックス値にのみ存在しない定数またはタイプに準拠していない定数があり
ます5.かどうかクラスファイルの各部分とファイル自体削除または追加された他の情報があります。

実際、最初のフェーズの検証ポイントはそれ以上のものであり、上記はホットストップ仮想マシンからのものです。ソースコードのコンテンツのごく一部。この検証フェーズの主な目的は、入力バイトストリームを確認することです。Blueは正しく解析され、メソッド領域に格納され、フォーマットはJavaタイプ情報を記述するための要件を満たしています。この段階での検証は、バイナリバイトストリームに基づいています。この段階で検証に合格した後にのみ、バイトストリームはストレージ用のメモリのメソッド領域に入ります。したがって、以下の3つの検証段階はすべて、メソッド領域のストレージ構造に基づいています。バイトストリームを直接操作しなくなりました

メタデータの検証

第2段階は、バイトコードによって記述された情報に対してセマンティック分析を実行して、記述された情報がJavaに準拠していることを確認することです。言語仕様の要件には、この段階で次の検証ポイントが含まれる場合があります
。1。このクラスには親クラスがありますか。オブジェクトを除いて、すべての人が親クラスを持っています。
2.このクラスの親クラスは、継承が許可されていないクラスを継承しますか?ファイナル
3によって変更されたクラス。このクラスが抽象クラスでない場合、親クラスまたはインターフェイスに実装する必要があるすべてのメソッドを実装する
かどうか4.クラスのフィールドメソッドが親クラスと競合するかどうか、オーバーライドする場合親クラスFieldのfinal。または、ルールに準拠していないメソッドのオーバーロードがあります。たとえば、戻り値の型が異なる場合、メソッドとパラメーターが同じであるなどです。

第2段階の主な目的は、クラスのメタデータ情報に対してセマンティック検証を実行して、Java言語仕様に準拠していないメタデータ情報がないことを確認することです。

バイトコードの検証

第3段階は、検証プロセス全体の中で最も複雑な段階です。主な目的は、データフローと制御フローの分析を通じて、プログラムのセマンティクスが合法かつ論理的であることを確認することです。第2段階では、メタデータ情報のデータ型を確認した後、この段階でクラスのメソッド本体に対して雇用分析を実行し、レスキューされたクラスのメソッドが実行時に危険にならないことを確認します。イベント、たとえば
1 。いつでもオペランドスタックのデータ型と命令コーディングを確認してください。シーケンスは連携して機能します。たとえば、同様の状況は発生しません。int型のデータをオペレーティングステーションに置き、使用される場合はlongに従ってローカル変数テーブルにロードします。
2.ジャンプ命令がメソッド本体の外部のバイトコード命令にジャンプしないことを確認します。
3.保証メソッドの重みのタイプステータスが有効です。たとえば、サブクラスオブジェクトを親データタイプに割り当てることができます。これは安全です。その時点で、親オブジェクトをこのデータ型に割り当てること、またはオブジェクトをそれに割り当てることでさえ、継承関係はなく、完全に無関係なデータ型です。これは危険で違法です。
クラスメソッド本体のバイトコードがバイトコード検証に合格しない場合は、問題があるはずです。ただし、メソッド本体がバイトコード検証に合格した場合、それが安全でなければならないという意味ではありません。コード検証に多くのチェックがあったとしても、これは保証できません。これには、離散数学でよく知られている問題である停止問題が含まれます。素人の言葉で言えば、データが完全に正確であることを確認してプログラムロジックを検証することは不可能であり、プログラムを介して限られた時間内にプログラムを完了できるかどうかを正確に確認することは不可能です。

データフロー検証の複雑さが非常に高いため、高速設計チームは、時間をかけすぎないようにするために、dk1.6の後の検証段階の後にcコンパイラとJava仮想マシンを追加して、のコードにワンクリック最適化を実行する方法を説明します。トピック属性。スティックマップテーブルという名前の属性が属性テーブルに追加されました。この属性は、メソッド本体のすべての基本ブロックを記述します。プロセスに従って、アンパックされたコードブロックはローカル変数テーブルとオペランドスタックを開始します。Yiyouのステータスは再びバインドされておらず、検証期間中にプログラムに従ってこのステータスの合法性を導き出す必要はありません。スティックメープルテーブル属性のレコードが正当かどうかを確認するだけです。これにより、検証のタイプがタイプチェックに直接変換され、時間を節約できます。

理論上のスティックマップテーブルの属性も間違っているか、改ざんされている可能性があります。したがって、コード属性を悪意を持って改ざんしているときに、対応するスティックマップテーブル属性を生成して、XunJiの心を騙す可能性はありますか。検証は、仮想マシンの設計者にとって検討する価値のある質問です

jdk1.6のホットスポットでは、仮想マシンは-XX:UseSplitveriferオプションを提供して、この最適化をオフにするか、パラメーターを使用します。-XX:FailOverToOldVerfierでは、型の検証が失敗したときに古い型に戻る必要があり、検証には控除方法が使用されます。この最初の1.7以降、メジャーバージョンが50を超えるクラスファイルの場合、タイプチェックを使用してデータフロー分析が完了します。検証は、型推定方法に戻れない唯一のオプションです。

シンボル参照の検証

検証の最終段階は、シンボル参照が直接参照に変換されるときに発生し、この変換アクションは、リンク解析フェーズの第3段階で発生します。シンボル参照の検証は、クラス自体以外の一致する情報と見なすことができます。テスト。通常、次の内容を確認する必要があり
ます。1。シンボルアプリケーションで、通常文字列で記述される完全修飾地名が対応するクラスを見つけるかどうか。
2.シンボリックメソッドのフィールド記述子と、指定されたクラスに単純なメーター長で記述されたメソッドとフィールドがあるかどうか。
3.シンボル参照のクラスフィールドメソッドcへのアクセスに、現在のクラスがアクセスできるかどうか

シンボル参照検証の目的は、解析アクションの正常な実行を保証することです。たとえば、シンボル参照検証に合格することはできません。次に、例外サブクラスがスローされます。
仮想マシンのクラスロードメカニズムにとって、検証フェーズは非常に重要ですが、必ずしも必要なフェーズではありません。実行されるすべてのコードが繰り返し使用および検証されている場合は、実装フェーズでパラメーターを検討できます-Xverify :仮想マシンクラスのロード時間を短縮するために、ほとんどの内部検査手段をオフにするハムスターはありません。

おすすめ

転載: blog.csdn.net/weixin_39472101/article/details/110308146