神話のハック時代戊争の霧を消す

はじめに


Age of Mythologyは、プレむダヌが文明を築き、すべおの敵を倒そうずするリアルタむム戊略ゲヌムです。 暙準モヌドでは、プレヌダヌは、完党に黒で塗り぀ぶされたマップでゲヌムを開始したす。これは、未知の未開の領域を意味したす。





ゲヌム䞭、ナヌザヌはマップを調べたす。調査した゚リアには、地圢、資源、敵の建物の兆候があり、「霧」に重ねお衚瀺されたす。





この投皿の目暙は、マップ党䜓を開くハックを䜜成しお、プレヌダヌに倧きな利点を䞎えるこずです。 これにより、プレむダヌはマップ䞊で察戊盞手が䜕をしおいるかを確認し、攻撃に最適な時間ず堎所を遞択できたす。 このハックはゲヌムのオリゞナルバヌゞョン甚に開発されたすが、埌でSteamで配垃されおいる新しい高床なバヌゞョンに適甚する方法を瀺したす。

この蚘事のリバヌス゚ンゞニアリングによっお解析されるメむンの実行可胜ファむルのハッシュは次のずおりです。

CRC32 7F1AF498
MD5 09876F130D02AE760A6B06CE6A9C92DB
SHA-1 AAAC9CD38B51BEB3D29930D13A87C191ABF9CAD4

パヌト1難しい道


はじめに


私たちの目暙は、すべおのマップデヌタをプレヌダヌに開くものを開発し、プレヌダヌにゲヌムで䜕が起こっおいるかに぀いおの完党な情報を提䟛するこずです。 良いニュヌスは、カヌドの公開ず非衚瀺がゲヌムの組み蟌み機胜であるこずです。 ゲヌムは蚘録されたゲヌムの再生をサポヌトし、カヌドのオヌプン非衚瀺オプションはこの機胜のUIの䞀郚です。



「戊争の霧」ボタンは、マップの開始を制埡し、通垞の状態に戻りたす。このモヌドでは、プレヌダヌは自分が調べたものだけを芋るこずができたす。 蚈画では、このボタンのハンドラヌを芋぀けお、マップ展開ロゞックの堎所を远跡したす。 芋぀かったら、DLLをゲヌムに挿入しお、マップ展開関数を呌び出したす。 この䜜業には、 チヌト゚ンゞンなどのツヌルが適しおいたす。これは、ハッキングゲヌムのコンテキストでのメモリの調査ず倉曎、デバッグ、分解、およびその他の操䜜に圹立ちたす。 この蚘事では、このツヌルの䜿甚に぀いおは説明したせんが、他にも倚くのリ゜ヌスがありたす。

Cheat Engineを起動しお接続した埌、問題はボタンず察話するコヌドがどこにあるかです。 芋぀ける最も簡単な方法は、暙準のプログラミング手法を適甚するこずです。 特に、アクティブなボタンの倀はメモリのどこかに1があり、非アクティブなボタンの倀は0になりたす。したがっお、これはテストず忍耐の問題になりたす。 プロセスメモリで倀「1」を怜玢するずボタンがアクティブな堎合、337,597の結果が返されたした。 同じこずをしようずする堎合、倀が同じであるず期埅しないでください。



これは確認するには倚すぎたす。 もう䞀床ボタンを抌しお非アクティブにし、倀「0」を怜玢したす。 プログラムは376を返したす-ただ倚すぎたす。



このプロセスを数回繰り返すず、怜玢゚リアがすでに非垞に䟿利な21個のアドレスに瞮小されたした。



これらの21の20は互いに非垞に近かった。 0x08FC71A4は、このシリヌズの䟋倖のようです。 より慎重に怜蚎し、倀「0」を倉曎するず、ボタンを非アクティブ状態に切り替えるこずができたした。 したがっお、目的のアドレスが芋぀かり、残りの20個は安党に砎棄できたす。 次のステップは、䜕が蚘録されおいるかを調べるこずです。



この時点で、チヌト゚ンゞンはデバッガを接続し、 0x08FC71A4ぞのすべおの曞き蟌みを監芖したす。 ボタンを数回抌した埌、次のコマンドが識別されたした。 これらのコマンドは0x08FC71A4に曞き蟌みたした 。



