Python3 の場合、これまでのところ、安定して動作する逆コンパイラはありません。最も近いのは unpyc3 で、せいぜいバグがあります。Python で動作する逆コンパイラを作成したいのですが、どうすればよいでしょうか? Python で作成したいのですが、すべての言語で動作するグローバル逆コンパイラを使用することは可能ですか? プログラムが特定の言語のすべてのライブラリにアクセスでき、コンパイルされたファイルが与えられた場合、コンピューターはそれを任意の言語に分割できますか? 機械語で動作しているので、これは逆コンパイルで問題になるのでしょうか?
1 に答える
uncompyle6は非常に優れており、Python 3 で動作します。
これを一般的に行うための書き方に関する質問については、その仕組みを説明しているwiki を参照してください。
ただし、以下の手順の概要を説明します。
最初に、特定の CPU タイプのマシン コードまたは仮想マシンのバイトコードを含む「実行可能ファイル」を読み取る方法を理解する必要があります。Uncompyle6は、文法を使用してプログラムを再構築します。逆アセンブルされた機械語命令は、構文解析用語で「トークン」と呼ばれます。たとえば、「token: number with value 5」の代わりに、「LOAD_CONST
instruction with value 5」になります。
この後、おそらく制御フローを理解したいでしょう。そのために、通常は基本的なブロック、つまり直線コードが決定されます。どのトークンがジャンプ命令であるかを理解しているので、これを行うことができます。
uncompyle6 が使用する基本的な考え方は、文法にトークンを追加して、文法が制御フローを検出できるようにすることです。したがって、大まかに次のように表示されます。
SETUP_LOOP
JUMP_IF FALSE X
...
X:
X に何かを追加して、それが終わりであることを示します。
SETUP_LOOP
JUMP_IF_FALSE X
...
COME_FROM_LOOP # this is added
次に、各基本ブロック内で、基本ブロック内の式とステートメントの抽象構文ツリー (AST) を構築できます。uncompyle6で使用されるアプローチは、文脈自由文法を使用することです。pycdcや引用したプログラムunpyc3などの他の Python3 プログラムは、それを行いません。代わりに、スタックと命令の線形スキャンを使用してツリーを構築します。これについて何らかの考えを与えるために
LOAD a # tree/stack: | a
LOAD b # tree/stack: | b, a
LOAD c # tree/stack: | c, b, a
ADD # tree/stack: (c + b) | a
MULTIPLY # tree/stack: (c + b) * a
STORE d # tree/stack: d = (c + b) * a |
おそらく、文法が同じことをどのように行うかを見ることができます。
これを言ってuncompyle6を提案すると、現在のところ、主にアドホックな制御フロー分析部分がかなり弱いと言えます。
あなたは逆コンパイラの作成に興味を示しているので、代わりに既存のコンパイラを改善するために貢献してみませんか?