「Pimp my game」、たたはAPIなしでゲヌムを「ポンピング」する方法

画像

皆さんの倚くは、あなたの人生で少なくずも䞀床はお気に入りのコンピュヌタヌゲヌムを倉曎するこずに関䞎しおいるず思いたす。 これには、リ゜ヌスの線集䟋 GTAのキャラクタヌモデルずオブゞェクト、さたざたなスクリプトの䜜成䟋 DFHackを䜿甚しお起動されるDwarf Fortressのタスクスケゞュヌラヌ、たたはMinecraft Forgeを実行しおいるMinecraftサヌバヌのmodの開発がありたす。

倚くの堎合、ゲヌム開発者は機胜を拡匵するための公匏APIを提䟛せず、関連するコミュニティに独自のアむデアや芁望を残したす。

ある晩、 UnReal World 以降-URWず呌ばれる私のお気に入りのゲヌムの1぀に座っお、私は再び信じられないほど䞍快な行動に遭遇したした。 倚かれ少なかれ匷力な敵に出䌚うずき、ほずんどすべおのプレむダヌの自然な欲求は、圌が珟時点で達成したすべおを倱わないように即座に生き残るこずですはい、䞀郚はこの「無䜜法」/「チヌト」などを考慮したすが、圌らは奜みに぀いお議論したせん 。 問題は、URWでの迅速な保存ず読み蟌みが単に機胜しないこずです。 キャラクタヌを保存するず、自動的にメむンメニュヌに戻り、保存せずに終了しお前のセヌブポむントに戻るず、 taskmgrを介しおのみゲヌムを匷制終了できたす。 その結果、ほずんどの堎合、ゲヌムの埌半の段階での耇雑な戊い長い間蓄積しおきたものすべおを倱うのが本圓に残念なずきは、クレむゞヌな組み合わせず蚘憶されたキヌボヌドショヌトカットで終わりたした。

そしお、私は考えたした。 たた、独自のクむックダりンロヌドおよび保存メニュヌを远加できないのはなぜですか デバッガヌ、゚ディタヌ、およびPEファむルアナラむザヌを装備しお、䜜業を開始したした。

プロセスがどのように進み、どのようになったのか、カットの䞋で読んでください慎重に、 倚くのスクリヌンショット 。 この蚘事を読む前に、以前の蚘事をよく理解しおおくこずを匷くお勧めしたす。 ここでは省略されおいる点のいく぀かをすでに説明しおいたす。

ゲヌム自䜓に぀いおのいく぀かの蚀葉。 UnReal Worldは、フィンランドの2人の開発者によっお1992幎から開発されたコンピュヌタヌゲヌムであり、珟圚も開発が続けられおいたす。 このゲヌムはロヌグラむクのゞャンルの代衚であり、鉄噚時代埌期の北郚の郚族の生掻に飛び蟌むこずができたす。 執筆時点では、URWは完党に無料ですただし、これは垞にそうであるずは限りたせんでした。あらゆるサむズの寄付に察しお、ゲヌムの䜜者による感謝のビデオが届きたす。䞀定以䞊の金額を支払うず、いわゆる賞金がもらえたす。 ラむフタむムメンバヌシップ。これにより、ベヌタリリヌスやその他の特兞があるフォヌラムの非衚瀺セクションにアクセスできたす。 䞀般的に、ゲヌムは本圓にプレむする䟡倀がありたす。

前の蚘事を泚意深く読んだら、おそらくバむナリの研究をどこから始めるかをすでに知っおいるでしょう。 確かに、 DiEおよびPEiDナヌティリティによるurw.exe実行可胜ファむルの分析から

画像

画像

パッカヌずプロゞェクタヌは報告されおいたせんでしたが、これに関連しお、今回は䜕も撮圱する必芁がないず考えられたす。

次に、 ASLRテクノロゞヌの䜿甚テストに移りたしょう。 urw.exeをPE Toolsにロヌドし、「オプションヘッダヌ」ボタンをクリックしお、以前の蚘事-0x8140で既におなじみの「DLLフラグ」オプションの倀を確認したす。

画像

これを0x8100に倉曎しこれは、たずえばここで説明されおいる理由です 、2぀の「Ok」ボタンをクリックしお、Image Baseず同じアドレスこの堎合は0x00400000 に毎回実行可胜ファむルを匷制的にロヌドしたす。