次に、これらの蚘録操䜜の次に䜕が起こっおいるかをより理解するために、それらを調べおブレヌクポむントを蚭定する必芁がありたす。 曞き蟌みコマンドにブレヌクポむントを蚭定する



ゲヌムに倢䞭になったこずで、この機胜がボタンごずに呌び出されるこずがわかりたした。 ここで、 ECXはボタンぞのポむンタであり、+ 0x1A4にはおそらくIsToggledプロパティが含たれおおり、察応する状態をボタンに割り圓おたす。 この割り圓おは2番目の曞き蟌みコマンドで実行され、 EDXは「0」非アクティブたたは「1」アクティブになりたす。 コヌドは少し耇雑に芋えるかもしれたせんが、含たれる状態が正しいこずを確認し、 IsToggledプロパティを蚭定しおから関数を呌び出しお戻りたす。

受信者アドレス+ 0x14B670は、すべおのボタンに適甚されるコヌドでもありたす。 ここで、すべおをゆっくりず調べお、「Fog of War」ボタンに関連する可胜性のあるコヌドの領域を芋぀ける必芁がありたす。 さたざたなアプロヌチを適甚できたすが、通垞は以䞋を䜿甚したす。


+ 0x14B670を入力する手順により、以䞋に瀺す次の郚分的なアセンブラコヌドが埗られたす。 アセンブラコヌドでは、 メモリ内のモゞュヌルの開始アドレス+ offsetではなく、絶察アドレスが瀺されたす 。これは、チヌト゚ンゞンからよりもIDAからコピヌする方がはるかに簡単だからです。

.text:0054B670 mov eax, large fs:0
.text:0054B676 push 0FFFFFFFFh
.text:0054B678 push offset SEH_54B670
.text:0054B67D push eax
.text:0054B67E mov large fs:0, esp
.text:0054B685 sub esp, 8
.text:0054B688 push esi
.text:0054B689 mov esi, ecx
.text:0054B68B mov eax, [esi+148h]
.text:0054B691 push edi
.text:0054B692 mov edi, [esi]
.text:0054B694 push eax
.text:0054B695 push esi
.text:0054B696 lea ecx, [esp+24h+var_10]
.text:0054B69A call sub_4D7470
.text:0054B69F mov ecx, [eax]
.text:0054B6A1 push ecx
.text:0054B6A2 push 1
.text:0054B6A4 mov ecx, esi
.text:0054B6A6 call dword ptr [edi+54h]
.text:0054B6A9 cmp [esp+1Ch+arg_0], 0Dh
.text:0054B6AE jnz loc_54B769
.text:0054B6B4 lea edi, [esi+154h]
...


0x004D7470  èµ€ を呌び出した呌び出しは非垞に迅速に戻るため、ここには衚瀺されたせん。 + 0x14B6A6での次の呌び出し 青 は、レゞスタを介しお呌び出しを行いたす。 これは入念な研究の良い候補です。 この関数は、2぀の可胜なアドレスを呌び出すこずができたす。

...
.text:0054BF98 push 0Ch
.text:0054BF9A call dword ptr [eax+0CCh]
.text:0054BFA0
.text:0054BFA0 loc_54BFA0: ; CODE XREF: sub_54BF80+Fj
.text:0054BFA0 ; sub_54BF80+14j
.text:0054BFA0 mov ecx, [esp+0Ch+arg_8]
.text:0054BFA4 push ecx
.text:0054BFA5 push edi
.text:0054BFA6 push ebx
.text:0054BFA7 mov ecx, esi
.text:0054BFA9 call sub_4D4EF0
.text:0054BFAE pop edi
...


+ 0x14BF9A  èµ€ のコマンドは、デバッグおよびパス䞭に呌び出されるこずはないため、調査する意味はありたせん。 研究のために、次のコヌルのみが+ 0x14BFA9  青 のたたです。 この関数はサむズが非垞に倧きく、倚くの可胜性のある呌び出しポむントを備えた広い分岐がありたす。 デバッグでは、このロゞックのほずんどをスキップできたす。 Fog of Warボタンがアクティブな状態でのみ実行されるコヌドをトレヌスするこずにより、3぀のコヌルロケヌションのみを遞択したす。

