判断は分岐の命令にある
radare2 は、プログラムを逆アセンブルして、関数や文字列に名前をつけて見せる、リバースエンジニアリングの道具です。プログラムが何かを判断する場所は、いつも分岐の命令にあります。
分岐を見つければ、割引の年齢や合言葉の長さのような、判断の材料が読めます。
このレッスンのゴール
メモ
radare2 でプログラムの分岐を見つけ、何で決まるか言える。
重要な言葉
| ことば | いみ | れい |
|---|---|---|
| radare2 | 逆アセンブルと解析をする道具。コマンドは r2 | |
| 分岐 | 条件で、次に進む行を選ぶこと | |
| 解析 | 関数と文字列を探して、名前をつけること | aa |
| 16進数 | 0 から f の16個の数字で書く数 | 0x40 |
| 比較命令 | 2つの値を比べて、フラグを立てる命令 | cmp |
| 条件ジャンプ | フラグを見て、飛ぶかどうかを決める命令 | jle |
学生が入力するセルは、このプレビューでは空白です。
radare2 は名前をつけて見せる
r2 -q -e scr.color=0 -c コマンド ファイル は、ファイルを開き、コマンドを1つ実行して終わります。-q は終了、-c はコマンドの指定です。
aa は、関数を探して名前をつける解析です。pdf @ main は、main を逆アセンブルして出します。
最初に覚える radare2 のコマンド
| コマンド | 意味 |
|---|---|
| aa | プログラム全体を解析する |
| afl | 見つけた関数を一覧にする |
| iz | 中の文字列を一覧にする |
| pdf @ main | main を逆アセンブルして出す |
| q | radare2 を終わる |
学生が入力するセルは、このプレビューでは空白です。
年齢で運賃が変わるプログラム
次の練習用プログラムは、年齢を受け取ります。65以上なら senior fare、それ以外なら regular fare と出します。
ソースを作ってバイナリにし、ソースを消してから、radare2 で分岐を探します。
ソースを書く
printf '%s\n' '#include <stdio.h>' '#include <stdlib.h>' 'int main(int c, char **v) {' ' int age;' ' if (c != 2) { puts("usage: rev3 AGE"); return 2; }' ' age = atoi(v[1]);' ' if (age >= 65) puts("senior fare");' ' else puts("regular fare");' ' return 0;' '}' > /tmp/rev3.cここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
プログラムを作る
gcc -O0 -no-pie -o /tmp/rev3 /tmp/rev3.cここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
ソースを消す
rm /tmp/rev3.cここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
文字列を一覧にする
r2 -q -e scr.color=0 -c iz /tmp/rev3 2>/dev/nullここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
main を探す
r2 -q -e scr.color=0 -c aa -c afl /tmp/rev3 2>/dev/null | grep mainここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
jle の前の cmp が材料を持つ
pdf @ main の出力から、cmp、jle、call の行だけを残します。cmp が比べる値と、そのあとの条件ジャンプが、判断の中身です。
数は16進数で書かれ、0x40 は十進数の 64 です。出力の var_4h は、main の中の変数の名前です。
分岐の行を探す
r2 -q -e scr.color=0 -c aa -c 'pdf @ main' /tmp/rev3 2>/dev/null | grep -E "cmp|jle|call"ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
16進数と10進数
| 16進数 | 10進数 | どう数えるか |
|---|---|---|
| 0x0c | 12 | c は 12 を表す |
| 0x10 | 16 | 16が 1 つ |
| 0x40 | 64 | 16が 4 つ |
| 0x41 | 65 | 16が 4 つと 1 |
学生が入力するセルは、このプレビューでは空白です。
条件ジャンプの読み方
| 命令 | 飛ぶとき |
|---|---|
| je | 等しい |
| jne | 等しくない |
| jle | 以下 |
| jg | より大きい |
| jl | より小さい |
| jge | 以上 |
学生が入力するセルは、このプレビューでは空白です。
よくある間違い
注意
条件ジャンプは、if の条件が成り立ったとき飛ぶと思いがちです。実際は逆のことが多く、コンパイラは「成り立たなければ飛ぶ」と書きます。このプログラムの jle は、64以下のとき regular fare へ飛びます。
64歳で実行
/tmp/rev3 64ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。
65歳で実行
/tmp/rev3 65ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。