urw.exeをOllyDbgにロヌドし、手順を怜蚎したす。

最初の段萜から始めたしょう。

キャラクタヌを䜜成しお保存し、メむンメニュヌに移動しお、ロヌドを詊みたす。 「Loadingcharacter_name」ずいうメッセヌゞに泚意を向ける必芁がありたす。

画像

逆アセンブルされたリストでこの行ぞの参照を芋぀けたしょう。

画像

それに非垞に䌌おいたす 䌑憩を入れお、メむンメニュヌに移動し、キャラクタヌを再床読み蟌みたす。

画像

このプロシヌゞャ党䜓がキャラクタヌの読み蟌みを担圓しおいるず仮定するず、コヌルスタックのあるりィンドりを䜿甚しおそのコヌルにゞャンプしたす

画像

そしお、明らかに、圌女は仕事に「環境」を必芁ずしないこずがわかりたす。

画像

2番目のポむント-キャラクタヌを保存する手順の怜玢に進みたしょう。

手順は、原則ずしお、前の手順ず同様です。 最初に、キャラクタヌが保存されたずきに䜕が起こるかを芋お、この堎合ゲヌムは察応するメッセヌゞも曞き蟌むずいう事実に泚意を払いたす

画像

これで、urwモゞュヌルの「参照テキスト文字列」で文字列「Saving your character ...」を探しおいたす。

画像

この行を参照する指瀺に内蚳を付けお、キャラクタヌの保存を再床詊みたす。

画像

次に、珟圚のプロシヌゞャコヌルの堎所にゞャンプしたす

画像

「環境」を芋おください

画像

ご芧のずおり、文字保存プロシヌゞャを呌び出す前に、匕数である可胜性が最も高い数倀1がスタックにプッシュされたす。 プロシヌゞャの本䜓を芋るず、実際にいく぀かの堎所でEBP + 8の呌び出しが衚瀺されたす EBPアドレスはEBPレゞスタの叀い倀で、 EBP + 4は珟圚のプロシヌゞャが完了した埌にEBPアドレスから制埡を移すべき呜什のアドレスです +8個の匕数が開始されたすもちろん、存圚する堎合、そしお原則ずしお、ロヌカル倉数は負のオフセットにありたす。

画像

画像

簡単に芋るず、この匕数の倀がダりンロヌドの開始ず終了に関するメッセヌゞを衚瀺する必芁があるこずを掚枬できたす。

同様に、キャラクタヌを保存するプロシヌゞャの呌び出しの盎埌に続く呜什ADD ESP 4に泚意を払うこずも重芁です。 プロシヌゞャの匕数この堎合は1぀だけによっお占有されおいたスタック䞊の堎所を「クリヌン」にしたす。 スタックの「クリヌンアップ」を実行する必芁のあるトピックに関する芁件は、さたざたな呌び出し芏玄によっお決定されたす。

それで、ゲヌムワヌルドのロヌドず保存の手順を理解したので、次のステップに進みたしょう。空いおいるホットキヌを芋぀けおメニュヌを描画したす。

幞いなこずに、以前のバヌゞョンのゲヌムでは、「拡匵チヌム」のメニュヌは「カットアりト」でした。これは、以前は「」文字を入力しお呌び出されおいたした。 これで、アクティブ化しようずするず、ゲヌムに次のメッセヌゞが衚瀺されたす。

画像

パッチを適甚するのに理想的な堎所は䜕ですか

「拡匵コマンドメニュヌが削陀されたした」ずいう行ぞの参照を探しおいたす

画像

そのうちの1぀にゞャンプしたす。

画像

手順の先頭を巊クリックし、Ctrl-Rを抌しお、呌び出し元の堎所を芋぀けたす。

画像

そうですね、そのような魅力は1぀だけです。 私たちはそれに飛び乗っお、スむッチブロックのケヌスの1぀で自分自身を芋぀けたす

画像

さお、パッチを実装する堎所を芋぀けたした。 では、クむックロヌドず保存メニュヌをどのように描画するかを考えおみたしょう。

圓然、このメニュヌは、釣りメニュヌなどで行われおいるように、ゲヌムの残りのビゞュアルコンポヌネントに収たる必芁がありたす。

画像

釣りオプションの行にはヒットが倚すぎるので、ネットを取埗するための参照を芋぀けおみたしょう。

画像

指定された呜什にゞャンプしお、case'ovの1぀に入りたす。

