5

今日、IDA Pro を使用して、ビジュアル C++ で記述された単純な「Hello world」プログラムを逆コンパイルすることにしました。

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

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

私が見つけた最高のものは、http: //www.codeproject.com/Articles/4210/C-Reverse-Disassemblyの投稿で、Visual C++ を使用してコンパイルされた実行可能ファイルの実行順序は次のとおりであると述べています。

  1. CrtlStartUp

  2. 主要

  3. Crtlクリーンアップ

より詳細な回答をいただけますか?

4

2 に答える 2

4

遭遇する可能性が高い C++ 標準で必要とされるさまざまなものがあります。

最も重要なことは、main が呼び出される前にメインの変換単位で static の構築を処理するコードと、main が終了した後にそれらの破棄を処理する関数が必要であるということです。さらに、標準では、atexitメインが戻った後に呼び出される追加の関数を登録できる関数が必要です。

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

さらに、標準では、その翻訳単位で関数が実行される前に、他の翻訳単位の静的変数を作成する必要があります。多くの場合、コンパイラはリンカー内のすべてを単純に配置して、すべてがメインの前に呼び出されるようにしますが、それは必須ではありません。異なることを行うコンパイラは、最初の関数呼び出しで呼び出されるリンクされた他の翻訳単位コードの初期化ルーチンにサンクを提供する必要があります。

標準ライブラリを使用する場合、これだけでもかなりの作業です。std::cout は静的オブジェクトであることを思い出してください (静的リンケージではなく、静的ライフタイム - 紛らわしいオーバーロードされた単語アラート)。つまり、コンソールへの通信を構築することを意味し、プラットフォームが必要とする API が呼び出されます。標準には、そのようなオブジェクトが多数あります。

次に、プラットフォームやコンパイラに固有のもので、何らかの有用な方法でプロセスを準備したり、環境変数を解析したり、「標準」の動的/共有ライブラリをロードしたり、同様のものをロードしたりすることがあります。

通常、終了はそのリストをたどり、何らかの方法で main の戻り値を環境に提供します。これは、最近のほとんどの OS が自分でクリーンアップするためですが、それに加えてシステム固有のものがある場合があります。

于 2012-04-19T17:10:33.063 に答える
2

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

Hello World アプリの場合、関数リスト ダイアログで IDA find entry point を使用できます (正確な名前は覚えていません)。ただし、アプリが非常に小さい場合を除き、このアプローチはお勧めしません。

私が使用しているアプローチは、「ダウン ツー トップ アプローチ」と呼んでいます (c)

ツールを使用せずに、アプリケーションの現在の動作を分析することから始めます。これは非常に重要なステップであり、何を探しているのか、いつそれが発生するのかがわかるため、多くの時間を節約できます。次に、静的分析ツール (IDA) で見つけることができる文字列、定数値などの「弱点」を特定します。

次のステップは、アプリを逆アセンブルし、それらの「弱点」(IDA の文字列モジュール) を探し、それらが使用した関数からそれらへの参照を見つけることです (新しい IDA バージョンではグラフィック階層ビューを使用できます)。

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

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

于 2012-04-19T17:46:04.713 に答える