2012-04-19 6 views
5

今日、Visual C++で書かれた簡単な「Hello world」プログラムをIDA Proを使って逆コンパイルすることにしました。リバースエンジニアリングC++

私の知る限りでは、実行可能なエントリポイントでprintfをすぐに呼び出すことができないと確信していました。 コンパイルプロセス中に私によって書かれずにコンパイラによって追加された多くのコードが見つかりました。

コンパイルプロセス中にどのコードが追加されたかをよりよく理解したいと思います。 どうしますか? "main"をすばやく見つけ出し、逆アセンブリによって生成された不要なコードをすべてスキップする "トリック"はありますか?

私はこの記事にあった見つけることができる最高: http://www.codeproject.com/Articles/4210/C-Reverse-Disassembly、 は、次のようにVisual C++を使用してコンパイルされた実行可能の実行順序があると言って:

  • メイン

    1. CrtlStartUpを

    2. CrtlCleanUp

    もっと詳しい回答がありますか?

  • +5

    非常にコンパイラとプラットフォーム固有です。私は、あなたが望む正確な答えを得ることは疑う。 – Matt

    +1

    リバース・エンジニア・ガー・ウィナビーの方にロードマップとして[この記事](http://stackoverflow.com/a/9952374/176769)をお勧めします。 – karlphillip

    +1

    リバースエンジニアリングの経験はありませんが、メインアドレスの先頭にデバッガのブレークポイントを設定して相対アドレスを取得することはできませんでしたか?あるいは、実行可能ファイルのオブジェクトダンプをメインで検索しますか? – bjhend

    答えて

    4

    おそらく遭遇するであろうC++標準には、さまざまなことがあります。

    最も重要なのは、mainが呼び出される前にメイン翻訳ユニット内のスタティックの構造を処理するコードと、そのメインの葉の後にその破壊を処理する関数が必要であるということです。さらに、標準では、メインの戻り値の後に呼び出される追加の関数を登録できるようにする関数atexitが必要です。

    少なくとも、スタートアップコードは、メインからの復帰時に呼び出される関数のこのデータ構造を構築できる必要があります。これは動的なデータ構造です。なぜなら、プログラムによって実行時に追加される必要があり、呼び出しの順番は登録の反対です(通常は、簡単に歩く場所に追加するデータ構造が必要です)。

    さらに、標準では、その翻訳単位で機能が実行される前に他の翻訳単位の統計情報が作成されている必要があります。多くの場合、コンパイラはリンカの中のすべてを整理してmainの前に呼び出されますが、それは必須ではありません。異なることを行うコンパイラは、最初の関数呼び出し時に呼び出される他の翻訳単位コードの初期化ルーチンにサンクを提供する必要があります。

    標準ライブラリを使用している場合は、ちょっとした作業です。 std :: coutは静的オブジェクト(静的な生存期間ではなく、静的なリンケージではありません。つまり、あなたのコンソールへの通信を構築することです。あなたのコンソールに必要なAPIがあればそれが呼び出されます。このような多くのオブジェクトが標準にあります。

    あなたのプラットフォームやコンパイラには、プロセスをいくつかの便利な方法で準備したり、環境変数を解析したり、 "標準の"動的/共有ライブラリなどを読み込むものがあるかもしれません。

    通常、exitはそのリストを歩いていて、mainの戻り値を何らかの形で環境に提供しています。ほとんどの最新のOSはそれ自身の後でクリーンアップするためですが、それに加えてシステム固有のものがあるかもしれません。

    2

    今日のコンパイラでは大量の実行可能ファイルが作成されるため、たとえエントリポイントが見つかったとしても、理解して実際に必要なセクションに到達するまでには時間がかかります。

    あなたのケースでは、IDAの関数リストダイアログでエントリポイントを見つけることができます(私は正確な名前は覚えていません)。しかし、もう一度私はこのアプローチをお勧めしませんが、appが非常に小さい場合を除きます。

    私は、私はすべてのツールを伴うことなく、アプリケーションの現在の行動を分析することから開始する

    (c)は「トップダウンアプローチに」呼んで使っていたアプローチ。あなたが何を探しているのか、それがいつ起こるのかを知るように、時間を大幅に節約することは非常に重要なステップです。その後、静的解析ツール(IDA)で見つけることができる定数値である文字列のような「弱点」を特定します。

    次のステップは、

    アプリを分解し、その後、彼らは(あなたが新しいIDAのバージョンではグラフィックス階層ビューを使用することができます)に使用される機能何からそれらへの参照を見つけるそれらの「弱点」(IDA内の文字列モジュール)を探すことです

    あなたはまだそれがどのように動作しているか、または多くの場所から呼び出されたこのコードを得ることができない場合は、あなたが必要なものを知らない。ランタイム解析から始めて、ollydbgのようなデバッガ(softice?:)を使うことができます。これは仮想関数/関数ポインタのような静的解析では見えないものを表示します:例えばEAXを呼び出します。

    次に、必要なものが得られるまで段階的に処理します。

    関連する問題