メッセージトラップ型CDチェック解除とその応用について
目次
△アプローチ例
メッセージトラップ型CDチェック解除例
- CDドライブからCDを取り出す等、警告メッセージを表示させるようにしてから「OllyDbg」でゲームを起動。
- メッセージボックス或いはダイアログで警告メッセージが表示されたところで、「OllyDbg」でゲームの制御を奪います(Pause:F12)。
- 制御を奪った時点で、逆アセンブルコードリスト上におけるメッセージボックス或いはダイアログ表示処理直後のユーザー入力待ち箇所のコードで停止する筈ですので、その周辺のコードを観察します。もしシステムDLL内のコードで停止した場合は、メニューの「解析」→「ユーザーコードまで実行」でゲーム側に一旦制御を戻してメインモジュールのコードで停止させます。
- 通常のCDチェック解除同様に、CreateFileA関数やFindFirstFileA関数などのCALL後の条件ジャンプ書き換えや、GetDriveTypeA関数の戻り値確認部分を見つけて05から03に変更します。
- 「OllyDbg」のコード変更後の実行ファイル保存機能を使って、オリジナルとは別名の新しい実行ファイルとして保存します。
以上で完了です。一般的なタイプのCDチェックならば、上記所要時間は30秒台前半程度となります。ちなみにBlueAshさんは上記工程を20秒台後半で完了させます。もちろん、事前の解析無しの、ゲーム初回起動時での所要時間です。
この手法は極めて簡易な上、従来のメッセージボックスセオリーでは対処できない、ダイアログを用いた警告表示やメッセージ参照アドレスを経由させるタイプ等のCDチェックでも問題なく対処できます。そのため、現在ではこのメッセージトラップ型CDチェック解除が主流となりつつありますが、PCゲーム解析初心者の方はこの様なテクニカルな手法を実践する前に、CDチェック解除のチュートリアルで基本を勉強されることを強くお奨めします。
更にこの手法により、CDチェック以外でも逆アセンブルコードリスト上の各種警告メッセージ表示箇所等を簡単に探し出し、その処理の解析を効率化することが可能になります(セーブデータ改竄警告回避、ディスプレイ表示色数警告回避、バグによるスクリプトエラー等警告回避、ゲーム起動時の各種選択・入力強制ダイアログのスキップ他)。
なお、このようなデバッガを用いてゲームの処理中任意のタイミングで制御を奪い、逆アセンブルコードリスト上で同処理箇所を特定する解析手法は、BlueAshさんが「ExGAME」のVol6で高速化改造を例に詳しく解説されていますので、ご覧になることを強くお奨めします。
注:「OllyDbg」の操作に関しては、当サイトの「OllyDbg」Q&Aをご覧下さい。
CDチェック以外でのメッセージトラップ型解析例
「終末の過ごし方」(アボガドパワーズ)では、ゲーム起動時にBGMモードの選択を強制されます。そこで、その選択ダイアログをスキップします。「OllyDbg」からゲームを起動させ、上記選択ダイアログが表示された時点で、「OllyDbg」上でF12キーを押してゲームの制御を奪います。その時点で表示される逆アセンブルコードリストは下記(「OllyDbg」で表示されるものとは異なります)。
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406B28(C)
|
:00406B50 53 push ebx
:00406B51 6880000000 push 00000080
:00406B56 6A03 push 00000003
:00406B58 53 push ebx
:00406B59 6A01 push 00000001
:00406B5B 6800000080 push 80000000
* Possible StringData Ref from Data Obj ->"DOM.ADP" ;独自フォーマットのBGMファイル
|
:00406B60 68BC524100 push 004152BC
:00406B65 891DBCAF4200 mov dword ptr [0042AFBC], ebx ;選択結果フラグ格納先を値0で初期化
* Reference To: KERNEL32.CreateFileA, Ord:0034h
|
:00406B6B FF15DC204100 Call dword ptr [004120DC]
:00406B71 8BF0 mov esi, eax
:00406B73 83FEFF cmp esi, FFFFFFFF
:00406B76 743D je 00406BB5
:00406B78 8B1514BF4200 mov edx, dword ptr [0042BF14] ;以下でダイアログボックス表示
:00406B7E A110BF4200 mov eax, dword ptr [0042BF10]
:00406B83 53 push ebx
:00406B84 68E05E4000 push 00405EE0 ;ダイアログボックスプロシージャ
:00406B89 52 push edx
* Possible Reference to Dialog: DialogID_006F
|
:00406B8A 6A6F push 0000006F
:00406B8C 50 push eax
* Reference To: USER32.DialogBoxParamA, Ord:0093h ;BGMをPCMかCD−DAか選択させる
|
:00406B8D FF1518214100 Call dword ptr [00412118]
:00406B93 833DBCAF420001 cmp dword ptr [0042AFBC], 00000001 ;F12キー押下によりここで止まります
:00406B9A 7519 jne 00406BB5 ;PCMが選択されたらジャンプ
:00406B9C 8B0D2CBF4200 mov ecx, dword ptr [0042BF2C]
:00406BA2 6A01 push 00000001
* Possible Ref to Menu: MenuID_0065, Item: "音量設定"
|
:00406BA4 68629C0000 push 00009C62
:00406BA9 51 push ecx
* Reference To: USER32.EnableMenuItem, Ord:00B5h
|
:00406BAA FF1558214100 Call dword ptr [00412158]
:00406BB0 E86B810000 call 0040ED20
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:00406B76(C), :00406B9A(C)
|
:00406BB5 56 push esi ;改造でここへ無条件ジャンプさせます
* Reference To: KERNEL32.CloseHandle, Ord:001Bh
|
:00406BB6 FF1568204100 Call dword ptr [00412068]
:00406BBC E80FE7FFFF call 004052D0
:00406BC1 85C0 test eax, eax
:00406BC3 750A jne 00406BCF
:00406BC5 5F pop edi
:00406BC6 5E pop esi
:00406BC7 5D pop ebp
:00406BC8 5B pop ebx
:00406BC9 83C468 add esp, 00000068
:00406BCC C21000 ret 0010
以上により、PCM選択でダイアログボックス表示をスキップする場合は下記のようになります。
00406B78=8B1514BF4200-EB3B40484048(「4048」はパディング) このダイアログボックスのダイアログプロシージャは下記。基本的にダイアログ関連の解析では、ダイアログプロシージャにも目を通して必要があれば改造しておくと有用です。ダイアログプロシージャの解析に当たってはリソースエディタの併用をお奨めします。
また、ダイアログプロシージャのコードについては、当サイトで公開している「改造初心者向け練習用プログラム No1」のソースコード参照が有用と思われます。
:00405EE0 8B442408 mov eax, dword ptr [esp+08]
:00405EE4 83EC10 sub esp, 00000010
:00405EE7 2D10010000 sub eax, 00000110
:00405EEC 7428 je 00405F16
:00405EEE 48 dec eax
:00405EEF 751D jne 00405F0E
:00405EF1 8B4C2414 mov ecx, dword ptr [esp+14]
:00405EF5 33C0 xor eax, eax
:00405EF7 66837C241C01 cmp word ptr [esp+1C], 0001 ;PCM選択用ボタンのコントロールID
:00405EFD 6A00 push 00000000
:00405EFF 51 push ecx
:00405F00 0F95C0 setne al ;PCM選択用ボタン以外押下でalに値1をセット
:00405F03 A3BCAF4200 mov dword ptr [0042AFBC], eax ;選択フラグ格納先に値をストア
* Reference To: USER32.EndDialog, Ord:00B9h
|
:00405F08 FF155C214100 Call dword ptr [0041215C]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405EEF(C)
|
:00405F0E 33C0 xor eax, eax
:00405F10 83C410 add esp, 00000010
:00405F13 C21000 ret 0010
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00405EEC(C)
|
:00405F16 56 push esi
:00405F17 8B742418 mov esi, dword ptr [esp+18]
:00405F1B 8D542404 lea edx, dword ptr [esp+04]
:00405F1F 52 push edx
:00405F20 56 push esi
:00405F21 E85AC3FFFF call 00402280
:00405F26 8B442418 mov eax, dword ptr [esp+18]
:00405F2A 8B4C2414 mov ecx, dword ptr [esp+14]
:00405F2E 8B542410 mov edx, dword ptr [esp+10]
:00405F32 83C408 add esp, 00000008
:00405F35 6A00 push 00000000
:00405F37 50 push eax
:00405F38 8B44240C mov eax, dword ptr [esp+0C]
:00405F3C 51 push ecx
:00405F3D 52 push edx
:00405F3E 50 push eax
:00405F3F 56 push esi
* Reference To: USER32.MoveWindow, Ord:01C9h
|
:00405F40 FF15B4214100 Call dword ptr [004121B4]
:00405F46 33C0 xor eax, eax
:00405F48 5E pop esi
:00405F49 83C410 add esp, 00000010
:00405F4C C21000 ret 0010