wivern ロゴ

サイバーセキュリティ研究所

サイバーセキュリティを中心に、軍事、防犯、サーバーの管理と監視、その他、最新技術を研究しています。


「たのしいバイナリの歩き方」勉強メモ#2

シューティングゲームをチートから守るには

「たのしいバイナリの歩き方」#2

前回に続き、「たのしいバイナリの歩き方」の勉強メモ第2弾です。
実行環境は、Windows7(64bit版)です。

2.1 メモリダンプを読み解く
汎用プロセスメモリエディタ「うさみみハリケーン」Ver 0.18
http://hp.vector.co.jp/authors/VA028184/#TOOL
http://www.vector.co.jp/soft/win95/prog/se375830.html

メモリダンプ:メモリ上のデータをファイルにする
手順:① Ctrl+Alt+Delete でタスクマネージャを起動
   ②該当するプロセスを右クリック
   ③「ダンプファイルの作成」を選択
   →C:\Users\ユーザー名\AppData\Local\Temp\shooting.DMP が作成される

OS(ローダー)は、実行ファイルを元にプログラムをメモリ上へロードするが、メモリ上にあるデータは実行ファイルと全く同じではない。

Windows には Just-In-Time デバッグという機能があり、プロセスが継続不能なエラーによって終了した場合に、自動的にデバッガが立ち上がり、そのプロセスへアタッチするよう設定できる。

「Just-In-Time Debugging in Visual Studio (Visual Studio での Just-In-Time デバッグ)」 http://msdn.microsoft.com/ja-jp/library/5hs4b7a6.aspx

Just-In-Time デバッグの有効化/無効化は、レジストリで設定できる。

Visual Studio 2010 がインストールされた状態でレジストリは以下のようになっていた。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger : REG_SZ : "C:\Windows\system32\vsjitdebugger.exe" -p %ld -e %ld

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
Debugger : REG_SZ : "C:\Windows\system32\vsjitdebugger.exe" -p %ld -e %ld
ここにデバッガのパスを入れておけば、Just-In-Time デバッグ時に、任意のデバッガ(OllyDbg等)を利用できる。
OllyDbg は、オプション→ジャストインタイムデバッグを選択すると、設定用のウィンドウが表示されるので、レジストリを直接書き換える必要はない。

ダンプファイルは、WinDbg で解析できる。

WinDbg のショートカット
 Ctrl + D:クラッシュダンプファイルを開く
 Alt + 4:レジスタウィンドウを表示
 Alt + 5:メモリウィンドウを表示
 Alt + 6:Call Stack ウィンドウを表示
 Alt + 7:Disassembly ウィンドウを表示

P.90~91
Call Stack ウィンドウでダブルクリックしても、逆アセンブルが表示されませんでした。
なので、これ以降の内容は確認できませんでした。
コラム:パソコン以外のコンピュータを解析することはできるのか
devkitpro
http://devkitpro.org/

コラム:Java 製アプリを解析するには
逆コンパイラ(デコンパイラ):バイトコード(中間言語)を元々のソースコードに戻すツール
Java デコンパイラ
http://java.decompiler.free.fr/
↓こっちに移転してました
http://jd.benow.ca/
2.2 動作を解析されないようにするには
デバッガでアタッチされていることを検知する API 関数
 IsDebuggerPresent
 CheckRemoteDebuggerPresent

コラム:デバッグを検知するさまざまな方法
popf と SINGLE_STEP 例外を利用したデバッガ検出手法
int 2dh を利用したデバッガ検出手法

[参考資料]
マルウェアの解析対策を無効にするAnti-Anti-Debuggingツールを開発
http://itpro.nikkeibp.co.jp/article/Watcher/20071119/287574/

"Windows Anti-Debug Reference(英文)"
http://www.securityfocus.com/infocus/1893
デバッガ対策は、逆アセンブラで静的に解析されたり、デバッガで先頭から処理を追えば、検知箇所を特定されて、かんたんに潰される。