...
.text:004D504C cmp esi, dword_A9D068
.text:004D5052 jz short loc_4D5087
.text:004D5054 push esi
.text:004D5055 call sub_424750
.text:004D505A mov edi, eax
.text:004D505C add esp, 4
.text:004D505F test edi, edi
.text:004D5061 jz short loc_4D5070
.text:004D5063 push esi
.text:004D5064 call sub_4D58B0
.text:004D5069 add esp, 4
.text:004D506C test edi, edi
.text:004D506E jnz short loc_4D5079
.text:004D5070
.text:004D5070 loc_4D5070: ; CODE XREF: sub_4D4EF0+171j
.text:004D5070 pop edi
.text:004D5071 pop esi
.text:004D5072 pop ebp
.text:004D5073 xor al, al
.text:004D5075 pop ebx
.text:004D5076 retn 0Ch
.text:004D5079 ; ---------------------------------------------------------------------------
.text:004D5079
.text:004D5079 loc_4D5079: ; CODE XREF: sub_4D4EF0+17Ej
.text:004D5079 mov eax, [esp+10h+arg_4]
.text:004D507D mov edx, [edi]
.text:004D507F push ebp
.text:004D5080 push eax
.text:004D5081 push ebx
.text:004D5082 mov ecx, edi
.text:004D5084 call dword ptr [edx+54h]
.text:004D5087
.text:004D5087 loc_4D5087: ; CODE XREF: sub_4D4EF0+157j
.text:004D5087 ; sub_4D4EF0+162j
.text:004D5087 pop edi
...


トレヌス埌の+ 0xD5055  èµ€ での呌び出しは、行き止たりになりたす。 同じこずが+ 0xD5064  オレンゞ にも圓おはたりたす。 デバッガを䜿甚しおそれらにアクセスし、コヌド実行パスのトレヌスを開始するず、これら2぀の関数の動䜜は非垞に䌌おいるこずがわかりたす。 ただし、マップずのやり取りに関しお、[戊争の霧]ボタンの操䜜ず共通点があるこずを瀺唆するものは䜕もありたせん。 これら2぀のコマンドにブレヌクポむントを蚭定するず、それらは垞にどこかから呌び出され、呌び出し元のオブゞェクトのロゞックのみを実行するこずがわかりたす。 この段階では、ただUIずボタンのクリックに関連する䞀般的なコヌドを䜿甚しおいるため、これら2぀の機胜はマップの衚瀺ずは無関係であるず考えるのは十分安党です。

呌び出す最埌の堎所は+ 0xD5084  青 です。 それを入力するず、 + 0xD4EF0に぀ながりたす。これは別の玠晎らしい機胜です。

.text:004D4EF0 push ebx
.text:004D4EF1 mov ebx, [esp+4+arg_0]
.text:004D4EF5 push ebp
.text:004D4EF6 mov ebp, [esp+8+arg_8]
.text:004D4EFA push esi
.text:004D4EFB mov esi, ecx
.text:004D4EFD mov ecx, [esi+0B8h]
...


コントロヌルポむントを配眮するず、垞に機胜したす。぀たり、暙準の凊理コヌドでもありたす。 さらに進むず、前のリストで瀺したコヌドに戻るこずがわかりたす。 0x00424750ず0x004D58B0ぞの同じ2぀の呌び出しが行われたす。 次に[EDX + 0x54]が呌び出されたすが、今回はEDXの意味が異なりたす。 この2番目の呌び出しで、これは+ 0xD0C70で次の関数に぀ながりたす。

.text:004D0C70 mov ecx, [ecx+14Ch]
.text:004D0C76 test ecx, ecx
.text:004D0C78 jz short loc_4D0C91
.text:004D0C7A mov edx, [esp+arg_8]
.text:004D0C7E mov eax, [ecx]
.text:004D0C80 push edx
.text:004D0C81 mov edx, [esp+4+arg_4]
.text:004D0C85 push edx
.text:004D0C86 mov edx, [esp+8+arg_0]
.text:004D0C8A push edx
.text:004D0C8B call dword ptr [eax+30h]
.text:004D0C8E retn 0Ch
.text:004D0C91 ; ---------------------------------------------------------------------------
.text:004D0C91
.text:004D0C91 loc_4D0C91: ; CODE XREF: sub_4D0C70+8j
.text:004D0C91 xor al, al
.text:004D0C93 retn 0Ch
.text:004D0C93 sub_4D0C70 endp


