
ご存知のように、各居酒屋でのこの一連のゲームでは、プレーヤーは週に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で0Dを10に置き換えることで、目的の結果を得ることができます。このジャンルの古典:1バイトだけを置き換えることでバグにパッチを当てます!