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

CTFを勉強する上でおすすめの本だったので、「たのしいバイナリの歩き方」を購入し、勉強を始めました。
自分の理解を深めるためにも勉強メモとして記録しておこうと思います。

1.1 まずは解析の流れを体感してみよう

次の3点に注目!

  • ファイルの作成/変更/削除を行う
  • レジストリキーの作成/変更/削除を行う
  • ネットワーク通信を行う

監視するためのツールの紹介。

[Stirling](バイナリエディタ
http://www.vector.co.jp/soft/win95/util/se079072.html

[Process Monitor](ファイルとレジストリの監視)
http://technet.microsoft.com/en-us/sysinternals/bb896645

[Wireshark](ネットワーク監視)
http://www.wireshark.org/

sample_mal.exeで0.exeと1.exeはコピーされていましたが、
レジストリへの書き込みは確認できませんでした。
UACが関係しているのか???

1.2 静的解析をやってみよう

バイナリエディタの紹介。

[Stirling]
http://www.vector.co.jp/soft/win95/util/se079072.html

[BZエディタ]
http://www.vector.co.jp/soft/win95/util/se032859.html

コラム:StirlingとBZエディタの違い

  • Stirling:高機能。さまざまな用途に使える。数GBを超えるファイルは扱えない。
  • BZエディタ:どんな巨大なファイルでも開くことができる。

アセンブルツールの紹介。

[IDA 6.2 Demo version, IDA 5.0 Freeware version]
http://www.hex-rays.com/products/ida/support/download.shtml

wsample01a.exeをIDAで開いても、
wWinMainという関数名が見つかりませんでした。

1.3 動的解析をやってみよう

デバッガの紹介。

[OllyDbg]
http://www.ollydbg.de/

OllyDbgのショートカット。

[F2]:ブレークポイントのセット
[F7]:ステップイン
[F8]:ステップアウト
[F9]:実行

コラム:レジスタとは

  • レジスタ:CPUが内部に持つ記憶領域。EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI、EIPといった名前がついている。
  • ESP/EBP:スタックの管理に使用される。
  • EIP:現在実行中の命令を指す。
  • フラグ:EIPの下にあるC、P、A、Z、S、T、D、Oという文字。

最初にStirlingやIDAで全体をざっと眺めたあとに、
気になったポイントをOllyDbgでステップ実行していく、
という流れで解析することが多い。

コラム:好みのデバッガを選ぼう

[OllyDbg]
http://www.ollydbg.de/

[Immunity Debugger]
http://www.immunityinc.com/products/debugger/

[WinDbg(32ビット版)]
http://msdn.microsoft.com/ja-jp/windows/hardware/gg463016

[WinDbg(64ビット版)]
http://msdn.microsoft.com/ja-jp/windows/hardware/gg463012

OllyDbgが特に人気。
Immunity Debuggerも同じUIで使え、Pythonと親和性が高い。
WinDbgは初心者向けではないが、唯一カーネルランドで動作するプログラムのデバッギングに対応している。

1.4 最低限のアセンブラ命令だけざっくり把握する

実際に覚えなければいけない命令は20~50ほど。
よく使われるアセンブラ命令

命令 意味 説明
MOV MOV EAX,ECX EAX = ECX ECXの値をEAXへ格納
ADD ADD EAX,ECX EAX += ECX EAXにECXを加算
SUB SUB EAX,ECX EAX -= ECX EAXからECXを減算
INC INC EAX EAX++ EAXに1を加算
DEC DEC EAX EAX-- EAXから1を減算
LEA LEA EAX,[ECX+4] EAX = ECX+4 ECX+4をEAXへ格納
CMP CMP EAX, ECX if(EAX == ECX)
 ZF=1
else
 ZF=0
値と比較してフラグへ反映
 EAXとECXが同じならばZF=1
 EAXとECXが違うならばZF=0
TEST TEST EAX,EAX if(EAX == 0)
 ZF=1
else
 ZF=0
値を0と比較してフラグへ反映
 EAXが0ならばZF=1
 EAXが0以外ならばZF=0
JE(JZ) JE 04001000 if(ZF==1)
 GOTO 04001000
ZFが1なら04001000へジャンプ
JNE(JNZ) JNE 04001000 if(ZF==0)
 GOTO 04001000
ZFが0なら04001000へジャンプ
JMP JMP 04001000 GOTO 04001000 無条件で04001000へジャンプ
CALL CALL lstrcmpW lstrcmpWの呼び出し
PUSH PUSH 00000001 スタックへ00000001を格納
POP POP EAX スタックからEAXへ値を格納

test命令は、ほとんどの場合において、test eax,eax や test ecx,ecx といったように、同じレジスタが2つ渡される形で使われる。
同じレジスタが渡されているtest命令を見つけたら、それは条件分岐であり、「レジスタが0ならば、ZFを1にするんだな」と覚えておけば大丈夫。

戻り値はeaxに格納される。これはある種の決まりごとであり、多くのプロセッサでは常識的に扱われている。
サブルーチンに渡す引数は、push命令を使い、スタックに格納する。
「引数はスタックに積まれる」と覚えておいて問題ない。

1.5 アセンブラ命令から動作を把握しよう

OllyDbgの関数一覧で、TypeがExportと書かれている関数をダブルクリックすると、その関数の先頭にジャンプすることができる。

OllyDbgのショートカット。

[Ctrl]+[F9]:リターンまで実行
[Alt]+[F9]:ユーザーコードまで実行

リバースエンジニアリングでは、「重要な個所は時間をかけてじっくりと理解する」「それ以外は全体の雰囲気からなんとなくこんな感じかなぁとざっくり把握する」ぐらいでよい。

コラム:アセンブラを書こう

アセンブラを書くことで、読み書き両方の能力が鍛えられる。

[NASM](アセンブラ
http://www.nasm.us/

[ALINK](リンカ)
http://alink.sourceforge.net/download.html

アセンブラのファイル拡張子はasmにする。

実行例
C:\>nasm -fwin32 hello32.asm
C:\>alink -oPE hello32 win32.lib -entry main