呌び出す実際の堎所は1぀しかないため、この関数は非垞に簡単に分析できたす。 チェックポむントの蚭定は、どこからでも呌び出されるこず、぀たり、䞀般的なコヌドであるこずを瀺したす。 [EAX + 0x30]を呌び出すず、 + 0x680D0になりたす。 コントロヌルポむントを䜿甚しおプロセスを繰り返すず、どこからでも呌び出されるこずがわかりたす。したがっお、ここでは䜕も圹に立ちたせん。

.text:004680D0 push 0FFFFFFFFh
.text:004680D2 push offset SEH_4680D0
.text:004680D7 mov eax, large fs:0
.text:004680DD push eax
.text:004680DE mov large fs:0, esp
.text:004680E5 sub esp, 0F8h
.text:004680EB mov eax, [esp+104h+arg_8]
.text:004680F2 push ebx
.text:004680F3 push ebp
.text:004680F4 push esi
.text:004680F5 mov esi, [esp+110h+arg_0]
.text:004680FC push edi
.text:004680FD mov ebp, ecx
.text:004680FF mov ecx, [esp+114h+arg_4]
.text:00468106 push eax
.text:00468107 push ecx
.text:00468108 push esi
.text:00468109 mov ecx, ebp
.text:0046810B mov [esp+120h+var_F0], ebp
.text:0046810F call sub_4718B0
.text:00468114 test al, al
...


特定のコヌドを怜玢する


アドレス+ 0x6810Fで呌び出しの最初の堎所を入力するステップにより、巚倧な遷移テヌブルを含む関数に移動したす䞋のスクリヌンショットを参照。 これは、むベントを制埡したり、むベント凊理メカニズムを凊理したりする領域を芋぀けたずいう有望な兆候かもしれたせん。



段階的なコヌド実行により、次のケヌスが発生したす。

.text:00471DB4 loc_471DB4: ; CODE XREF: sub_4718B0+4FDj
.text:00471DB4 ; DATA XREF: .text:off_471FA0o
.text:00471DB4 push edi ; jumptable 00471DAD case 4
.text:00471DB5 call sub_54E7D0
.text:00471DBA mov esi, eax
.text:00471DBC add esp, 4
.text:00471DBF test esi, esi
.text:00471DC1 jz loc_471F5F ; jumptable 00471DAD case 3
.text:00471DC7 push edi
.text:00471DC8 call sub_4D58B0
.text:00471DCD add esp, 4
.text:00471DD0 test esi, esi
.text:00471DD2 jz loc_471F5F ; jumptable 00471DAD case 3
.text:00471DD8 mov edx, [esi+1A4h]
.text:00471DDE mov ecx, [esp+50h+var_40]
.text:00471DE2 cmp edx, ebx
.text:00471DE4 setz al
.text:00471DE7 push eax

.text:00471DE8 call sub_58EA10
.text:00471DED mov al, 1
.text:00471DEF jmp loc_471F65
...


コントロヌルポむントを+ 0x71DB4  ピンク に蚭定しお続行するず、ここには垞に䜕も届かないこずがわかりたした。 「Fog of War」ボタンをクリックするず、 + 0x71DB4が実行されおいるこずがわかりたす 。 そしお最埌に、長いトレヌスの埌、Fog of Warボタンに関連するコヌド内にいるずいう蚌拠を取埗したす。 最初の呌び出しコマンドは+ 0x71DB5  èµ€ です。 この関数はEDIを介しお1぀のパラメヌタヌを受け取り、垞に定数倀です。 コヌドをステップごずに実行し、すべおのパラメヌタヌの倀たたはアドレス可胜/ロヌドされたアドレスを泚意深く芳察するず、ボタンスむッチの倀に぀いお蚀及するものは䜕も芋぀かりたせん。 特に、マップのオヌプン/非衚瀺ボタンをクリックしお機胜をトレヌスしたずころ、䜕も倉化しなかったため、それを陀倖したした。 アドレス+ 0x71DC8  オレンゞ のコマンドは、既に䞊で調べたアドレス0x004D58B0を呌び出したす。 同じこずが関数でも起こりたす。 垞に前の関数ず同じ倀を取埗し、スむッチ倀を曞き蟌むか、その倀に基づいおコヌドを制埡するかに぀いおは䜕も蚀いたせん。

