スタティック再コンパイルは、バイナリを外部アーキテクチャから別のターゲットアーキテクチャに変換する有望な方法です。ジャストインタイム(JIT)より高速です。なぜなら、実行する直前にコードをコンパイルする必要がなく、生成するコードを最適化するために余分なコンパイル時間が必要になるからです。
しかし、JITコンパイルは動的プログラム解析を使用し、静的再コンパイルは静的プログラム解析(したがって名前)に依存します。
静的解析では、実行時の実行時情報がありません。
これに関する大きな問題は間接ジャンプによって引き起こされます。この用語は、特定のswitch
文から生成される可能性のあるコード、関数ポインタの使用、または実行時の多型(think virtual table)からのコードを対象としています。 それはすべての形式の命令に沸く:
JMP reg_A
は、あなたがあなたのプログラムの開始アドレスを知っているとしましょう、そしてあなたは、この時点からの指示を再コンパイルし始めることを決めました。ダイレクトジャンプが発生すると、ターゲットアドレスに移動し、そこから再コンパイルを続行します。あなたが間接的なジャンプに遭遇したとき、あなたは立ち往生しています。 このアセンブリ命令では、
reg_A
の内容は静的にはわかりません。 したがって、次の命令のアドレスはわかりません。動的再コンパイルでは、レジスタの仮想状態をエミュレートするため、この問題は発生しません。現在の内容は
reg_A
です。さらに、静的な再コンパイルでは、すべての可能なパスをコンパイルする必要があるため、
reg_A
のすべてのの可能な値をこの時点で見つけることに興味があります。動的解析では、現在実行中のパスを生成するために現在の値のみを必要とします。
reg_A
はその値を変更する必要がありますが、他のパスを生成することはできます。 場合によっては、静的解析で候補リストを見つけることができます(
switch
の場合は、どこかにオフセットの可能性のあるテーブルが必要です)が、一般的にはわかりません。
ファインと言うと、は、バイナリ内のすべての手順を再コンパイルしましょう。
ここでの問題は、ほとんどのバイナリでコードとデータの両方が含まれていることです。 アーキテクチャによっては、どちらがどちらであるかを判断できない場合があります。
いくつかのアーキテクチャでは、配置制約と可変幅命令がなく、ある時点で逆アセンブルを開始し、オフセットを使って再コンパイルを開始したことを発見することができます。
のは2つの命令と単一レジスタA
を備えた単純化された命令セットを見てみましょう:
41 xx (size 2): Add xx to `A`.
42 (size 1): Increment `A` by one.
のは、以下のバイナリプログラムを見てみましょう:
41 42
はのは、開始点は、最初のバイト41
あるとしましょう。 あなたは実行します。
41 42 (size 2): Add 42 to `A`.
しかし、どのような41の場合は、データの一部はありますか?次に、あなたのプログラムは次のようになります。
42 (size 1): Increment `A` by one.
この問題は、多くの場合、アセンブリで直接最適化、およびプログラマは意図的expect some byte to be interpreted as both code and data, depending on the context!
さらに悪いことかもしれないし、古いゲーム、に拡大され、再コンパイルプログラムを生成することができコード自体! JITコンパイラの再コンパイルを想像してみてください。その結果、ソース・アーキテクチャー用のコードが出力され、そのファイルにジャンプしようとします。プログラムがすぐに終了する原因になります。実行時にのみ利用できるコードを静的に再コンパイルするには、無限のトリッキーが必要です!
スタティックバイナリ分析は、(主にセキュリティの分野で、ソースが利用できないシステムの脆弱性を探すための)研究の非常に活発な分野であり、実際にはNES emulator that tries to statically recompile programsを生成しようとしています。 記事は非常に興味深いです。
JITと静的再コンパイルの間の妥協点は、静的に変換できないビットのみを保持してできるだけ多くのコードを静的に再コンパイルすることです。
数回行っています。たとえば、DECのFX!32はx86バイナリを再コンパイルして、DEC Alpha上で動作します。 DECの(誤った)管理を補うだけでは不十分であり、Compaq/HPはそれについてはあまり気にしなかった。 –
エミュレータはなぜそうなのですか?これは本当にエミュレータを書くよりもはるかに難しいことですか? – user1483857