何かの仕組みを分解して、その仕組みを知りたくなったことはありませんか? まあ、ない人はないでしょう。 その欲求こそが、リバースエンジニアリングの原動力なのです。 このスキルは、製品のセキュリティを分析したり、怪しい .exe ファイルを実行せずにその目的を突き止めたり、失われたドキュメントを復元したり、レガシーソフトウェアに基づく新しいソリューションを開発したりするのに役立ちます。

この記事では、リバース エンジニアリングを行うために必要な知識ベース、Windows ソフトウェアの一部をリバース エンジニアする基本原則、ディスアセンブラ、およびツールについて説明しています。 また、アプリケーションのリバースエンジニアリングのステップバイステップの例も提供します。

Written by

Development Coordinator,

Network Security Team

and

Anton Kukoba,

セキュリティ研究リーダー

コンテンツ

ソフトウェアリバースって何ですか?

リバースエンジニアリングに必要なものは?

理論的な知識。 ソフトウェアリバースエンジニアリングのプロセス

リバースエンジニアリングに役立つツール

ディスアセンブラ

ネットワーク監視ツール

デバッガ

実機での使用例

Windowsソフトウェア

Windowsソフトウェア

ドライバのリバースエンジニアリング方法

まとめ

ソフトウェアリバースとは何か?

リバース エンジニアリングとは、ハードウェアまたはソフトウェアのアーキテクチャや内部構造など、その背後にある原理を明らかにするプロセスです。 リバース エンジニアリングの原動力となる質問は、「どのように動作するか」です。

当然ながら、ドキュメントがあれば、プロセス全体がはるかに簡単になります。 しかし、ドキュメントがないこともよくあり、ソフトウェアがどのように動作するかを知るために別の方法を見つける必要があります。

どのような場合にソフトウェアの一部をリバース エンジニアする必要があり、そうすることでどのように役に立つのでしょうか。

  • ネットワーク通信プロトコルの研究
  • コンピューター ウィルス、トロイの木馬、ランサムウェアなどのマルウェアに使用されているアルゴリズムの発見。
  • E メールデータベースやディスクイメージなど、あらゆる種類の情報を保存するために使用されるファイルフォーマットの調査
  • 自社のソフトウェアがリバースエンジニアリングに耐えられるか確認する
  • プラットフォームやサードパーティ製ソフトウェアとのソフトウェア互換性の向上
  • 文書化されていないプラットフォーム機能を使用する

リバースエンジニアの合法性はその目的とソフトウェアの使用方法次第といえます。 あなたがソフトウェアのコピーを合法的に入手したと仮定すれば、上記の目的はすべて完全に合法的です。 しかし、例えば、閉じたアプリケーションのある機能をリバースエンジニアリングし、それを別のアプリケーションに実装するつもりであれば、おそらくトラブルに巻き込まれるでしょう。

法的文書については、リバースエンジニアリングはエンドユーザー・ライセンス契約 (EULA) によってしばしば禁止されています。 しかし、米国のデジタルミレニアム著作権法では、他の製品との互換性を向上させるためにソフトウェアの一部をリバースエンジニアリングすることは合法であると明記しています。

リバースエンジニアリングに必要なもの

ソフトウェアのリバースエンジニアリングを始めるには、以下のものが必要です:

  1. リバースエンジニアリングを適用したい分野の知識
  2. ソフトウェアの分解を試みる際に知識を適用できるツール

ソフトウェアとは関係ない一般的な例も考えてみましょう。

この分野の知識があるということは、時計には3つのタイプがあることを知っているはずです。 さらに、電池があれば、それは時計の内部にあり、あなたがそれを開く場合は、それを見ることができることを知っている必要があります。 さらに、時計の内部構造、電池の形状、ケースを開けるための道具など、基本的な知識も必要です。 知識を応用するための道具を持つということは、ドライバーなど、時計を開けるきっかけとなる専用の道具が必要ということです。

時計のリバースエンジニアリングに特定のスキルセットと道具が必要なように、ソフトウェアのリバースエンジニアリングにはその分野特有の知識と道具が必要です。

理論的な知識です。 ソフトウェア リバース エンジニアリング プロセス

異なるソフトウェア リバース エンジニアリングのタスクには、異なるタイプの知識が必要です。 もちろん、一般的なアプリケーション構造、プログラミング言語、コンパイラなどの知識など、ほとんどのリバースエンジニアリング作業に役立つ共通の知識は存在します。

If you…

You need knowledge of…If you need of…