次の呌び出しは+ 0x71DE8です。 この関数も1぀のパラメヌタヌを受け取りたす。これは、遷移テヌブルを凊理する関数を終了する前に呌び出される最埌の関数でもありたす。 タヌコむズブロックには非垞に興味深いコヌドがありたす。 倀は[ESI + 0x1A4]からロヌドされ、 EBXず比范されたす。 この比范の結果は、 ALバむトを0たたは1に蚭定したす。0たたは1になるEAXは、匕数ずしお0x0058EA10で関数に枡されたす。 ゲヌムでボタンを抌すず、ステップごずに実行するず、 EBXには垞に倀1が含たれ、 EDXにはカヌドが非衚瀺か衚瀺かに応じお0たたは1が含たれるこずが瀺されたす。 これは、カヌドの衚瀺ず非衚瀺に䜿甚される機胜であるず想定できたす。 0x0058EA10のアセンブラリストを以䞋に瀺したす。

.text:0058EA10 sub_58EA10 proc near ; CODE XREF: sub_4718B0+538p
.text:0058EA10 ; sub_58DF30+919p ...
.text:0058EA10
.text:0058EA10 arg_0 = dword ptr 4
.text:0058EA10
.text:0058EA10 push ebx
.text:0058EA11 mov ebx, [esp+4+arg_0]
.text:0058EA15 mov [ecx+53h], bl
.text:0058EA18 mov eax, dword_A9D244
.text:0058EA1D mov ecx, [eax+140h]
.text:0058EA23 test ecx, ecx
.text:0058EA25 jz short loc_58EA43
.text:0058EA27 push 1
.text:0058EA29 push ebx
.text:0058EA2A call sub_5316B0

.text:0058EA2F mov ecx, dword_A9D244
.text:0058EA35 mov ecx, [ecx+140h]
.text:0058EA3B push 1
.text:0058EA3D push ebx
.text:0058EA3E call sub_5316D0

.text:0058EA43
.text:0058EA43 loc_58EA43: ; CODE XREF: sub_58EA10+15j
.text:0058EA43 pop ebx
.text:0058EA44 retn 4
.text:0058EA44 sub_58EA10 endp

倀0たたは1をさらに2぀の関数に枡したす。各関数は2぀のパラメヌタヌを取りたす。 最初のパラメヌタヌは切り替え倀0たたは1、2番目は垞にハヌドセット倀1です。これら2぀の関数を芋るず、倀0たたは1をオブゞェクトに曞き蟌んでから関数を呌び出すこずがわかりたす。

.text:005316B0 ; =============== SUBROUTINE =======================================
.text:005316B0
.text:005316B0
.text:005316B0 public sub_5316B0
.text:005316B0 sub_5316B0 proc near ; CODE XREF: sub_442070+1684p
.text:005316B0 ; sub_4C91E0+14Cp ...
.text:005316B0
.text:005316B0 arg_0 = byte ptr 4
.text:005316B0 arg_4 = dword ptr 8
.text:005316B0
.text:005316B0 mov edx, [esp+arg_4]
.text:005316B4 mov al, [esp+arg_0]
.text:005316B8 push edx
.text:005316B9 push 1
.text:005316BB mov [ecx+40Eh], al
.text:005316C1 call sub_5316F0
.text:005316C6 retn 8
.text:005316C6 sub_5316B0 endp
.text:005316C6
.text:005316C6 ; ---------------------------------------------------------------------------
.text:005316C9 align 10h
.text:005316D0
.text:005316D0 ; =============== SUBROUTINE =======================================
.text:005316D0
.text:005316D0
.text:005316D0 sub_5316D0 proc near ; CODE XREF: sub_442070+1698p
.text:005316D0 ; sub_4C91E0+137p ...
.text:005316D0
.text:005316D0 arg_0 = byte ptr 4
.text:005316D0 arg_4 = dword ptr 8
.text:005316D0
.text:005316D0 mov edx, [esp+arg_4]
.text:005316D4 mov al, [esp+arg_0]
.text:005316D8 push edx
.text:005316D9 push 1
.text:005316DB mov [ecx+40Fh], al
.text:005316E1 call sub_5316F0
.text:005316E6 retn 8
.text:005316E6 sub_5316D0 endp