画像

䌑憩を入れお、「釣り」メニュヌを開き、どこから呌び出されたかを確認したす。

画像

画像

この手順の最初に䌑憩を入れお、OlyDbgでF9を抌しお、もう䞀床釣りメニュヌをアクティブにしたす。 ステップバむステップデバッグの結果、プロシヌゞャ0x004FC530が既に確認したスむッチブロックから次のメニュヌ項目のテキストを取埗し、 0x004BEF10にあるプロシヌゞャがメニュヌ項目をレンダリングするこずを想定しおいたす。

画像

画像

Arg1は、察応するメニュヌ項目を遞択するために入力する必芁がある文字のASCIIコヌドを瀺し、Arg2はその名前を担圓したす。

メニュヌタむトルを匕数ずしお取るプロシヌゞャ0x004BF3B0は 、その名前でメニュヌをレンダリングする圹割を果たしたす。 たた、䜕らかの理由で、このプロシヌゞャを呌び出す前に0xAE16068の倀が1に倉曎され、その埌に0に倉曎されたす。

画像

これらの手順の堎合、スタックのクリヌンアップの責任は呌び出し元の肩にもあるこずに泚意しおください。

手順0x004BF3B0は、メニュヌオプションの1぀を遞択するか、Escキヌを抌しお、入力した文字のASCIIコヌドを瀺す数字をEAXレゞスタヌに入れた埌にのみ、呌び出したコヌドに制埡を戻したすEscの堎合は0

パッチのコヌドに぀いお考えおみたしょう。

;    PUSH "Save" PUSH 0x53 ; 'S' CALL 0x004BEF10 ;    ,    ADD ESP,8 PUSH "Load" PUSH 0x4C ; 'L' CALL 0x004BEF10 ;    ,    ADD ESP,8 ;      PUSH "Quick save-load" MOV DWORD PTR DS:[0xAE16068],1 CALL 0x004BF3B0 ADD ESP,4 MOV DWORD PTR DS:[0xAE16068],0 ; ,    CMP EAX,53 JE save ;   'S' CMP EAX,4C JNZ exit ;    'L' JMP load save: PUSH 1 ;          CALL 0x005030E0 ;   ,    ADD ESP,4 JMP exit load: CALL 0x0050CB90 ;   ,    JMP exit exit: ;   default-case switch-,    ;   ,     '#' JMP 0x0050C8C1 

実行可胜むメヌゞの最埌にコヌドケむブの堎所を探しおいたす。 アドレス0x0051039Bで開始するこずにしたした。

画像

起こったこずは次のずおりです。

 0051039B . 53 61 76 65 00 ASCII "Save",0 005103A0 . 4C 6F 61 64 00 ASCII "Load",0 005103A5 . 51 75 69 63 6B 20 73 61 76 65 2D 6C 6F 61 64 00 ASCII "Quick save-load",0 005103B5 68 9B035100 PUSH urw.0051039B ; ASCII "Save" 005103BA 6A 53 PUSH 53 005103BC E8 4FEBFAFF CALL urw.004BEF10 005103C1 83C4 08 ADD ESP,8 005103C4 68 A0035100 PUSH urw.005103A0 ; ASCII "Load" 005103C9 6A 4C PUSH 4C 005103CB E8 40EBFAFF CALL urw.004BEF10 005103D0 83C4 08 ADD ESP,8 005103D3 68 A5035100 PUSH urw.005103A5 ; ASCII "Quick save-load" 005103D8 C705 6860E10A 01000000 MOV DWORD PTR DS:[AE16068],1 005103E2 E8 C9EFFAFF CALL urw.004BF3B0 005103E7 83C4 04 ADD ESP,4 005103EA C705 6860E10A 00000000 MOV DWORD PTR DS:[AE16068],0 005103F4 83F8 53 CMP EAX,53 005103F7 74 07 JE SHORT urw.00510400 005103F9 83F8 4C CMP EAX,4C 005103FC 75 13 JNZ SHORT urw.00510411 005103FE EB 0C JMP SHORT urw.0051040C 00510400 6A 01 PUSH 1 00510402 E8 D92CFFFF CALL urw.005030E0 00510407 83C4 04 ADD ESP,4 0051040A EB 05 JMP SHORT urw.00510411 0051040C E8 7FC7FFFF CALL urw.0050CB90 00510411 ^ E9 ABC4FFFF JMP urw.0050C8C1 

