アイジア

CTF, 情報セキュリティの学んだことメモ

crkme04 + 04a

http://doomo.xyz/crack/crkme04.exe

f:id:favoritte15:20180713124317p:plain

いつも通りGetWindowText関数が呼び出された直後の処理を見ていく。

004011FA . 68 2C304000 PUSH crkme04.0040302C 
004011FF . E8 20000000 CALL crkme04.00401224

入力した文字列を引数としてアドレス401224に飛んでいる。

f:id:favoritte15:20180713124540p:plain

0040122C |> AC /LODS BYTE PTR DS:[ESI]

LODS命令はESIレジスタに格納されているアドレスを参照してEAXレジスタに格納する命令だ。

ここでは「BYTE PTR DS」と指定されているので1バイト(入力文字列の先頭1文字分)だけをEAXにロードしている。

 

ロードしたEAXの値に対して3つの比較を行い、ループを抜けるかの条件分岐をしている。

f:id:favoritte15:20180713125210p:plain

ループを抜ける条件は

①EAXが0であること

②EAXが30より小さいこと

③EAXが39より大きいこと

なので入力文字列は0x30~0x39(ASCIIコードで0~9)でなければならない。

 

EAXが0x30~0x39のとき、以下の処理が行われる。

 

f:id:favoritte15:20180713131022p:plain

 

 EAXから0x30引いてEBXと交換する。EAXをx0A倍してそれをEBXと足し合わせる。

 

...

入力文字列が12345678なら

1 + 0*10

2 + 1*10

3 + 12*10

4 + 123*10

.

.

.

という風な感じになる。ただ入力文字列を10進数とみなして16進数に直してるだけだった。この関数を呼び出した直後に

00401204 . 3D F9602E2C CMP EAX,2C2E60F9

 とあり、EAXの値は最終的に0x2C2E60F9でなければならない。

EAXを0x2C2E60F9にしたいならこれを10進数に直した741236985を入力として与えればよい。

 

 

crkme04a

f:id:favoritte15:20180717094024p:plain

f:id:favoritte15:20180717094105p:plain

00401222 |. E8 21000000 CALL crkme04a.00401248

関数0x401248はcrkme04でやったのと同じで入力した数字を16進数にしてEAXに格納する関数だった。

その後上位16ビットをEAXに、下位16ビットEBXに分けて格納して、EAX×EBXが0x99BA4A95なら正解処理に進む。ただしEAX < EBXでなければならない。

0x99BA4A95は10進数で2579122837。この約数をプログラムで求めると、

2579122837 = 42197 × 61121 であることが分かった。

42197 = 0xA4D5

61121 = 0xEEC1

0xA4D5EEC1 = 2765483713