このPartで最後です。
本を読み進めていましたが、途中で使うサンプルプログラムの配布がなく、実習できませんでした。残念。古い本なので仕方ないですね。そして、途中からは無能すぎて何いってんだコイツ状態になりました。出直してきます。
難読化・解析対策
「使えません」というメッセージボックスと出してしまうだけで、解析する側はクラックするきっかけを手に入れることができてしまいます。また、その直前でif文で条件分岐などをさせていると、ジャンプ系の命令が直前に確認できるため、書き換えで簡単に突破されてしまいます。
メッセージボックスを出す部分を関数ポインタにすることで直前に分岐を発生させないことができるようです。関数ポインタは、単純に、”関数が格納されたアドレスを指すもの”です。直接アドレスを渡す場合だとそのアドレスがバレるので、アドレスを2分割して、呼び出すときに合体させるなどをすると、解析が難しくなります。時間をかければ解析されてしまうことにはかわりなしです。
コールスタック
流れた処理の中でコールされた履歴が見られる機能?です。右下のスタックウインドウは、スタックウインドウは積まれたスタックを表示するだけなので、あらゆる情報が記載されていますが、このコールスタックは余計な情報がない分、見やすくなっています。
crackmeからのコール元がわかるので、上記の画像のMessageBoxを呼び出しているアドレスにすぐ飛べます。直前に条件ジャンプがあれば、期限切れの判定をしていると判断できます。便利。ただし、プログラム自体に工夫(CALLで呼ぶ関数をJMPで飛んで実行している場合など。インラインアセンブラでコードを書けば実装できる!)がされているとそうもいかず、コールスタックにcrackmeからの呼び出し元が何も表示されない場合があります。
そういう場合は、表示された別の情報にBPをかけ、そこからユーザコードまで実行すれば、crackmeまで戻ってこれるようです。その後に、そこのアドレスに対して「選択コマンドへの参照」をすることで、そのアドレスを利用している箇所が抽出できます。そこからごにょごにょすれば処理が終えてクラックできます。
APIを知ることが大切
Windowsで動いているプログラムを解析するならWin32APIの神になる必要があるということがよくわかります。
現在の時間を取得する、文字列を取得するテキストボックスを含むウインドウなど単純なものでも多数のAPIがあり、解析時に常に同じものが使われているとは限りません。頻出のAPIに関しては覚えておかないと解析どころではありません。すべてを知る必要があるとは思っているわけではなく、必要に応じて調べて理解できればいいなという感じです。
今後
別の書籍やWeb情報を元に解析・アセンブラに関してもう少し理解できたらと思いましたので、進めてみたいと思います。文字を読んでいるだけではダメで実習ベースでないと全く身につかないので、とにかく触っていきたいと思います。