あらゆるネットワーク アプリケーションのリバース エンジニアリング

プロセス間通信の原理、ネットワークの構造、接続、ネットワーク パケットなどです。

暗号アルゴリズムの逆引き

暗号とその分野で使用される最も人気のあるアルゴリズム

調査ファイル 構造

基本的なファイルの概念と、異なるシステムやコンポーネントがファイルをどのように扱うか

特別なタイプのソフトウェアをリバースする際に、特別なテクニックで時間を大幅に節約することが可能です。 ファイルの相互作用の場合、実際のストレージ ファイルにオフセットとデータ サイズを記録しながら、ユニークなタイプの値をファイルに書き込むテストを作ると、オフセットの共通パターンを見つけるのに役立つかもしれません。 これは、これらのファイルの内部構造についてのヒントになります。

リバースエンジニアリングのプロセスを開始するとき、ソフトウェア開発者は一般に、アルゴリズムとプログラムロジックを適所で見つけるためにディスアセンブラを使用します。 多くの異なる実行ファイル形式、コンパイラ (異なる出力を与える)、およびオペレーティング システムが存在します。 この技術の多様性により、すべてのタイプのソフトウェアを逆引きするために 1 つの技術を使用することはできません。

逆コンパイルされたコードを理解するには、アセンブラ言語、関数呼び出し規則、スタック構造、スタック フレームの概念などについてのある程度の知識が必要です。 Windows x86 プラットフォームのいくつかの例を考えてみましょう。

int count = 0;for (int i = 0; i < 10; ++i){count++;}std::cout << count;

このコードを実行可能ファイルにコンパイルすると、ディスアセンブラではこのように表示されます:

004113DE loc_4113DE:004113DE mov eax, 004113E1 add eax, 1004113E4 mov , eax004113E7 loc_4113E7:004113E7 cmp , 0Ah004113EB jge short loc_4113F8004113ED mov eax, 004113F0 add eax, 1004113F3 mov , eax004113F6 jmp short loc_4113DE004113F8 loc_4113F8:004113F8 mov ecx, ds:004113FE push eax00411400 call ds:<<(int)00411404 xor eax, eax00411406 retn 

ご覧のように、通常のサイクルは比較とジャンプを含むアセンブリ コードに変わりました。 このアセンブリコードでは、ecxレジスタにカウンタを持つ通常のアセンブリループは使用されていないことに注意してください。 さらに、ここでのローカル変数は、適宜、and として参照されます。

このコードをリリース ビルドを使用してコンパイルするとどうなるか見てみましょう:

00401000 main proc near00401000 mov ecx, ds:00401006 push 0Ah00401008 call ds:<<(int)0040100E xor eax, eax00401010 retn00401010 main endp

このコード片は、前とは全く違って見えます。 これは、コードがどのように最適化されたかによるものです。 技術的には、count 変数を 10 に増加させる以外に価値のあることは何もしていないので、ループは削除されました。 そこで、オプティマイザーは count 変数の最終値を保持し、その値を count 出力演算子の引数として直接配置することにしました。 そのため、リバースエンジニアリングを行う際には、元のコードそのものを取得しようとするのではなく、コードの背後にある考え方(コードの原理)を理解した方が良いのです。

異なる演算子、構造体、およびその他の言語構造をコンパイルした場合に、どのようなアセンブリコードが得られるかを知ることは非常に有用でしょう。 結果のアセンブリ コードを理解することは、C++ のリバース エンジニアリング プロセスを開始する良い方法ですが、ここではその技術的な詳細には触れません。

Windows ソフトウェアのリバース エンジニアリングに役立つツール

ProcessMonitor や ProcessExplorer など、いくつかのリバース エンジニアリング ツールについては、アプリケーション アーキテクチャ研究の中ですでに説明しています。 これらのツールはリバースエンジニアリングには絶対に欠かせません。

このセクションでは、最も人気のあるディスアセンブラと、私たちがリバースエンジニアリングプロジェクトで使用している他のいくつかのツールについてレビューします。

ディスアセンブラ

ディスアセンブラとは、実行可能ファイルをアセンブリ言語に変換するプログラムです。 最もポピュラーなのはIDA Pro

IDA Pro

IDA Proはディスアセンブリのための便利で強力なツールである。 ソフトウェアの一部をすばやく分解することができる膨大な数の機器を備えています。 関数コールツリーを表示したり、実行ファイルのインポートおよびエクスポートを解析したり、それらに関する情報を表示したりすることができます。 また、複数のCPUアーキテクチャをサポートしているので、IDA Proを使ってARM、AVR、M68k、および他の多くのアーキテクチャのコードをリバースエンジニアリングすることが可能です。

