Kidhak Prehistorik 2:レベルのロック解除

この素晴らしいゲームのファンは専用です...



画像

...ある場合。 しかし、私はすべてがそれほど悪いわけではなく、Crysisは人類の脳を完全に完全に吸収していないと確信しています。

したがって、前述の古いゲームのファン、特に92年の素晴らしいゲームの1つは、ゲーム内の保存システムがややプレフィックス付きの精神で作られていることを思い出すことができます:コードはレベル全体に散らばっています(時には予期せず到達しにくい場所にあり、MS-DOSで慎重に使用されます)紙に記録され、宝物のように保存されます。 メインメニューに入力したコードにより、対応するレベルを開始位置から開始できます。

Soshite 、私たちの時代には、何らかの方法で、Prehistorik 2をプレイしたい人たちに問題がありました。つまり、Dosboxでゲームをエミュレートする必要性:誰もが埋め立て地でそれを見つける機会はありません。メザニンは486番目に慎重に保管されました。

実際には、コードを生成するときに、ゲームはBIOS環境変数を使用します。 Dosboxでどのようにエミュレートされるか、私は理解していませんでしたが、エミュレータの新しい起動ごとにゲーム内のコードが異なることは確かです。 したがって、コード付きの紙は役に立たなくなり、ゲームの快適でストレスのない通過の可能性は無駄になります。ゲームは1回座って完全に完了することができます。 おそらく、これはDosboxの詳細な構成によって解決されます。 しかし...それは非常に簡単で、非常に簡単なので、ゲームの実行可能ファイルを少し掘り下げることさえ怖がっています。



問題の声明



画像

小さなハックを実装します。その結果、 私のようなベテランがコードの代わりに希望するレベルの番号を入力するだけで済みます。 結果に直行します。



















解決策



画像



















ほとんどの場合、ゲームファイルを解凍するのに時間がかかりました。 かつてパックされていたゲームコードにコピー保護をクラックしたチームのイントロが追加され、その後すべてが別のアルゴリズムで再びパックされました。 開梱のヘルプについては、グレチニコフ氏の記事habrahabr.ru/post/187072に目を向けました。この記事では、「開梱」という見出しの下のセクション、特に次の段落に興味がありました。

つまり、コマンドラインで/ niパラメータを渡すと、loc_19960プロシージャの残りは呼び出されません。 このパラメーターを使用すると、ゲームは勇敢なハイブリッドチームのリマインダーをスキップし、すぐにゲーム自体に進みます。 seg002全体がゲームに不要なスクリーンセーバーであり、実行中のexe'shnikにかかっていると結論付けます。 ヘッダーcs:ipを0000:0003に書き換え、ss:spを1681:0080に書き換え、最後の5E90hバイトをトリミングし、ヘッダーのサイズと追加のメモリフィールドを調整します。




(さらに、既成のソリューションは私が望んでいたものではないため、面白くありませんでした。)

このアドバイスに従った後、私は以前にウサギから抽出されたアヒルの卵を見つけました...またはそれは古代ロシアのおとぎ話で通常どのように起こりましたか? これをマトリョーシカと比較する方が簡単です:



画像



画像



食事を開梱した後、プログラムは90 Kbに成長しましたが、何も私に汚い足を走らせることを妨げるものはありませんでした。 Hiewを開き、すぐに興味のある行を見つけました。



画像



Hiewで行を見つけることは、F4-Hex、F7-ASCII->「興味のある行」を開始した直後であるということを、経験を積んでいる人のために(常に学ぶ価値はありますが)明確にします。

行アドレスは15401です。 ここで、プログラムがこの行にアクセスしている場所を見つける必要があります。 当然のことながら、そのような高い確率の呼び出しは、私が破ろうとした部分に近いでしょう。

