2012-04-25 1 views
18

「decompiling」という言葉は、以前は数回使用されていたと聞きましたが、その仕組みについて非常に不思議に思っています。デコンパイルはどのように機能しますか?

私はそれがどのように機能するかについて非常に一般的な考えがあります。アプリケーションをリバースエンジニアリングして、どの機能を使用しているかを確認しますが、それ以上のことはわかりません。

ディスアセンブラ」という言葉も聞いたことがありますが、逆アセンブラと逆コンパイラの違いは何ですか?

私の質問をまとめるには:何かを逆コンパイルのプロセスに正確に関与させますか?それは通常どのように行われますか?どのように複雑/簡単なプロセスですか?それは正確なコードを生成することはできますか?逆コンパイラと逆アセンブラの違いは何ですか?

+0

可能な複製[どのように非コンパイラですか?](http://stackoverflow.com/questions/2902074/what-is-a-de-compiler-how-does-it-work ) –

答えて

20

ここで現在最も優れたデコンパイラの1つは間違いなくHex-Rays Decompilerです。見たい場合は、出力できるものはhttp://www.hex-rays.com/products/decompiler/compare_vs_disassembly.shtmlです。これは、内のすべての困難が何であるかでの素敵な概要を説明しhttp://www.hex-rays.com/products/ida/support/ppt/decompilers_and_beyond.ppt:ここhttp://www.hex-rays.com/products/ida/support/ppt/decompilers_and_beyond_white_paper.pdfとプレゼンテーション:

その著者、イルファック・ギルファノーブは、ホワイトペーパーをいくつかの詐欺で彼の逆コンパイラの内部作業についてのスピーチを与えた、とここにありますデコンパイラを構築し、それをすべて動作させる方法。

これ以外にも、いくつかの非常に古い論文があります。 http://itee.uq.edu.au/~cristina/dcc.html#thesis

複雑さに関して、すべての「逆コンパイル」の内容は、バイナリの言語とランタイムによって異なります。たとえば、.NETとJavaの逆コンパイルは、利用可能なフリーデコンパイラがあるため、成功率が非常に高い(元のソースを生成する)ので、「完了」と見なされます。しかし、これは、これらのランタイムが使用する仮想マシンの非常に特殊な性質によって引き起こされます。

C、C++、Obj-C、Delphi、Pascalなどの本当にコンパイルされた言語については、タスクがはるかに複雑になります。詳細は上記の論文を読んでください。

逆アセンブラと逆コンパイラの違いは何ですか?

バイナリプログラム(実行可能ファイル、DLLライブラリなど)をお持ちの場合は、プロセッサの命令で構成されています。これらの命令の言語は、アセンブリ(またはアセンブラ)と呼ばれます。バイナリでは、これらの命令はバイナリ符号化されているため、プロセッサは直接命令を実行できます。 逆アセンブラはこのバイナリコードをテキスト表現に変換します。この変換は通常1対1であり、1つの命令が1行のテキストとして表示されます。このタスクは複雑ですが、単純ですが、プログラムはすべての異なる命令とそれらがバイナリでどのように表現されているかを知る必要があります。

一方、デコンパイラは、はるかに難しい作業です。バイナリコードまたは逆アセンブラ出力(1対1であるため、基本的に同じです)と高レベルのコードを生成します。私に例を示してみましょう。私たちは、このC関数を持っていると言う:あなたはそれをコンパイルすると

int twotimes(int a) { 
    return a * 2; 
} 

、コンパイラは最初にその関数のアセンブリファイルを生成し、、それは次のようになります。

_twotimes: 
    SHL EAX, 1 
    RET 

(最初の行SHLはシフト左演算を行います。これは2倍の速さで乗算され、RETはその関数が実行されたことを意味します)。結果バイナリでは、次のようになります。

08 6A CF 45 37 1A 

(これを実際のバイナリ命令ではありません)今度は、逆アセンブラがバイナリ形式からアセンブリ形式に変わることがわかりました。 デコンパイラーは、Cコード(またはその他の高水準言語)に移動します。

3

逆コンパイルは、本質的にコンパイルの逆です。つまり、オブジェクトコード(バイナリ)を取得し、そこからソースコードを再作成しようとしています。

逆コンパイルは、ソースコードの構造を確認するために使用できるオブジェクトコードに残されているアーティファクトに依存します。

C/C++では、逆コンパイル処理を支援する余裕はあまりありません。そのため、非常に難しいです。しかし、JavaやC#などの仮想マシンをターゲットとした他の言語では、オブジェクトコード内に多くのヒントが残るため、逆コンパイルが容易になります。

+0

誰もが "難しい"と言っていますが、それはいつでも可能ですか? –

+1

@MarcoPrins:Hexraysによれば、一般的には、自動的には常に自動的には可能ではありません。コンパイルのガイドラインについての前提がなければなりません(一般的なコンパイラが使われていて、いくつかの奇妙な特別な非標準化されたハック実装や "悪い"手作りアセンブリではありません)。 – BullyWiiPlaza

0

ところで、あなたは enter link description here ここで逆コンパイラの仕事についていくつかの情報を得ることができます(PowerPCプロセッサ用)逆コンパイラのオンライン版は、プロIDAの表記でアセンブラコードを取得すること、があります。 しかし、サービスは、次の生成し、「中間表現をする」のオプションがあります。

  • 入力コード(テキスト)
  • ソースコードの抽象シンテックス(木)BasicBlock形式(グラフ)で
  • コールグラフ
  • 入りBasicBlock形態で
    • コールグラフ(グラフ)レジスタの値の
    • データフロー(グラフ):
    • Metainformationsは、逆コンパイル中thatsの復元されました
    • 変数の値のデータフロー式の依存性の(グラフ)
    • データフロー(グラフ)
  • Nassi-Shneiderman図(ツリー+グラフ)
  • 構造Nassi-Shneiderman図(ツリー+グラフ)
  • アルゴリズム(一部のような逆コンパイル)
  • いくつかの他...
  • として
  • 最適Nassi-Shneiderman図(ツリー+グラフ)
  • ソースコード記述

このサービスは、デコンパイラの実験と理解に役立ちます。

BTW。 逆アセンブラ:バイナリ・マシン・コード - >アセンブラ・テキスト 逆コンパイラ:アセンブラ・テキスト - >高級言語でのソースのバージョン(c、C++、cの拡張子など))

関連する問題