Radare

Radare

RadareディスアセンブラはIDAに代わるものです。 基本的には IDA の機能をすべて備えていますが、 それほど堅牢でも安定でもありません。 しかし、それはフリーでオープンソースです。 Radare 自体はコンソールツールですが、Cutter フロントエンドを備えており、IDA の真の代替となります。

Windows Sysinternals

Windows Sysinternals ユーティリティは、一般に Microsoft Windows 環境の管理、診断、トラブルシューティングおよび監視に使用されます。

TCPViewは、すべてのプロセスからのTCP/UDPパケットに関するすべての情報を表示するネットワークスニファです。 このツールは、ネットワークプロトコルをリバースするのに便利です。

PortMon は、物理システムのポートモニタです。 シリアルおよびパラレル・ポートと、それらを通過するすべてのトラフィックを監視します。

WinObjは、階層構造でシステムのすべてのグローバル・オブジェクトを表示します。 このツールは、ミューテックスやセマフォのような同期プリミティブで動作するアプリケーションをリバースするときや、カーネルモードドライバをリバースエンジニアリングするときに便利です。 ネットワークトラフィックをキャプチャできるだけでなく、イーサネット、TCP、IP のような本当に低レベルのものから、WebSocket や XMPP のようなアプリケーション固有のプロトコルまで、さまざまなネットワークプロトコル用のパーサを含んでいます。 Wiresharkとは異なり、個別のネットワークパケットではなく、HTTPセッションを表示します。 Fiddler はまた、HTTP で送信された圧縮データを分析し、SOAP、REST、および AJAX リクエストを監視する際に JSON および XML データを分析できます。

API Monitor

API Monitor

API Monitor はアプリケーションによってどの API が呼ばれ、アプリケーションがそれらの API からどんな動作を期待しているかを検出するのに役立つツールです。 このツールは強力なデータベースを持ち、kernel32 や ntdll だけでなく、COM やマネージド環境など、膨大な数の API 関数の呼び出しを確認することができます。 また、API Monitor は便利なフィルタリング機構を提供します。

デバッガ

デバッガは、プログラムが今何を行っているかを確認できる、開発者にとっては非常に貴重なものです。 アプリケーションをリバースする際のデバッグから、ライブアプリケーションのデバッグから得られるのと同じ利益を得ることができます。

最も人気のあるデバッガは OllyDbg、WinDbg、および Windbg Preview です。

OllyDbg

OllyDBG

OllyDbg (とその後継 x64dbg) はおそらくソフトウェアのリバースエンジニアリングを考える上で最高のデバッガーと言えるでしょう。 特にリバースエンジニアリングのニーズに合わせて開発され、その目的に必要なすべてのツールを備えています。

  • 重要なデータ構造を分析および識別する能力を備えた組み込みのディスアセンブラ
  • インポートとエクスポート分析機能
  • 組立てとパッチの組み込みエンジン

API 関数とそのパラメータを解析する能力により、システムとの相互作用を簡単に逆行できます。 スタックビューは、コールスタックに関する多くの情報を提供します。 9261>

WinDbg

Windbg

シンプルなインターフェースにもかかわらず、WinDbg にはデバッグのための強力なツールがあります。 組み込みのディスアセンブラ、デバッグ中のプロセス/システムに関するほとんどすべての情報を知ることができるさまざまなコマンド、そしておそらく最も価値のある機能であるカーネルモードデバッグを行う機能を備えています。 特にカーネルモードドライバをリバースする際に大きな利点となります。

Windbg Preview

Windbg Preview

Windbg PreviewはMicrosoftが開発したWindbgの新しいバージョンです。 Windows ストア経由でのみ配布されています。 従来の Windbg のすべての機能と、新しい UI およびいくつかの新機能を併せ持っています。 これらの新機能の1つはタイムトラベルデバッグで、プログラムの実行を一定期間記録し、それを何度でも再生することができる。 この方法では、誤ってコードを実行して文脈やすべてのデータを失うことを恐れることなく、コードの興味深い部分を段階的に実行することができます。
9 Best Reverse Engineering Tools for 2018

Real-life software reverse engineering example

では、ソフトウェアの一部をリバース エンジニアする方法の例を見ていきましょう。 疑わしい実行可能ファイルがあることを想像してみましょう。 このプログラムが何をするのか、ユーザーにとって安全かどうかを調べる必要があります。

