Slide 1

Slide 1 text

x86アセンブラ入門 mcat meeting #4 07/22/2014 ntddk

Slide 2

Slide 2 text

前提 ● 実行ファイルからソースコードを復元するのは 困難 – セマンティックギャップ – 変数名 – ポインタ – コンパイラ最適化 ● リバースエンジニアリング

Slide 3

Slide 3 text

アセンブラ 8B E5 mov esp, ebp ● ニーモニック – オペコードとオペランドの組み合わせ ● オペコード – アセンブラの命令 ● オペランド – 演算に用いるレジスタやメモリアドレス 機械語 オペコード 第一オペランド 第二オペランド ニーモニック

Slide 4

Slide 4 text

レジスタ ● CPU内の記憶領域 ● 汎用レジスタ – eax, ecx, edx, ebx, esp, ebp, esi, edi ● セグメントレジスタ – cs, ds, ss, es, fs, gs ● ステータス制御レジスタ – eflags, eip ● FPUレジスタ, MMXレジスタ, SSEレジスタ

Slide 5

Slide 5 text

汎用レジスタ ● eax, ecx, edx, ebx, esp, ebp, esi, edi ● eax, ecx, edx, ebx – 値 – eax ● 変数 – ecx ● C++製のバイナリに多い ● thisポインタ, forのカウンタなどが保存される ● 初期化されなければクラスのメンバ関数

Slide 6

Slide 6 text

汎用レジスタ ● eax, ecx, edx, ebx, esp, ebp, esi, edi ● esi, edi – メモリアドレス

Slide 7

Slide 7 text

汎用レジスタ ● esp – スタックポインタ – push命令, pop命令によって変動 ● ebp – スタックフレームのベースポインタ 値 a リターンアドレス 値 b スタックはLast In, First Out スタックポインタ ベースポインタ

Slide 8

Slide 8 text

セグメントレジスタ ● cs, ds, ss, es, fs, gs ● 旧世代の遺物 ● cs – コードセグメント – 実行ポインタが参照 ● ds – データセグメント – mov命令などが参照

Slide 9

Slide 9 text

セグメントレジスタ ● ss – スタックセグメント – push, pop, call, retなどスタック操作を伴う命令が 参照 ● es, fs, gs – 仕組み上はおまけのようなものだが… – いずれ詳しくやります – 構造化例外ハンドラ

Slide 10

Slide 10 text

ステータス制御レジスタ ● eflags, eip ● eflags – 演算過程の状態を保存 – 加減(add, sub)や比較(cmp test)の命令に伴いセット される

Slide 11

Slide 11 text

ステータス制御レジスタ ● eflagsのフラグ – CF ● キャリーフラグ ● 最上位ビットに対して繰り上げまたは繰り下げが行われ たときにセットされる – ZF ● ゼロフラグ ● 結果がゼロだったときにセット

Slide 12

Slide 12 text

ステータス制御レジスタ ● eflagsのフラグ – SF ● サインフラグ ● 結果がマイナス値だったときにセット – OF ● オーバーフローフラグ ● 結果を格納するためのレジスタより結果の値が大きいと きにセット

Slide 13

Slide 13 text

ステータス制御レジスタ ● eip – 次に実行する命令のアドレス

Slide 14

Slide 14 text

代表的なアセンブラの命令 ● mov命令 – レジスタ・メモリ間またはレジスタ・レジスタ間で 値をコピー – mov ecx, 10 ; ecx = 10 ● add命令, sub命令 – 加減算 – add eax, ecx ; eax = eax + ecx

Slide 15

Slide 15 text

代表的なアセンブラの命令 ● push命令, pop命令 – スタックに値を入れる, スタックから値を取り出す – espの加減算を伴う

Slide 16

Slide 16 text

代表的なアセンブラの命令 ● sal命令, sar命令 – 左シフト演算, 右シフト演算(算術シフト) – 1bit左シフトの場合, 1010 0011 → 1100 0110 ● shl命令, shr命令 – 左シフト演算, 右シフト演算(論理シフト) – 1bit左シフトの場合, 1010 0011 → 0100 0110 – 2の累乗で乗算 , 2の累乗で除算と覚えると楽 – shr eax, 0x4 ; ecx = ecx >> 0x4 ● 余りは無視

Slide 17

Slide 17 text

代表的なアセンブラの命令 ● 分岐命令 – eflagsレジスタをもとに任意のアドレスに分岐 – jmp命令 ● 無条件ジャンプ – jc, jnc命令 ● CFが立っているかどうか – jz, jnz命令 ● ZFが立っているかどうか

Slide 18

Slide 18 text

代表的なアセンブラの命令 ● 分岐命令 – js, jns命令 ● SFが立っているかどうか – jo, jno命令 ● OFが立っているかどうか

Slide 19

Slide 19 text

代表的なアセンブラの命令 ● test命令 – 論理積 – test eax, eax – eax=0ならZF=1となるので, jz命令などで分岐 ● cmp命令 – 比較 – cmp eax, 0 – eax=0ならZF=1となるので, jz命令などで分岐

Slide 20

Slide 20 text

代表的なアセンブラの命令 ● xor命令 – 排他的論理和 – xor eax, eax – 同じ値同士なら0になるので, testやcmpの準備に多 用される

Slide 21

Slide 21 text

d.hatena.ne.jp/a4lg/20120225/1330180431

Slide 22

Slide 22 text

予定 ● 実際の逆アセを読む – 特にC++の仮想関数テーブルやコンストラクタなど ● PEファイルフォーマット ● 逆アセンブラとデバッガ ● アンチデバッギング