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

「たのしいバイナリの歩き方」の勉強メモ第2弾です。

2.1 メモリダンプを読み解く

汎用プロセスメモリエディタの紹介。

[うさみみハリケーン]
http://hp.vector.co.jp/authors/VA028184/#TOOL
http://www.vector.co.jp/soft/win95/prog/se375830.html

Windows Vista以降の場合のメモリダンプの取得方法

  1. [Ctrl]+[Alt]+[Del]でタスクマネージャを起動
  2. 該当するプロセスで右クリック
  3. 「ダンプファイルを作成」を選択

すると、C:\Users\ユーザー名\AppData\Local\Temp\***.DMP が作成される。

Windows XPまでの場合のメモリダンプの取得方法
プロセスが異常終了した時にワトソン博士というメモリダンプツールが起動する。

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

OllyDbgでもこの設定ができる。メニューからオプション→シャストインタイムデバッグを選択すると設定用のウィンドウが表示され、そこで「ジャスト・イン・タイム デバッガ 新規設定」をクリックすると、OllyDbgがJust-In-Timeデバッガとして設定される。

guitest.exeでメニューのヘルプからバージョン情報を開き、
そのウィンドウを閉じて異常終了させても、OllyDbgが起動しなかった。

設定では次のような画面になったが、何か問題があるのだろうか?
f:id:satou-y:20151101201606p:plain

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

[Ctrl]+[D]:ダンプファイルを開く
[Alt]+[6]:Call Stackウィンドウの表示
[Alt]+[7]:Disassenblyウィンドウの表示
[Alt]+[4]:Registersウィンドウの表示
[Alt]+[5]:Memoryウィンドウの表示

コラム:パソコン以外のコンピュータを解析することはできるのか

[devkit]
http://devkitpro.org/

各ゲーム機を解析した有志が集まり非公式の開発環境などを公開している。

コラム:Java製アプリを解析するには

[Javaコンパイラ]
http://java.decompiler.free.fr/

Javaバイトコードx86アセンブラにくらべてソースコードに戻すことが容易。
Eclipseプラグインとしても提供されている。

2.2 動作を解析されないようにするには

デバッガ検知のAPI関数の例

  • IsDebuggerPresent
  • CheckRemoteDebuggerPresent

コラム:デバッグを検知するさまざまな手法

  • popfとSINGLE_STEP例外を利用したデバッガ検知手法
  • int 2dhを使った検知手法

デバッグ対策は効果的であるが、逆アセンブラで静的に解析され、検知処理を走らせている箇所を特定されてしまうと、かんたんに潰される。
コードを解析されないようにするための手段が「難読化」である。

コラム:難読化に関する話題

難読化に関する有益な論文の紹介。

Obfuscation of executable code to improve resistance to static disassembly.
http://www.cs.arizona.edu/solar/papers/CCS2003.pdf

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

アンチデバッギング、難読化のほかにも、実行ファイルを実行できる状態のまま圧縮することで解析を防ぐことができる。
そのためのソフトをパッカーと呼ぶ。パッカーには次のようなものがある。

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

[ASPack]
http://www.aspack.com/
アンチデバッギングを目的としたパッカー。P2Pファイル交換ソフトWinnyで使用されていた。

パッカーで圧縮された実行ファイルを展開するツールをアンパッカーと呼ぶ。

  • UPXの場合は、-dオプションで実行すれば展開できる。
  • UPX以外の場合は、公式にはアンパッカーが存在しない。

UPXを手動でアンパックして仕組みを理解するために、
OllyDumpというOllyDbg用のプラグインを使用する。

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

CALL packed.XXXXXXXXが完了してから、
OllyDbgメニューからプラグイン→OllyDump→Dump debugged processを選択、
ファイルの保存すると、アンパックしたファイルになっている。

最初にあったpushadと最後にあったpopad、これらに挟まれた処理が展開ルーチンであった。
ほとんどのパッカーはこのような仕組みを採用しており、必ずどこかのタイミングで展開ルーチンが終わり、本処理へ進む。
手動アンパックとは「展開ルーチンが終わる瞬間(箇所)を見つける作業」といえるかもしれない。

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

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

OllyDbgのショートカット。

[Ctrl]+[G]:指定アドレスにジャンプ
[Ctrl]+[A]:コード解析

コラム:.NET製アプリを解析するには

コンパイラの紹介

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

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