このシナリオを考慮すると、この実行ファイルを仕事用のコンピューターで実行せず、代わりに仮想マシンを使用するのがよい考えと言えます。 それでは、仮想マシンでアプリケーションを起動してみましょう。

Process creates service

見てわかるように、このファイルはTestDriverというWindowsサービスを作成します。 これは、タイプが kernel であるため、ドライバであることがわかります。 しかし、実行するために、どこからドライバファイルを取得するのでしょうか? Sysinternals SuiteのProcessMonitorを使えば、それを知ることができます。 ProcessMonitorを開くと、フィルタを設定して、興味のあるプロセスのファイルアクティビティだけを表示させることができる。 その活動ログは次のようになります:

FileMon information

ドライバー ファイルは、逆引きしているプロセスによって作成され、このプロセスはこのファイルをユーザーの一時ディレクトリに配置します。 プロセスが使用後すぐに削除することが確認されているため、temp フォルダでファイルを探す必要はありません。 では、プロセスはこのファイルをどうするのでしょうか。 もしファイルを解凍したら、プロセスのリソースセクションでそのファイルを探すことができます。 そこを見てみましょう。 リソースを調べるために、別のツール – Resource Hacker – を使ってみましょう。

Examine resources with Resource Hacker

ビンゴ!を実行します。 見つかったリソースの内容からわかるように、MZ署名で始まり、”This program cannot be run in DOS mode” という文字列があるので、これはおそらくWindowsの実行ファイルでしょう。 それが私たちのドライバファイルであるかどうか確認してみましょう。 そのために、Resource Hackerを使ってリソースを抽出し、ディスアセンブラで開きます。

ディスアセンブラ画面

ご存知のように、DriverEntryはWindowsシステムにおけるカーネルモードドライバのエントリポイントです。 正しいドライバーを見つけたようなので、調査を続けることができます。

ドライバーのリバース エンジニアリング方法

ドライバーのリバース エンジニアリングを開始するには、DriverEntry から呼び出される関数を 1 つずつ調べます。 sub_14005まで行っても面白いものは見つからないので、sub_110F0まで続けて、このコードを見つけます。

コード1

コード2

コード3

コード4

ここでは簡略化のため一部の行は省略されています。

最初のリストでは、ユニコード文字列が作成され、この文字列はパス C:\hello.txt を指しています。 その後、OBJECT_ATTRIBUTES 構造体に通常の値が入力されます。この構造体は、ZwCreateFile などの関数を呼び出すときによく必要になることがわかっています。

2番目のリストでは、ZwCreateFile が実際に呼び出されており、ドライバーがファイルを作成し、作成後のファイルがどこにあるかがわかっています。

3番目と4番目のリストから、ドライバがユニコード文字列を受け取り、それをバッファに書き込み(これは sub_11150 関数で発生します)、バッファは ZwWriteFile 関数を使用してファイルに書き込まれることがわかります。 最後に、ドライバは ZwClose API を使用してファイルを閉じます。

最後にまとめましょう。 元のプログラムは、リソースからドライバファイルを取り出し、カレントユーザーのtempフォルダに置き、このドライバのWindowsサービスを作成し、実行していることがわかりました。 その後、プログラムは停止し、tempディレクトリからサービスと元のドライバファイルを削除します。 この動作と逆アセンブルの分析から、ドライバは C ドライブに hello.txt というファイルを作成し、”Hello from driver” という文字列を書き込む以外は何もしていないようです。

さて、正しいかどうかを確認する必要があります。 プログラムを実行し、Cドライブを確認してみましょう。

アプリケーション画面

Wonderful! この単純なプログラムをリバース エンジニアリングし、使用しても安全であることがわかりました。

デバッグまたは API Mon の使用、テストの記述など、さまざまな方法でこの結果を達成できたはずです。 9261>

まとめ

Windows ソフトウェアのリバース エンジニアリングには、確かな学歴とプログラミングの経験が必要です。 リバースエンジニアリングを行うには、逆アセンブル、ネットワーク監視、デバッグ、API統合、いくつかのプログラム言語、コンパイラーなどのスキルを組み合わせる必要があります。 また、ソフトウェアをリバースする際には、著作権法を破ったり、システムに損害を与えたりしないよう、細心の注意が必要です。

Aprioritでは、経験豊富なリバースエンジニアチームを擁しています。 もしあなたがリバースエンジニアリングの技術をプロジェクトに適用したいのであれば、お気軽にご連絡ください!

コメントを残す

メールアドレスが公開されることはありません。