〜前回に続き〜ディスクチェック解除方法の中編です♪「えぇ〜? ってことはまだ終わらないんか〜〜???」 と思われるかもしれませんが、まあそうです(苦笑 逆アセンブルリストを読みながら、解析するコツを覚えていきましょう。 ドライブチェックの後…GetDriveTypeAの後の判定分岐処理を書き替えるところまでやりましたので、今度はその後に待っているディスク判定処理を解除しましょう。 ここがディスクチェックのメイン部分とも呼べるところですが、解析前に一つ言っておきます。 プログラマの人の趣味が出ます(爆 これは、言いかえれば「ゲームごとにアルゴリズムが違う」ということです。 例えばAさんというプログラマが「CD内のファイル構成を元にしたチェック」を作ったら、 逆アセンブルリストにはファイルチェックをベースとしたディスクチェック処理がありますし、 Bさんというプログラマが「俺は、CDのボリュームラベルをチェックに使う」としたら、 逆アセンブルリストにはボリュームラベルチェックをベースとしたディスクチェック処理があります。 つまり、ディスクチェックには数多くのパターンがある…ということです。 (実はほとんどのチェックに「共通部分」があるんですけど、それはまた別の機会で…) まあ、1回成功すれば後は自力で何とかできると思いますので、今回はとりあえず、 前回使ったサンプルを続行して解析しましょう。 なお、このサンプルに使用されている方法はボリュームラベルチェックです。 この形式のチェックは結構よく見かけますので、参考になると思いますよぅ(某T社とか… ボリュームラベルを取得する処理を探す!…と言っても、簡単です(笑そもそも、前回すでにチェック第1段階である GetDriveTypeA を見つけているのですから、 すぐ後に見つかるのは当然だったりします。 というわけで、リストの GetDriveTypeA の下の方を見てゆくと〜…
…案の定でしたね(笑 GetVolumeInformationA…読んで字のごとく「ボリューム情報の取得」です。 VisualC++でプログラムを組む場合(ボリュームのみ取得したい場合)には… GetVolumeInformation("A:\\",LabelName,sizeof(LabelName),NULL,NULL,NULL,NULL,NULL); といった感じにします。 (上記の例では、Aドライブのボリュームラベル名を、LabelNameに格納します) で、LabelNameに格納されたボリュームラベル名をチェックして、正しければスタート〜… という処理を作れば、それがボリュームラベルチェックをベースとした、 ディスクチェック処理になります。簡単ですね。 さらに処理を見てゆく…ボリュームラベルを取得したあと、以下のような処理が続きます。
「なんやねん、これ〜〜〜???」 と思うかもしれませんが、ここがボリュームラベルチェック後の処理です。 つまり「警告を表示するか、正常に起動するか…」です。 一応、コメントは付け加えておきましたので、解説を見る前に目を通しておくと良いですよ。 ただ、これを一気に理解しようとすると、まず間違い無く挫折してしまうと思います。 なので、主要な部分をピックアップしてみましょう。 フラグという概念上記の逆アセンブルリストを見ていると、コメントのところどころに「フラグを〜…」という文章が見られますが、これが、このフラグがプログラムのポイント部分です。 プログラムの最後には「フラグが01(正常)だった場合に来る処理。」もありますし、 この処理は全て、このフラグによって制御されていると言えます。 (なお、アセンブラのフラグレジスタとは違うものですので、混合しないよう気をつけてください) つまり、このフラグを強制的に「ディスクが入った状態と同じ値」にしてしまえば、 プログラムはディスクが入っていると認識し、チェックを通過するはずです。 では、やってみましょう。 フラグをON/OFFしている部分を探すまあ、コメント内で書いていますので気づいたと思いますが、以下の処理がそれです。
上の条件分岐があり、その下に mov という命令が使われていますが、 これがディスクチェックフラグをONにするのに使用される命令です。 mov命令上記の例で使用されている mov dword[ebp+FFFFFEFC], 00000001 には、「アドレス ebp+FFFFFEFC の数値を、dword型(4バイト)の1(01 00 00 00)にする」 という効果があります。 もちろん、これが mov dword[00435000], FFFFFFFF であれば、 「アドレス 00435000 を FFFFFFFF にする」という効果があります。 (正しくはアドレス 00435000 に FFFFFFFF をストアする…などと言います) 「アドレス ebp+FFFFFEFC ???」と思われる方も多いと思いますが、このebpはレジスタです。 このebpにどんな数値が入っているかは、デバッガで確認しないと分かりませんが、 私の環境でデバッガで調べた結果、ebp=0063FDAC でした。 では、ウインドウズに標準で入っている「電卓」を起動してください。 (インストール時に変更しなければ、普通は「アクセサリ」内にあります)。 起動したら、メニューから「電卓の種類」を選び、これを「関数電卓」にします。 そして、そこで以下の計算をします。 0063FDAC+FFFFFEFC これで、計算結果が 63FCA8 となればOKです。 「FFFFFEFC(4294967036)と足したのに、足す前より減ってる???」 と思った方はなかなか観察力がありますね。 まあ、この辺りは情報処理技術者資格の参考書でも読んでください。 ひょっとしたら、情報処理検定2〜3級の参考書にも書いてあるかもしれませんです。 「2進数の計算」とか「補数によるマイナスの扱い方」などのところを見てくださいな。 つまり、これにより、mov dword[ebp+FFFFFEFC], 00000001 とは、 mov dword[0063FCA8], 00000001と同じだということが分かります。 (つまり、アドレス 0063FCA8 に 01 00 00 00 を書き込むってわけです) ※注意 Windows2000やWindowsNTだとメモリ配置が異なるらしいので、動作は保証しかねます。 必ずそのアドレスの数値を確認してから作業を行ってください。 なお、ヒープ1の範囲が00410000〜0064FFFFでなければ、確実に失敗するはずです。 手動でフラグをいじってみるでは、キーディスクを入れずに、サンプルプログラム CHK_VOL.EXE を実行してみてください。警告メッセージが表示されますが、そこでDBxSTANDなどのプロセスエディタでCHK_VOLを開きます。 そして、先ほどの計算で求めたアドレス 0063FCA8 を見ると〜… 00 00 00 00 となっています。 そこでキーディスクを挿入して「はい」をクリックしてディスクチェックをし、 正常終了メッセージを表示させたまま再びプロセスエディタに戻ります。 すると… 01 00 00 00 。つまり、フラグがONになっていることが確認できます。 では1度サンプルプログラムを終了し、再びキーディスク無しで起動してプロセスエディタで開きます。 警告メッセージが表示されますが、その状態でアドレス 0063FCA8 の数値を 01 00 00 00 にします。 そして、「はい」をクリックすると……もう言わなくても分かりますね。 これがフラグを変更した場合に可能なディスクチェック解除です。 次回に続く!です。先ほどの方法では手動でフラグを変更しましたが、次はプログラムそのものを改造し、 「必ずフラグがONになる」という処理にしてみたいと思います。 それではお楽しみに! >>NEXT STEP |