caseブロックのコヌドケむブに無条件ゞャンプを远加したしょう。これは、高床なコマンドのメニュヌのオヌプンを凊理する圹割を果たしたす。

画像

ゲヌムで「」を抌すず...

画像

これは䜕ですか どうやら、前のメニュヌを開いた埌、アむテムのリストはクリアされず、新しいアむテムでのみ拡匵されたした。 「フィッシング」メニュヌがどのように描画されるかをもう䞀床芋おみたしょう。メニュヌの堎合、少なくずももう1぀のプロシヌゞャ0x004BED40を呌び出さないこずに泚意しおください 。 おそらく、すべおのアむテムを描画する盎前に呌び出しが行われるため、クリヌンアップを担圓するのは圌女です。

画像

このプロシヌゞャを呌び出す前に、 EBXレゞスタの倀がスタックにプッシュされるずいう事実にもかかわらず、実装を芋るずわかるように、このプロシヌゞャの匕数ではありたせん。

画像

すべおの呜什を「シフト」せず、すでに蚘述されおいるコヌドケむブのアドレスを倉曎しないために、case-blockのコヌドにこのプロシヌゞャぞの呌び出しを远加したしょう

画像

そしお、もう䞀床「」蚘号を入力しおみおください。

画像

いいね

セヌブロヌドにふける

画像

そしお、䞀芋したずころすべおが正垞に機胜しおいるこずに気付きたす。

テストの過皋で、私たちは村に来たす

画像

もう䞀床-Sを抌したす。

画像

人々はどこぞ行きたしたか

どうやら、ゲヌムワヌルドを保存する手順には、ゲヌムオブゞェクトのクリヌンアップコヌドも含たれおいたす。 メむンメニュヌにアクセスするコンテキスト以倖で䜿甚するためのものではありたせん。 この状況から抜け出すには2぀の方法がありたす-クリヌニングコヌドがどこにあるかを正確に把握するそしおそこにネストされた呌び出しがたくさんありたす、信じおくださいか、通垞の保存の代わりにチヌトしお保存しおから読み蟌みたす。 最埌の遞択肢に留たるこずを提案したす。 0x0051040Aにある呜什JMP 0x00510411を入力しお、コヌドケヌブを倉曎したす。

 0051039B . 53 61 76 65 00 ASCII "Save",0 005103A0 . 4C 6F 61 64 00 ASCII "Load",0 005103A5 . 51 75 69 63 6B 20 73 61 76 65 2D 6C 6F 61 64 00 ASCII "Quick save-load",0 005103B5 68 9B035100 PUSH urw.0051039B ; ASCII "Save" 005103BA 6A 53 PUSH 53 005103BC E8 4FEBFAFF CALL urw.004BEF10 005103C1 83C4 08 ADD ESP,8 005103C4 68 A0035100 PUSH urw.005103A0 ; ASCII "Load" 005103C9 6A 4C PUSH 4C 005103CB E8 40EBFAFF CALL urw.004BEF10 005103D0 83C4 08 ADD ESP,8 005103D3 68 A5035100 PUSH urw.005103A5 ; ASCII "Quick save-load" 005103D8 C705 6860E10A 01000000 MOV DWORD PTR DS:[AE16068],1 005103E2 E8 C9EFFAFF CALL urw.004BF3B0 005103E7 83C4 04 ADD ESP,4 005103EA C705 6860E10A 00000000 MOV DWORD PTR DS:[AE16068],0 005103F4 83F8 53 CMP EAX,53 005103F7 74 07 JE SHORT urw.00510400 005103F9 83F8 4C CMP EAX,4C 005103FC 75 13 JNZ SHORT urw.00510411 005103FE EB 0C JMP SHORT urw.0051040C 00510400 6A 01 PUSH 1 00510402 E8 D92CFFFF CALL urw.005030E0 00510407 83C4 04 ADD ESP,4 0051040A 90 NOP 0051040B 90 NOP 0051040C E8 7FC7FFFF CALL urw.0050CB90 00510411 ^ E9 ABC4FFFF JMP urw.0050C8C1 

わあ オブゞェクトは消えたすが、その埌の読み蟌みによりすぐに衚瀺されたす。

倉曎をディスクに保存しおみたしょう。

画像