どうすればわかりますか? 実際、多くの方法があります。 Ida Proでファイルを開き、相互参照を調べることができます。 確かに、最初はIdaは使用される文字列のタイプと友達になるように構成されていました。 しかし、IdはDosboxと16ビットファイルを落ち着いて、迷惑な要素なしでデバッグできるレベルでは友達になれなかったので(Dosboxは、パッチやプラグインにもかかわらず、彼がデバッガーであることを忘れて、自分の人生を生きようとしました) 、それから私は、必要な場所で、おそらく数バイトを修正するためだけに、そのような重砲を使用しないことにしました。

したがって、より簡単に行います。 この行へのオフセットがプログラムで使用されている場所を見つけるには、まずオフセット自体を見つける必要があります。 これを行うには、データセグメントのデータベースを知る必要があります。 Hiewでは、これは単純ではありません。 F8キーを押して、ファイルヘッダーを確認します。



画像



そのため、最初に電卓を開き、16進法に切り替えて、ヘッダーに値Paragraphs:86を入力し、10を掛けます。この値をバッファーにコピーし、ヘッダーウィンドウがまだ閉じていないHiewに戻ります。 終了せずに、F5を押してエントリポイントに移動します。 そして、ここでデコードモードに切り替えます(F4-デコード)。 リストの前に:



リスト1。

00000468: FA cli 00000469: FC cld 0000046A: BAFFFF mov dx,0FFFF ;" " 0000046D: BE8000 mov si,00080 ;" " 00000470: AC lodsb 00000471: 98 cbw 00000472: 8BC8 mov cx,ax 00000474: E35E jcxz 0000004D4 ---↓ (1) 00000476: AC lodsb 00000477: 3C2F cmp al,02F ;"/" 00000479: 7404 je 00000047F ---↓ (2) 0000047B: E2F9 loop 000000476 ---↑ (3) 0000047D: EB55 jmps 0000004D4 ---↓ (4) 0000047F: AC lodsb 00000480: 24DF and al,0DF ;"▀" 00000482: 3C46 cmp al,046 ;"F" 00000484: 7506 jne 00000048C ---↓ (5) 00000486: 2E83260300FE and w,cs:[0003],0FFFE ;"■" 0000048C: 3C4D cmp al,04D ;"M"
      
      







このすべてに興味はありません。 dsレジスタに値を割り当てることに興味があります。 検索する必要もなく、画面をかなり下にスクロールして、探しているものを見つけます。



リスト2。

 000004D4: B8030A mov ax,00A03 ;"◙" 000004D7: 8ED8 mov ds,ax
      
      







00A03を取り出して計算機に挿入します。計算機では、10倍して、以前にバッファーに保存されていた値に加算します。 A290入手します。 そして今、15401: B171からA290を引きます。 これは、プログラム内で使用される行オフセットです。 16進マッピング(F4-16進)に移動し、F7を押します。ここで、Basurmの単語「Neh」で指定された行に71 B1を入力します(バイトは逆順になります、覚えていますか?)。 次のリストに移動します。



リスト3。

 00009E23: E85801 call 000009F7E ---↓ (1) 00009E26: C606A7B103 mov b,[0B1A7],003 ;"" 00009E2B: BB71B1 mov bx,0B171 ;"▒q" 00009E2E: C706A2B1F20A mov w,[0B1A2],00AF2 ;"◙Є" 00009E34: E8EDFE call 000009D24 ---↑ (2) 00009E37: C606A7B104 mov b,[0B1A7],004 ;"" 00009E3C: BB6CB1 mov bx,0B16C ;"▒l" 00009E3F: C706A2B1C912 mov w,[0B1A2],012C9 ;"╔" 00009E45: E8DCFE call 000009D24 ---↑ (3) 00009E48: 803EA6B101 cmp b,[0B1A6],001 ;"" 00009E4D: 7503 jne 000009E52 ---↓ (4) 00009E4F: E90001 jmp 000009F52 ---↓ (5) 00009E52: 803EA6B102 cmp b,[0B1A6],002 ;"☻" 00009E57: 7503 jne 000009E5C ---↓ (6) 00009E59: E90601 jmp 000009F62 ---↓ (7) 00009E5C: 8A1E7028 mov bl,[2870] 00009E60: F6C380 test bl,-080 ;"" 00009E63: 7403 je 000009E68 ---↓ (8) 00009E65: E91501 jmp 000009F7D ---↓ (9) 00009E68: A02928 mov al,[2829] 00009E6B: 0A060C28 or al,[280C]
      
      