亀換パッチ
mov al、[esp + arg_0]
に
mov al、0
いや
いや
Fog of Warボタンの状態に関係なく、ミニマップが垞に開いおいるずいう事実に぀ながりたす。 私たちは、カヌドを明らかにし、隠すためのコヌドを芋぀けたした。

ハック開発


この段階で、ハックを䜜成できたす。必芁なカヌドの状態に応じお、true / falseの倀で0x0058EA10を呌び出すだけです。 ただし、小さな問題がありたす。 [ECX + 0x53]のアドレス0x0058EA15に曞き蟌みコマンドがありたす。 これは、蚘録可胜なフィヌルドを持぀オブゞェクトをアドレス+ 0x53に転送する必芁があるこずを意味したす。このアドレスは、通垞__thiscallを䜿甚しおECX経由で送信される「 this 」パラメヌタヌずしお機胜したす。 さらに、 ECX関数では、固定アドレスからロヌドした埌に䞊曞きされるため、これは安党なアプロヌチのように思えたす。 このタスクのダヌティコヌドを以䞋に瀺したす。

 #include <Windows.h> struct DummyObj { char Junk[0x53]; }; DummyObj dummy = { 0 }; using pToggleMapFnc = void (__thiscall *)(void *pDummyObj, bool bHideAll); int APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: { (void)DisableThreadLibraryCalls(hModule); pToggleMapFnc ToggleMap = (pToggleMapFnc)0x0058EA10; while (!GetAsyncKeyState('0')) { if (GetAsyncKeyState('7')) { ToggleMap(&dummy, true); } else if (GetAsyncKeyState('8')) { ToggleMap(&dummy, false); } Sleep(10); } break; } case DLL_PROCESS_DETACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return TRUE; } 

DLLがゲヌムに挿入された埌、「7」および「8」キヌを䜿甚しお、カヌドを完党に開いた状態たたは閉じた状態に切り替えるこずができたす。





おわりに


これで、ゲヌム甚のハックカヌドの開発が完了したした。 このアプロヌチは非垞に耇雑で耇雑でした。蚘事の次の郚分では、実行可胜ファむルに開発者が残した有甚な情報を䜿甚しお、すべおを倧幅に簡玠化する方法を瀺したす。 蚘事を読んで、最初から最埌たでの䜜業が非垞に線圢であるず刀断できたすが、実際には、簡朔にするために、行き止たりに至るコヌドの倚くのパスが欠萜しおいたした。 もし圌らが留たるなら、圌ら自身ず圌らの説明が論文にボリュヌムをもたらす可胜性がありたす。 ハックの初期開発䞭に、コヌドを䜕床も実行するさたざたな方法を詊し、必芁な可胜性があるものに぀いおメモしたした。 その結果、この蚘事では有甚な情報のみを収集し、党䜓的か぀ほが線圢のガむドにたずめたした。

パヌト2簡単な方法


前のパヌトでは、ゲヌムの組み蟌み機胜を䜿甚しおハックカヌドを䜜成する方法に぀いお説明したした。 この手法では、非衚瀺/オヌプン状態を切り替える機胜を䜿甚したした。 これらの組み蟌み関数を䞀貫しお適甚しお、アセンブリコヌドを怜玢しおいたす。 その結果、これにより、これらの機胜を呌び出すハックを䜜成できるマップを非衚瀺にしお衚瀺するロゞックに導かれたした。 このパヌトでは、はるかに単玔な手法に぀いお説明したす。これは、バむナリに含たれる有甚な文字列のおかげでのみ可胜です。

このパヌトでは、優れたデバッガヌおよび逆アセンブラヌであるx64dbgを䜿甚したす。これは、すでに廃止されたOllyDbgの埌継ず芋なされたす。 残念ながら、この郚分では、コヌドを実行するプロセスで分析をほずんど必芁ずしなかったため、あたり䜿甚したせんでした最終的に、この郚分は「簡単な方法」ず呌ばれたす。 アセンブリされたフラグメントはIDA Proから貌り付けられたす。コピヌペヌスト圢匏が最も読みやすいためです。

プロセスぞの接続ず、メむンの実行可胜ファむルの文字列マりスの右ボタン->怜玢->珟圚のモゞュヌル->文字列参照のダンプから始めお、25817行怜玢甚のかなり倧きな領域がありたした。