気づくのは悲しいこずですが、実行可胜ファむルのむメヌゞの終わり近くに远加した指瀺は、以前の蚘事の1぀にあったように、「物理的な境界」を超えおrawいたした。

PE Toolsのurw.exeセクション情報を芋お、䞊郚の「境界」を蚈算したしょう。

画像

仮想オフセット 0x00001000 +生サむズ 0x0010F400 +画像ベヌス 0x00400000 = 0x00510400

぀たり 匷調衚瀺された指瀺は「境界線」から「倖に出た」

画像

もちろん、 NOPは削陀できたすが、ただ20バむト残っおいたす。 コヌド掞窟の前でさらに5バむトを借りるこずができたす。

画像

しかし、残りの15バむトをどうすればよいでしょうか たずえば、「S」、「L」、「SL」ず等しくするこずで、メニュヌ項目ずそのタむトルを担圓する行のサむズを小さくするこずができたすが、これは非垞に゚レガントな゜リュヌションではありたせん。

逆アセンブルされたリストの途䞭に、独自のコヌドを远加できる堎所もある可胜性がありたす。 これらはれロである可胜性があり、通垞、実行可胜ファむルむメヌゞ、 NOP、たたはたずえばINT3呜什の末尟にあり、プロシヌゞャ本䜓間で互いに続きたす。 最埌のケヌスは、urw.exeで確認されおいたす。 䟋えば

画像

行をこがしお、そのような堎所で凊理を保存およびロヌドしたしょう。

 00409FBA . 53 61 76 65 00 ASCII "Save",0 00409FBF . 4C 6F 61 64 00 ASCII "Load",0 00409FC4 . 51 75 69 63 6B 20 73 61 76 65 2D 6C 6F 61 64 00 ASCII "Quick save-load",0 005007A2 6A 01 PUSH 1 005007A4 E8 37290000 CALL urw.005030E0 005007A9 ^ E9 C6F5FFFF JMP urw.004FFD74 004FFD74 83C4 04 ADD ESP,4 004FFD77 ^ E9 16FFFFFF JMP urw.004FFC92 004FFC92 E8 F9CE0000 CALL urw.0050CB90 004FFC97 E9 25CC0000 JMP urw.0050C8C1 0050C438 > \BE 20C75300 MOV ESI,urw_.0053C720 ; ASCII "Extended commands"; Case 23 ('#') of switch 0050C3FB 0050C43D . E8 FE28FBFF CALL urw.004BED40 0050C442 E9 4F3F0000 JMP urw.00510396 0050C447 . E9 75040000 JMP urw.0050C8C1 00510396 68 BA9F4000 PUSH urw.00409FBA ; ASCII "Save" 0051039B 6A 53 PUSH 53 0051039D E8 6EEBFAFF CALL urw.004BEF10 005103A2 83C4 08 ADD ESP,8 005103A5 68 BF9F4000 PUSH urw.00409FBF ; ASCII "Load" 005103AA 6A 4C PUSH 4C 005103AC E8 5FEBFAFF CALL urw.004BEF10 005103B1 83C4 08 ADD ESP,8 005103B4 68 C49F4000 PUSH urw.00409FC4 ; ASCII "Quick save-load" 005103B9 C705 6860E10A 01000000 MOV DWORD PTR DS:[AE16068],1 005103C3 E8 E8EFFAFF CALL urw.004BF3B0 005103C8 83C4 04 ADD ESP,4 005103CB C705 6860E10A 00000000 MOV DWORD PTR DS:[AE16068],0 005103D5 83F8 53 CMP EAX,53 005103D8 ^ 0F84 C403FFFF JE urw.005007A2 005103DE 83F8 4C CMP EAX,4C 005103E1 ^ 0F85 B0F8FEFF JNZ urw.004FFC97 005103E7 ^ E9 A6F8FEFF JMP urw.004FFC92 

今回は、画像が正垞に保存され、すぐにロヌドしお保存するための新しいメニュヌを䜿甚しお、URWで遊ぶこずができたす。

あずがき


怠azineは、ほずんどすべおの人ず掻動分野で最も厄介な性質の1぀です。 初めおではなく盎面しおいる問題の解決に少し時間を費やすこずを怠らないでください-これにより、将来的にはより倚くの時間を節玄できるでしょう。

ご枅聎ありがずうございたした。たた、この蚘事が誰かに圹立぀こずを願っおいたす。

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


All Articles