a

よろしくのキワミ

Reversing進捗8

Reversing進捗8

Direct3D_FPS

動作確認

起動すると一人称視点のFPSゲームが始まる。

f:id:toDo:20190128130251p:plain

やたらと動作が重いのはPCのスペックがあっていないからだろうか

解いていく

おそらくゲームをクリアすればフラグが入手できるのだと思う。
つまり処理の方でいわゆるチート行為をするように書き換えればいいのではと考えた。

ゲームのプログラミングについては趣味程度でしか触ったことがないが、入力待ちの状態を繰り返し入力に応じて関数を呼び出すという感じで処理を書いたので今回もそうだと思う。
つまりどこかでそこそこ大きな繰り返し処理があるということだ。

まずは参照している文字列を検索する

f:id:toDo:20190128132232p:plain

Game Clear!の文字列が見える。
ここから処理をさかのぼってみる。

f:id:toDo:20190128134106p:plain

"Game Clear!"文字列を使用している処理を見てみるとMessageBoxが呼び出されていることがわかる。

ここに飛ぶように処理を書き換えてみる。

f:id:toDo:20190128142040p:plain

表示されたメッセージボックスがこれだ。

文字化けしていてよくわからないがフラグはこれっぽい。
わざわざクリアをする必要はなさそうですね。

MessageBoxAの引数を見るとfps.BE55B0が"Game Clear!"の文字列の入っているメモリアドレスでfps.BE7028がフラグの入っているアドレスだということがわかる。

MessageBoxA function

int MessageBoxA(
  HWND   hWnd,
  LPCSTR lpText,
  LPCSTR lpCaption,
  UINT   uType
);

アドレスに保存されている値を見てみる

f:id:toDo:20190128144917p:plain

この値が出力されていることがわかる。

他の参照を調べる

出力されるのはfps.BE7028の値で間違いないので、他に参照しているところがないか調べてみる。

f:id:toDo:20190128162319p:plain

2件ヒットする。
下の処理は先ほど見たMessageBoxAに対する引数渡しの処理なので別の方の処理の近くを見てみる。

f:id:toDo:20190128162503p:plain

imulという命令を始めてみたので調べてみると符号付掛け算らしい

imul ecx, ecx, 210

ecxと0x210を掛け算していることはわかるがそれ以上のことは他を参照しないとわかりそうにない。
clはカウンタレジスタのはずなので繰り返し処理をしているのかな?

詰まった

ここで詰まってしまいわからなくなった。
Flagと思われるメモリにブレークっポイントを設定し、ゲームを遊びながら値を確認することにした。

f:id:toDo:20190204144315p:plain

すると敵を1匹倒すと上記の処理が呼び出されてFlagのバイトが1バイト変更されているのがわかった。

しかし敵をすべて倒してもフラグがすべて復号されていないので敵を増やすかフラグのバイト数処理を回すことにする。

敵を増やして倒すのはハッカーっぽくないので処理をバイト数回すことにした。

というわけでまずは返還対象のバイト数を調べる

data = [
0x43, 0x6B, 0x66, 0x6B, 0x62, 0x75, 0x6C, 0x69, 0x4C, 0x45, 0x5C, 0x45, 0x5F, 0x5A, 0x46, 0x1C,0x07, 0x25, 0x25, 0x29, 0x70, 0x17, 0x34, 0x39, 0x01, 0x16, 0x49, 0x4C, 0x20, 0x15, 0x0B, 0x0F,0xF7, 0xEB, 0xFA, 0xE8, 0xB0, 0xFD, 0xEB, 0xBC, 0xF4, 0xCC, 0xDA, 0x9F, 0xF5, 0xF0, 0xE8,0xCE,0xF0, 0xA9
]

print(len(data))

f:id:toDo:20190204172810p:plain

50バイトだとわかる。
次に変換する処理を調べる

挙動を確認したところ復号はdata[i]番目 ^ i * 4していることがわかった。

というわけで復号するコードはこうなります

data = [
0x43, 0x6B, 0x66, 0x6B, 0x62, 0x75, 0x6C, 0x69, 0x4C, 0x45, 0x5C, 0x45, 0x5F, 0x5A, 0x46,
0x1C,
0x07, 0x25, 0x25, 0x29, 0x70, 0x17, 0x34, 0x39, 0x01, 0x16, 0x49, 0x4C, 0x20, 0x15, 0x0B, 0x0F,
0xF7, 0xEB, 0xFA, 0xE8, 0xB0, 0xFD, 0xEB, 0xBC, 0xF4, 0xCC, 0xDA, 0x9F, 0xF5, 0xF0, 0xE8, 0xCE,
0xF0, 0xA9
]

answer = ""
for i in range(len(data)):
  answer += chr(data[i] ^ i * 4)

print(answer)

f:id:toDo:20190204174403p:plain

というわけでフラグをゲットできた。

じゃあimul ecx, ecx, 210ってなんなのよ!

なんなのよ!

感想

大分進んできた

f:id:toDo:20190204175227p:plain

  • 本処理に絡まないところもしっかり考えるようにしよう
  • 一回一回挙動の確認をしなくても処理を見ただけで解析ができるようになりたい
プライバシーポリシー お問い合わせ