Heroes of Might and Magic IV:居酒屋のバグまたはパッチの古典

この短いストーリーでは、Heroes of Might and MagicIVの非公式modであるEquilibrisプロジェクトによって実行されたプロジェクトの1つについて説明します。リバースエンジニアリングとパッチの両方の観点から、それは特に興味深いものではありません-エンディングだけがやや面白いことが判明しました。



画像


ご存知のように、各居酒屋でのこの一連のゲームでは、プレーヤーは週に1人の新しいヒーローしか雇うことができません。だが…



バグの説明: 外部の居酒屋で募集がなかった場合、8日目から、2日以内に2人のヒーローを購入できます。



最新の公式アドオン「WindsofWar」から分解されたファイルheroes4.exeが作業に使用されます。居酒屋の操作手順は以前にチームによって発見され、アドレス4705E0にあります。その仕事のアルゴリズム全体から、現時点で居酒屋でヒーローを雇うことが可能かどうか、または待つ必要があるかどうかが決定される場所に興味があります。ゲームでは、これは対応するメッセージの出力によって明示されます。





プログラムの観点から、これはNewWindowCreate(720C80)関数を使用してゲームで作成される新しいウィンドウです(ディスアセンブラーで認識される関数には独自の名前が付けられています)。居酒屋の手続きでは、この関数への呼び出しがいくつかあり、最初のチャレンジャーはアドレス470823への呼び出しです。デバッガーの助けを借りて、この呼び出しが実際に目的のダイアログボックスを作成することを確認します。NewWindowCreateへのこの呼び出しを制御するコードは、上記の470645にあります。



00470638                 call    HeroesPricesInTavern_Lost
0047063D                 mov   al, [ebp+48h]  // 0 –   ; 1 –     ( 7 ).
00470640                 add     esp, 8
00470643                 test    al, al
00470645                jz      loc_470866 //   ,      470823


ヒーローの居酒屋で購入し、「ブレークポイント」を設定して[ebp + 48h]宛てのセルに書き込みます。その後、ゲーム内で7日間待ちます。居酒屋が「空になる」と、デバッガーは470DFFでポップアップします。周囲のコードを見てみましょう:



00470DF0 TavernCountDays proc near               
00470DF0                 mov     dl, [ecx+48h] // ECX+48h –   :
DL=0 –   ;
DL=1 –     ( 7 )
00470DF3                 xor     eax, eax 
00470DF5                 cmp     dl, al
00470DF7                 jz      short loc_470E06
00470DF9                 cmp     dword ptr [ecx+4Ch], 7 //  [ECX+4Ch] -         .   7 – . 
00470DFD                 jl      short loc_470E06
00470DFF                mov     [ecx+48h], al  //   (AL=0)
00470E02                 mov     [ecx+4Ch], eax  //   
00470E05                 retn
00470E06
00470E06 loc_470E06:                             
00470E06                                         
00470E06                 inc     dword ptr [ecx+4Ch] //          
00470E09                 retn
00470E09 TavernCountDays endp


この小さな手順は、居酒屋が雇用のために閉鎖されている日数を確認するために使用されます。これは、ゲームの毎日、マップ上のすべての居酒屋に対して呼び出されることに注意してください。バグの原因は何ですか?何らかの理由で、プログラムは主人公が居酒屋で雇われなかった日数と居酒屋が閉まった週の後の日数を数え続けます(470E06のカウンターを見てください)。その結果、次の図が得られます。ヒーローの最初の募集は、ゲームの8日目にのみ行われます。手順の入り口では、[ecx + 48h]の居酒屋利用可能フラグの値は「1」(居酒屋は閉まっています)になり、[ecx + 4Ch]の日カウンターの値は「8」になります。ただし、470DF9での比較後、コントロールは470DFFでコードを受け取ります。これにより、居酒屋が再開されます。これにより、日カウンターがリセットされます。そして2番目のヒーローを雇った後、アルゴリズムは作者が意図したように機能します。しかし、ゲーム内で2週間が経過すると、サイクル全体が繰り返されます。



バグを修正する最も簡単な方法は、日数のカウントを停止することです。居酒屋が閉まっているとき(より論理的です)にのみカウンターを機能させ、残りの時間はそれをゼロに設定します。これは非常に簡単に実現されます-アドレス00470DF7の遷移を関数の最後に変更することによって:



00470DF5                 cmp     dl, al
00470DF7                 jz      short loc_470E09


残っているのは、既存のコードにパッチを適用することだけです。これを行うには、オリジナルを見てください





変更されました





オプション。



ご覧のとおり、アドレス470DF8で0D10に置き換えることで、目的の結果を得ることができますこのジャンルの古典:1バイトだけを置き換えることでバグにパッチを当てます!



All Articles