『自動早釣り機能の内訳その1』 [使用ツールollydbg/うさみみハリケーン] 改造コードの中には、それ一つでは然程意味が無いと感じるものの、数個が同時に実行されることにより、大きな効果を 発揮するものがあります。意味的には2種類あって、同系統の効果を重複させるもの(戦闘時MP減らないとフィールド上で MP減らないの複合等)と各々が全く独立した役割をもつものがあります。後者は解析における思索多様化の一つとして、 自らが行いたい事象すらも多角的に考察・システムに併せた分解を施すことによって成立させるもので、 当方で公開している対戦格闘ゲーム系パッチ等は、この系統の発想を基点にしています。 英雄伝説6SCにおける「釣り」は、竿と餌の選択→竿を振る→魚が掛かるまで待つ→タイミングよくクリックして釣る の 4項目で構成されています。前者2つは動作・手順共に流れ作業的ですが、3番目の手順でウエイトが、4番目の手順でリスクが 発生します。また、魚がヒットすれば必ず餌が減り、このソフトで最もアイテム消費の激しい部分でもあります。 1)魚が掛かるまで待つ=無駄に待ち時間が発生する 2)タイミングよくクリックして釣る=外せばこれまでの手順が無駄になり危険 3)魚がヒットすれば餌が減る=回数に限りがあって不便 この部分を同時に解決すれば、素早く魚を釣れまくることが可能です。 よって、解析自体もこの3つを各々独立させての対処が基本方針。結論から申せば、今回の3つの解析のうち上二つは同系統の解析でしたので、 前編である今回は、3番目の餌が減らない効果についてのアプローチの記録です。 < 魚がヒットしても餌が減らない解析 > 題目から、『「○○減らない」の解析』じゃないの?と思った方、ご明察です。 ただし、今回はその過程における思索や、応用に関する内容を扱っています。 いずれにせよ初心者向けではありますが。 ◆解析の基点 行うべきことは実際に餌を減らしている処理を見つけ出し、対処することです。 とはいえ残念ながら、超能力でもない限りダイレクトにその箇所を特定することはできません。 ですが、件の箇所の周囲を推測すると… 1)どのアイテムを減らすかの決定 2)そのアイテムがどのアドレスにあるかの検索 3)減らす値の決定 4)対象アイテム数をロード 5)減らしても0以下にならないかの判定 6)対象アイテム数を減算 7)対象アイテム数をストア 8)5)に追随するアイテムが足りない場合の処理 ざっと挙げただけでも、これだけの要素が存在するわけです。 中でも共通要素として多いのが「対象アイテム数」。これはベタで扱っている限り、 比較的容易に判別できる要素です。 ですから、この関連要素を元に該当箇所を辿る解析をします。 「アイテム数にブレークポイントを設置して〜」で始まる解説を多く見かけますが、 ほとんどがこれに近似した思索を前提に成り立っています。高名な方のテキスト にはAPI関数を基点とした解説が比較的多いですが、この場合も関連要素を Windows自体の汎用ライブラリに求めているからであって、原始的なレベルに 遡ればほぼ同じ基点に到達します。 解析手法上「〜は、こうするものなのだ」は存在しません。 (省略されているものも含めた上で)全てに意味があり、 その各々を理解することが応用への第一歩に繋がると思います。 ◆◆◆解析の実践 釣りを実際に行うなどして、対象アイテム数を変動させ、数値・変動サーチします。 ![]() アドレス0x2CBE9F4hより、4バイトを1単位として、 前2バイト:アイテムの種類 後2バイト:アイテムの個数 であることが判明。word[E?X*4+2CBE9F6](アドレス0x2CBE9F6hより、4の倍数を足した先の2バイトの値)で 、値が表せる簡易なものであることがわかりましたので、デバッガで"ED6_WIN2.exe"にアタッチし、 対象アイテム数の格納アドレスにメモリライトブレークポイントを設置してから、 再度同じ餌で釣りをします。 <補足1> このケースでは、E?Xレジスタが対象アイテム数のアドレスを示す手がかりになりますが、 多くの場合において、この値が実際のゲーム上でのアイテムスロット番号にあたります。 <補足2> E?Xが格納アイテムのスロット番号になりますので、02CBE9F6hという即値とモジュール エリアのサイズを考慮することで、この値は当該モジュール内の絶対アドレスに存在するものとわかります。 アドレス変動するかしないかは、こうした構成式から容易に判断できるものも多いです。
◆◆◆対処の実践 基本方針は3通り。 即ち減算の無効化・減算値の無力化・減算の回避です。 ![]() 1)減算の無効化 減算そのものを無かったことにする・減算の結果を反映させない方法 ![]() 2)減算値を無力化してしまう方法 減算を無意味にするため、減算値を0にする方法 ![]() 3)バイパスジャンプやサブルーチンの簡略化による回避方法 必要なデータを見切ったうえで、他の判定ジャンプを流用する・処理群自体をスキップする方法 ※このケースは他にも数通りの書き換え方があります。 <補足3> SUB命令以外に減算する方法について 以下、いずれも値を1減らす結果になります。 1) 48 DEC EAX デクリメント命令を使う方法 2) 81C0 FFFFFFFF ADD EAX,0FFFFFFFFh 補数を採って加算する方法 近辺のNOT/NEG命令に注目 3) 8D40 FF LEA EAX,DWORD PTR DS:[EAX-1] ロードアドレス命令を使う方法 以上、件の対処自体はいたって簡単でした。せっかくなので、 ここでは対処そのものよりも、一つの点に関して多くの視点を 得ることに留意して頂けますと幸いです。 ……………………………………………………が、ここで一つ問題発生。 「このコードを使ったら、なんか他のアイテムも減らなくなってました。 特に害はありませんけど、参考までに報告しときます」 …対処が簡単とはいえ、このまま公開していたら、こんな指摘が ほぼ確実に行われたことでしょう。無論気にしないのも自由ですが、 自動早釣りと銘打った限り、釣りに関係ない部分にまで影響を 及ぼすと、不安がる方がいらっしゃるのもまた事実。 ですから、今回は敢えて「釣り餌のみ減らない」を追求します。 いずれ要望等があればこのコードを公開すれば良いでしょう。 ◆◆◆対処の実践その2 では、何故このような状況になったか。以下のコードに注目します。 004C887E C3 RETN間違いなくサブルーチンです。そこで、サブルーチンの始点アドレス 0x4CC850hで、ollyの「参照を検索」を試してみます。 004C88E9 CALL ED6_WIN2.004C8850一件しかかかりませんでした。サブルーチン化する意味は当該処理群の汎用化 にありますので、複数箇所からコールされているはずです。0x4CC850h以降の 処理群も値を減算する役割のみでした。ここで、先に述べた推測を振り返ります。 1)どのアイテムを減らすかの決定 2)そのアイテムがどのアドレスにあるかの検索 3)減らす値の決定 少なくとも3)は可変要素ですね。2)もアイテムを減らす処理以外での利用法 がありそうです。ですから、件のサブルーチンは複数箇所からコールされている ルーチン或いはそれに追随するルーチンからコールされているのだろうと考えられます。 つまりは複重連鎖しているであろうということです。 「釣り餌のみ減らない」ためには、釣りの場合に 3)減らす値の決定 を行って いる箇所を叩く必要があります。この箇所を特定するため、サブルーチンを遡って いきます。方法としては、ステップ実行機能やコード実行ブレークポイント等が有効です。 <補足4> スタック始点に変動を及ぼす状況 1)CALL命令の実行 ジャンプに際し、リターンアドレスをスタックにPUSHします。 2)PUSH/POP系命令の実行 特定レジスタの値を退避・復帰する目的で使用されます。 3)ESPレジスタへの直接演算 4)ret命令の実行 サブルーチンから戻る際に使用されます。以上の補足3/4のようなものに関しましては、インテルマニュアル他、 最近出版されました、アセンブリ言語の知識・クラッキング手法について触れられた書籍にて、 より詳しい解説を得ることが可能です。興味がおありであれば、 当サイトリンク先にあります「でじたるとらべしあ」さんの紹介ページへどうぞ。 …ただし、専門書故に少々お高く感じるものもあるやもしれません、あしからず。 004C8854 56 PUSH ESI 004C8855 57 PUSH EDI 004C8856 8B7C24 10 MOV EDI,DWORD PTR SS:[ESP+10] 004C885A 66:8B0495 F6E9CB>MOV AX,WORD PTR DS:[EDX*4+2CBE9F6] 004C8875 2BC7 SUB EAX,EDI 0x4C8856h時点のスタック上 +0 +04 +08 +0C +10 EDI ESI ret先 xxx 減算値 コール元->0x4C88E9 004C88E3 8B4C24 0C MOV ECX,DWORD PTR SS:[ESP+C] //このECXレジスタが減算値 004C88E7 51 PUSH ECX 004C88E8 50 PUSH EAX 004C88E9 E8 62FFFFFF CALL ED6_WIN2.004C8850 0x4C88E3h時点のスタック上 +0 +04 +08 +0C xxx xxx xxx 減算値 004C88D0 56 PUSH ESI 004C88D1 8B7424 08 MOV ESI,DWORD PTR SS:[ESP+8] 004C88D5 56 PUSH ESI 004C88D6 E8 E5FCFFFF CALL ED6_WIN2.004C85C0 //このサブルーチンが 推測2)そのアイテムがどのアドレスにあるかの検索 部分 004C88DB 83C4 04 ADD ESP,4 0x4C88D0h時点のスタック上 +0 +04 +08 +0C ret先 xxx 減算値 コール元->0x4EB2A6 004EB2A3 6A 01 PUSH 1 004EB2A5 52 PUSH EDX 004EB2A6 E8 25D6FDFF CALL ED6_WIN2.004C88D0 0x4EB2A6h時点のスタック上 +0 +04 xxx 減算値 ![]() 処理の流れ自体はこちらの推測2)と3)が逆でしたが、 目的の減算値を引数としている箇所は以下になります。 004EB2A3 6A 01 PUSH 1よって、「釣りをしても餌が減らない」の改造コードは 4EB2A4-00 ※対処の実践内 2)減算値を無力化してしまう方法 を採ります。 さて、以上いかがでしたでしょうか?当たり前のように思えることにも意味が あるの前言通り パラメータをメモリサーチし、ブレークポイントを設置、 ブレークした周囲の命令や判定ジャンプを潰すことも、適当にやったら…では なくて、きちんと意味がありますことをご理解頂けましたでしょうか? プログラマさんが100人居れば、100通りのプログラムが出来ますが、 とあるソフトで通じた手法が、そのまま別のソフトでは通用しないという時も、 何か一つの知識・視点の追加によって、なし崩しに解決できてしまうこと も往々にしてあります。 今回は単に対処の方法を語るよりも、そこに至る理由・処理を読み取ること・ そこから派生するより多くの視点を得ることに重点をおきました。 対処方法の基本自体に関しましては、当サイトリンク先にあります 「DANAの部屋」さんの改造講座にて丁寧に触れられています。そちらも参考にされますと、 より深い理解が得られるのではないかと考えます。 それでは本日はこれにて。次回は「自動」「早釣り」についての補足に移ります。…1回でまとめきれるかな?(^^; ■今ページ開設のきっかけを与えて下さった有志の開発者・解析者の皆様に深く感謝いたします。 2006/04/16 REDCAT記
|