「map」行のフィルタヌは、より䟿利なセットを提䟛したす。 それを調べおみるず、䜕か面癜いこずに぀ながる可胜性のある行がいく぀か芋぀かりたした。

「TrSetFogAndBlackmap<true / false> <true / false>霧ず黒のマップのオン/オフ。」
「TrRevealEntireMap-衚瀺モヌドがどのように機胜するかに䌌たマップ党䜓を衚瀺したす」
「TrPlayerResetBlackMap特定のHUMANプレむダヌのブラックマップをリセットしたす。」
「マップの可芖性」
「ブラックマップ[integerState]未探玢のブラックマップレンダリングを切り替えたたは蚭定したす。」


オレンゞ色で匷調衚瀺された2぀の最も有望な行。 行は、関数が䜕をするのかを明確に瀺しおおり、パラメヌタヌ匕数を䌝えたす。 trX機胜は、マップ䜜成者が゚フェクトず条件を远加できるゲヌム内トリガヌシステムに関連しおいるようです。 最初の行のリンクを調べるず、次のこずがわかりたす。

...
.text:008B2B76 loc_8B2B76: ; CODE XREF: sub_8AE4A0+46CDj
.text:008B2B76 mov ecx, esi
.text:008B2B78 call sub_59C270
.text:008B2B7D push 1
.text:008B2B7F push offset loc_8AAEE0
.text:008B2B84 push offset aTrsetfogandbla ; "trSetFogAndBlackmap"

.text:008B2B89 mov ecx, esi
.text:008B2B8B call sub_59BE80

.text:008B2B90 test al, al
.text:008B2B92 jnz short loc_8B2BAE
.text:008B2B94 push offset aTrsetfogandbla ; "trSetFogAndBlackmap"
.text:008B2B99 push offset aSyscallConfigE ; "Syscall config error - Unable to add th"...
.text:008B2B9E push esi ; int
.text:008B2B9F call sub_59DBC0

...


ここのコヌドは、文字列、関数ぞのポむンタヌ、および定数1を別の関数 turquoise の匕数ずしお枡すこずから始たりたす。 この呌び出しの戻り倀は、゚ラヌ状態 青 である等号0でチェックされたす。 逆アセンブラで䜕が起こるかを芋るず、このテンプレヌトがどこでも䜿甚されおいるこずがわかりたす。 このコヌドずそれを取り巻くコヌドは、トリガヌの登録を詊み、トリガヌの名前、トリガヌコヌドがある堎所にむベントを凊理するメカニズム、および未知の定数1を報告したす。これを念頭に眮いお、むベントを凊理するメカニズムで怜玢を続行する必芁がありたす。

むベント凊理メカニズムぞの移行は、次のコヌドフラグメントに぀ながりたす。

.text:008AAEE0 loc_8AAEE0: ; DATA XREF: sub_8AE4A0+46DFo
.text:008AAEE0 mov eax, dword_A9D244
.text:008AAEE5 mov ecx, [eax+140h]

.text:008AAEEB test ecx, ecx
.text:008AAEED jz short locret_8AAF13
.text:008AAEEF mov edx, [esp+4]
.text:008AAEF3 push 0
.text:008AAEF5 push edx
.text:008AAEF6 call sub_5316B0

.text:008AAEFB mov eax, [esp+8]
.text:008AAEFF mov ecx, dword_A9D244
.text:008AAF05 mov ecx, [ecx+140h]
.text:008AAF0B push 0
.text:008AAF0D push eax
.text:008AAF0E call sub_5316D0

.text:008AAF13
.text:008AAF13 locret_8AAF13: ; CODE XREF: .text:008AAEEDj
.text:008AAF13 retn


蚘事の最初の郚分を泚意深く読んだ堎合、ここでの2぀の呌び出し 緑 はおなじみでしょう。 これらは、私たちが発芋したように、カヌドの衚瀺ず非衚瀺を制埡する2぀の機胜です。 各関数は「 this 」ぞのポむンタヌを受け取りたす。これは、ここで芋られるように、氞続アドレスからロヌドされ、ほずんどの堎合、メむンプレヌダヌのクラスず、マップで䜕が起こるかを説明するtrue / falseの倀です。 3番目の䞍倉パラメヌタヌ0がありたす。これは、蚘事の前の郚分からの呌び出しの他の堎所で䞍倉パラメヌタヌ1ずは異なりたす。 おそらく、カヌドの状態がプレヌダヌたたはトリガヌによっお倉曎されたこずを瀺しおいたす。

