「たのしいバイナリの歩き方」 第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
実行例 C:\>nasm -fwin32 hello32.asm C:\>alink -oPE hello32 win32.lib -entry main