コース目次 / 第2章

逆アセンブルを読んで、正解を計算する

objdumpでcheck関数を逆アセンブルし、比較対象のバイト列とXOR鍵が即値オペランドとして埋め込まれていることを読み取ります。実行せずにPythonで正解を計算し、最後に実行で答え合わせをします。

第2章 / 全4章目安 約15分この章のゴール: objdumpの出力から定数を読み取り、実行せずに正解を計算できるようになる

check関数を、逆アセンブルする

objdump -d -M intel crackme

<check>: から始まる部分に注目します。長い出力ですが、必要なのは最初の数命令です。

0000000000001209 <check>:
    1209:	f3 0f 1e fa          	endbr64
    120d:	55                   	push   rbp
    120e:	48 89 e5             	mov    rbp,rsp
    1211:	48 83 ec 30          	sub    rsp,0x30
    1215:	48 89 7d d8          	mov    QWORD PTR [rbp-0x28],rdi
    1219:	64 48 8b 04 25 28 00 	mov    rax,QWORD PTR fs:0x28
    1220:	00 00 
    1222:	48 89 45 f8          	mov    QWORD PTR [rbp-0x8],rax
    1226:	31 c0                	xor    eax,eax
    1228:	c7 45 f2 1a 0e 02 0c 	mov    DWORD PTR [rbp-0xe],0xc020e1a
    122f:	66 c7 45 f6 08 0f    	mov    WORD PTR [rbp-0xa],0xf08
    1235:	c6 45 e7 55          	mov    BYTE PTR [rbp-0x19],0x55
    1239:	48 8b 45 d8          	mov    rax,QWORD PTR [rbp-0x28]

関数プロローグ(push rbp / mov rbp,rsp / sub rsp,…)は、sec-asmで見た「スタックフレームを作る」定型パターンです。読み飛ばしてよい部分と、注目すべき部分を見分けられることが、revの第一歩です。

即値オペランドに、答えが埋まっている

0x1228 の mov DWORD PTR [rbp-0xe],0xc020e1a に注目します。これは 「4バイトの即値 0x0c020e1a を、スタック上の変数に書き込む」命令です。x86はリトルエンディアンなので、メモリ上のバイト列は下位バイトから並びます——つまりこの4バイトは 1a 0e 02 0c です。
続く 0x122f の mov WORD PTR [rbp-0xa],0xf08 は2バイト 08 0f。合わせると 6バイトの配列 1a 0e 02 0c 08 0f が、target 配列の初期化だと分かります(crackme.c の target[] と同じ値です——ソースを知らなくても、この並びだけで読み取れます)。
さらに 0x1235 の mov BYTE PTR [rbp-0x19],0x55 が、1バイトの XOR鍵 0x55 です。

これで実行せずに答えが分かります。 ソースが手元にある今回は答え合わせがすぐできますが、ソースなしバイナリだけが与えられるrev問題でも、同じ手順——mov命令の即値オペランドを拾って、比較ロジック(今回はXOR)を読み取る——で解けます。

Pythonで、正解を計算する

solve.py として保存します。

target = [0x1a, 0x0e, 0x02, 0x0c, 0x08, 0x0f]
key = 0x55
password = ''.join(chr(t ^ key) for t in target)
print(password)
python3 solve.py
O[WY]Z

まだ一度も ./crackme に正解を入力していません。逆アセンブルを読んで、計算だけで答えを出しました。

実行で、答え合わせをする

printf 'O[WY]Z\n' | ./crackme
合言葉を入力してください: 正解! flag{O[WY]Z_verified}

計算した通りの結果になりました。これがrevの基本の型です——「動かして総当たり」ではなく、「読んで論理を理解し、計算で答えを出し、最後に実行で確認する」。今回のXORのように単純な比較でなくても、暗号処理や複雑な条件分岐であっても、この順序自体は変わりません。

こうなっていればOK

卒業まであと1章です。

この章はまだ完了していません。