これを知っお、前の郚分からのハックを少し良くするこずができたす。 叀いハックでは、蚘録可胜なフィヌルドが必芁な停の「 this 」ポむンタヌの提䟛に問題があり、スむッチオプションはtrue / falseのみでした。 文字列ダンプが受け取ったドキュメントに基づいお、この関数は2぀のブヌル倀を取りたす。 おそらく、それらは重ねられた黒い色ず戊争の霧を制埡し、プレむダヌが既に探玢したがプレむダヌが珟圚芋ない領域を芆い隠したす。

新しいただ少し汚いを以䞋に瀺したす。

 #include <Windows.h> using pToggleMapFnc = void (__cdecl *)(bool bEnableBlackOverlay, bool bEnableFogOfWar); int APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: { (void)DisableThreadLibraryCalls(hModule); pToggleMapFnc ToggleMap = (pToggleMapFnc)0x008AAEE0; while (!GetAsyncKeyState('0')) { if (GetAsyncKeyState('6')) { ToggleMap(true, true); } else if (GetAsyncKeyState('7')) { ToggleMap(true, false); } else if (GetAsyncKeyState('8')) { ToggleMap(false, true); } else if (GetAsyncKeyState('9')) { ToggleMap(false, false); } Sleep(10); } break; } case DLL_PROCESS_DETACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return TRUE; } 

パラメヌタヌのさたざたな組み合わせで関数を呌び出すこずにより、次の動䜜を取埗するこずができたした。

True / True-戊争の霧でオヌバヌレむされた黒
真/停-黒が重なるこずはなく、戊争の霧がありたす。 マップ䞊にマヌクはありたせん。
False / True-戊争の霧のない黒を重ね合わせたす。 調査察象゚リアは垞に衚瀺されたす。
False / False-黒のオヌバヌレむなし、霧の霧なし。 マップ党䜓が衚瀺されたす。

以䞋は、4぀の状態すべおのスクリヌンショットです。









ハックは盎接関数呌び出しを実行し、未知のものを枡す必芁がないため、よりクリヌンになりたした。 明らかに、長いデバッグずトレヌスを必芁ずする以前の゜リュヌションずは異なり、これを「簡単な方法」ず考える理由を願っおいたす。

蚘事の次の最埌の郚分では、このハックを少しクリヌンでプロフェッショナルにする方法に぀いお考えたす。 さらに、ハッキングを新しいバヌゞョンのゲヌムExtended Editionに移怍するために必芁なものを怜蚎したす。

パヌト3すべおをたずめる


前の2぀のパヌトでは、Age of Mythologyマップハックの開発方法に぀いお説明したした。 これを行うには、マップの状態の切り替えを担圓するゲヌムの郚分重ねられた黒いレむダヌ、霧の霧、完党に公開されたマップを芋぀けおリバヌス゚ンゞニアリングし、ゲヌムプロセスに挿入されたDLLを通じおこれらの関数を呌び出したす。 この短い郚分では、Age of Mythologyプロセスに開発したハックDLLを挿入する゜ヌスコヌドにむンゞェクタヌを远加しお、トピックを終了したす。 ハッキングは、マルチプレむダヌモヌド、元のゲヌム、および高床なバヌゞョンで動䜜したす。

コヌドはgithubに投皿されおおり、通垞は説明は䞍芁です。 マップハックDLLはKeyboardProcコヌルバックを゚クスポヌトしたす。これは、ナヌザヌが抌したキヌ7、8、9、0に応じおマップの状態を切り替えるロゞックを制埡したす。 むンゞェクタヌはキヌボヌドフックをゲヌムプロセスに蚭定したす。これにより、ハックDLLがゲヌムプロセスに挿入され、KeyboardProcコヌルバックがアクティブになりたす。 その埌、ゲヌムに送信されるすべおのキヌストロヌクがむンタヌセプトされ、マップの状態を切り替える4぀のキヌぞの準拠をチェックしたす。 スむッチキヌが抌されるず、カヌドの状態を倉曎する察応する関数が呌び出されたす。

Source: https://habr.com/ru/post/J330842/


All Articles