難読化:コードを読めないようにすること
[例]余計なマシン語1バイトを付加して、逆アセンブル結果を別のモノしてしまう。
  →コード自体の処理は何も変わらない

コラム:難読化に関する話題
Obfuscation of Executable Code to Improve Resistance to Static Disassembly
http://www.cs.arizona.edu/solar/papers/CCS2003.pdf

Binary Obfuscation Using Signals
http://www.cs.arizona.edu/solar/papers/obf-signal.pdf

耐タンパー制:システムの内部構造がどれだけ解析しにくいか

パッカー(Packer):実行ファイルを実行できる状態で圧縮することで解析を防ぐソフト

 UPX:http://upx.sourceforge.net/
  オープンソース。
  元々の実行ファイル内のコードやデータを圧縮し、それを展開するコードを先頭に付加して、あらたな実行ファイルとして出力するだけ。

 ASPack:http://www.aspack.com/
  圧縮ではなく、アンチデバッギング(リバースエンジニアリング)を目的としたパッカー。
  P2Pファイル交換ソフト Winny で使われた。

 現在のパッカーは、ほとんどの場合において、リバースエンジニアリング対策としての機能を持つ。
 そのため、マルウェア製作者がアンチウィルスベンダーの解析を遅らせるため、またはシグネチャを変更するために、パッカーを用いたりもする。

アンパッカー(Unpacker):パッカーで圧縮された実行ファイルを展開するツール
 UPX であれば、「UPX -d」で展開できる。
 UPX は別として、基本的にリバースエンジニアリング対策として作成されたパッカーには、公式なアンパッカーは存在しない。

OllyDump
http://www.openrce.org/downloads/details/108/OllyDump

メニュー:プラグイン→OllyDump→Dump debugged process

最初の pushad と popad に挟まれた処理が展開ルーチン。
(パックされた実行ファイルは)必ずどこかのタイミングで展開ルーチンが終わり、本処理へ進む。
手動アンパックとは「展開ルーチンが終わる瞬間(箇所)を見つける作業」。

ASPack のフリー版(試用版)の試用期間は、30日間。
ソフトウェアブレイクポイント
 デバッガが該当アドレスの命令を 0xCC(int3h) に書き換える。
 プロセッサは「0xCC という命令を見つけたら、OS をとおしてデバッガに例外を通知する」という仕組み
 ユーザーの気のすむまでセットできる

ハードウェアブレイクポイント
 0xCC ではなく、止めてほしいアドレスを、直接 DR レジスタに書き込む。
 「このアドレスに書き込みが起こったら停止させる」
 「このアドレスに読み込みが起こったら停止させる」等々
 ソフトウェアブレイクポイントよりも高機能
 4つしかセットできない(プロセッサに4つ分しか実装されていない)

ASLR:OS のセキュリティ機能( ON / OFF )

どのようなソフトウェアであれ、最終的にはプロセッサが解釈できるマシン語として実行される以上、「どれほど難しく、どれほど困難に対策をほどこしても、ソフトウェアを構成するすべてのマシン語が読まれてしまえば解読されてしまう」
コラム:.NET 製アプリを解析するには
コンパイル時に MSIL(Microsoft Intermediate Language) と呼ばれる中間言語になり、実行時に CLR(Common Language Runtime) によってプロセッサが解釈できるマシン語へ変換される。
→Java と同様に、MSIL を解析することになり、そのための逆コンパイラが .NET Reflector 8。

.NET Reflector 8
http://www.red-gate.com/products/dotnet-development/reflector/

Java や .NET 製アプリケーションのリバースエンジニアリングは、デバッガや逆アセンブラを使って少しずつ解析していくのではなく、「どこまで本来のソースコードに近い形に戻せるか」という点が重要になる。


記述に際しては、細心の注意をしたつもりですが、間違いやご指摘がありましたら、こちらからお知らせいただけると幸いです。


→「たのしいバイナリの歩き方」勉強メモ#3
←「たのしいバイナリの歩き方」勉強メモ#1


« 戻る