このリストの冒頭で、関心のある行でアクションが発生し、隣接する行「[[[[」で同じアクションが発生します。 おそらく、静的な観察では対応できません。 デバッガの助けを借りる必要があります。 子音の雰囲気に違反しないように、デバッガを含むDosbox 0.74の特別リリースに頼ります。 さらに、このオプションは松葉杖のIda + Dosboxプラグインよりもはるかに安定しています。



画像



そこで、Dosbox-74-debugを開きます(confファイルを設定した後、ゲームディレクトリをマウントするコマンドと、デバッグプレフィックスを付けて起動するためのディレクティブが単に示されています)。 さらに苦労することなく、トレースモードでゲームを起動し、すぐにこの場所でそれを見つけます。



リスト4。

 022E:014C 7B00 jpo 0000014E ($+0) 022E:014E C606A46C00 mov byte [6CA4],00 022E:0153 B80300 mov ax,0003 022E:0156 E86701 call 000002C0 ($+167) 022E:0159 E8138D call FFFF8E6F ($-72ed) 022E:015C 803E862D08 cmp byte [2D86],08 022E:0161 7234 jc 00000197 ($+34)
      
      







2番目のサブ機能を呼び出した後、メインメニューが起動し、このサブ機能内で「スピン」します。 最初のサブ機能の入り口で休憩を入れて、ゲームを再び開始し、最初に自由飛行に送ります。

それはすぐに判明します...



画像



...メインメニューの描画は、このコマンドで終了します。 そして、そのようなリストの直後に:



リスト5。

 022E:8E99 8ED8 mov ds,ax 022E:8E9B 33C0 xor ax,ax 022E:8E9D A3EC27 mov [27EC],ax 022E:8EA0 A3EE27 mov [27EE],ax 022E:8EA3 32C0 xor al,al 022E:8EA5 3806F227 cmp [27F2],al 022E:8EA9 7548 jne 00008EF3 ($+48) 022E:8EAB 3806F327 cmp [27F3],al 022E:8EAF 7557 jne 00008F08 ($+57) 022E:8EB1 A02928 mov al,[2829] 022E:8EB4 0A060C28 or al,[280C] 022E:8EB8 7539 jne 00008EF3 ($+39) 022E:8EBA 813EEC270E01 cmp word [27EC],010E 022E:8EC0 72E3 jc 00008EA5 ($-1d)
      
      







メインメニューでは、1または2のいずれかをクリックすることを提案しています。 この時点で、ゲームは022E:8EA5と022E:8EC0の間でループします。 すべてが明らかです。 両方のオプションにブレークポイントを設定します: 022Å:8EF3および022Å:8F08 、F5キーを押してゲームをフリーモードで「リリース」し、2-パスワードの入力を求めるメニュー項目を押します。



トレース後、リスト3に到達します。文字列 "[[[["は、 "ENTER CODE"と一緒にレンダリングされます-文字列 "_ _ _ _"で、canなフォントのためにこのように表示されるか、コード。 後者が真であると仮定し、不審な4バイトのオフセットでメモリにアクセスするブレークポイントを設定します:BPM011:16、011:011:16Eおよび011:16(デバッガーで現在のデータベースのデータベースを見ることができます)。 コードエントリメニューでキーを押し、提案されたコードのシンボルを入力すると、ゲームが再開され、プログラムはリストで停止します。



リスト6。

 022E:9A57 FF06A4B1 inc word [B1A4] 022E:9A5B FEC3 inc bl 022E:9A5D 80FB04 cmp bl,04 022E:9A60 7303 jnc 00009A65 ($+3) 022E:9A62 E9B800 jmp 00009B1D ($+b8)
      
      





デバッグ:メモリブレークポイント:0C11:B16C-5B-> 38




ある種の変数が増分され、その後レジスタの増分が発生し、明らかに0004を超えるチェックは4文字を入力する必要性と論理的に関連しています。 チェックの結果に応じて、retへの移行、またはコマンドの追加シーケンスへの移行があります。 これを含む:



画像



変数0C11:B1B5には、入力したばかりのコード「4789」が数値として格納されます。 次に、興味深いセクションが続きます。



リスト7。

 022E:9AAC 33D2 xor dx,dx 022E:9AAE 8BC2 mov ax,dx 022E:9AB0 E8A6F8 call 00009359 ($-75a) 022E:9AB3 3906B5B1 cmp [B1B5],ax 022E:9AB7 7420 je 00009AD9 ($+20) 022E:9AB9 42 inc dx 022E:9ABA 83FA14 cmp dx,0014 022E:9ABD 76EF jbe 00009AAE ($-11)
      
      







ゼロdxおよびax。 サブ関数が呼び出され、その後、新しくクリアされたレジスタahが入力されたコード(数値形式)と比較されます。 それらが同一である場合、距離のどこかに遷移があり、そうでない場合、dxは1増加し、14を超えない場合、操作が繰り返されます。

14個の正しいパスワードが列挙され、入力されたパスワードと比較されると仮定するのは論理的です(最初の9レベルは初心者向け、残りはエキスパート向けですが、この複雑さには2つの排他的レベルしかありません:キャッスルとミノタウロス、他のレベルの違いはわかりません、たとえば、 10番で、Icyがロードされます)。 すべての事実は、私たちが正しい軌道に乗っていることを裏付けています。



実際に...それがすべてです。 行き先はありません。 条件付き遷移を無条件に変更するだけです。 原則として、入力文字数も変更するとよいでしょう。これを変更しない場合、7番目のレベル番号を0007として入力する必要があるためです。結局、07として入力する方が便利です。これを行うには、リスト6を次のように変更します:



リスト6_1。

 022E:9A57 FF06A4B1 inc word [B1A4] 022E:9A5B FEC3 inc bl 022E:9A5D 80FB02 cmp bl,02 022E:9A60 7303 jnc 00009A65 ($+3) 022E:9A62 E9B800 jmp 00009B1D ($+b8)
      
      





4つのダッシュの線がどこでどのように描画されるかを探し、それらを2つに置き換えるために、私はすでに面倒でした。 Zmiroが<記号を使用してフォントリソースから感嘆符を描画し、 >記号をコンマに使用したにもかかわらず、「何がわからない」を検索するのは非常に面倒です。 デバッガーで少しずつ時間を費やして、この場所をローカライズすることはできましたが、私はそれほど完璧主義者ではありません。



結論 何をする



ゲームprel.exeの新しい実行可能ファイル。 ウイルスをチェックすることを忘れないでください。 ;)

レベルごとにパスワードを収集する必要がなくなりました。 4つのパスワードの代わりに2桁のシリアル番号を入力して、メインメニューからレベルを選択することができます。 不要なため、入力文字のマスクからラテンアルファベット(AF)の文字が削除され、数字のみが残されました。 入力レベル番号の範囲のチェックを追加(01-14)。 実際、誤って、または過度の好奇心から、プレーヤーがレベルをロードする代わりに、「 levelFF.sqzでディスクを挿入する」でクラッシュを観察する必要があるのはなぜですか 。 「ENTER CODE」からのパスワード入力のプロンプトは「SELECT LVL」に変更されました。 当初、ハイブリッドのイントロはゲームから切り離されていました。 最初の開発者イントロを変更しました( "Yeaaa ...私のゲームはまだ動作しています...")-ハイブリッドとこの変更に関する情報で補足されました。 難易度の名前の文字列を変更しました。

画像はクリック可能です。特に後者はクリック可能です。

画像 画像 画像 画像 画像



All Articles