さて、パッチ形式でのデータ取りは出来たものの、Feignに手を入れないで動かすのもやってみたい。どこから手をつければいいのかな。
と、その前にFeignはオンラインゲームです。どうやって動作検証を行うのでしょうか。Among Usの場合はローカルネットワークだけで動くモードがあります。こちらは抜け道を使うと一個のPCでフルの15人まで動かすことだって可能です。
でもFeignはオンラインにつなぐしかありません。二つのPCでSteam2アカウント使えばゲームの流れはつかめます。が、吊り=ゲーム終了となってしまうためまだ足りません。もう少し多様なシチュエーションを作るには最低あと二つ。てことでスマホとタブレットを持ってきて4アカ。ギリギリです。
さて、Feignのメモリを覗きこむ。そのためにはWin32APIのReadProcessMemoryを使用する必要があります。プロセスのハンドルとかはC#のProcess周りで取ることが出来そう。
では、これらを使ってどこを読めばいいのか?本格的にFeignの解析が必要です。
Unityで作られたゲームはIL2CPPという技術でコードの難読化も兼ねてネイティブコードに変換されています。Il2CppDumperとかIl2CppInspectorというツールで解析が出来るようです。
が、どちらも本家のアップデートが止まっています。試しにFeignに使ってみると対応しないVersionですとのこと。Forkをいくつか見てると更新が続いてるのがある、試してみると・・いけた。
入手した情報からアドレスの割り出しをしていく。見た感じstaticオブジェクトのポインタがわかって、staticのフィールド、インスタンスのフィールドのオフセットがわかったので順々にたどればいいのね。LobbyManagerはstaticクラスだったのでここから辿って辿っていくとusersは取れそう・・・。取れた。
GameControllerは動的に生成されてるので、インスタンスを誰か保持していないかな、と探すと同じく動的に生成されるクラスしか保持していない。あれ?詰んだ臭くない?
よく考えなおしてみよう。staticのオブジェクトも生成される場所はヒープのはずだからその周辺に確保されるはず。メモリサーチでクラス情報を保持しているオブジェクトらしきものを列挙してみる・・・。複数出てくる。
真のオブジェクトはplayers、deadPlayersというListを持っているはずだから、そのオフセットにListを持つものに絞ると・・・まだ複数ある。ゲームごとにオブジェクトを作成して破棄しきれていないらしい。あちこちで保持しあってるからGC効かないんだろうな。
こうなってくると、ゲーム開始直前のロビー人数とplayersが等しく、deadPlayersが0のゲームを現在のゲームと決め撃つしかなく、それで何とか取れたっぽい。
playersは生きているプレイヤー、deadPlayersは死んでいるプレイヤーに違いないから、これで生死を判定しようかな。あれ?両方に名前があるプレイヤーがいるぞ。もしかしてキルされたらplayersからdeadPlayersに移すけど、蘇生されたらdeadPlayersはそのままにplayersに再追加してる?そういう仮定で検出すると、あってるぽい。
てことでメモリ監視方式も完成。手動/メモリ監視/Mod経由の3通り全部乗せが出来ました。テストプレイで代替問題ないことを確認して数日後。
本体アップデートが来ました。こうなってくるとアドレスも変わってるだろうし、パッチもそのまま当たるかわからないし。いやぁ、アプデに追従するのは大変だなぁって実感しました。ある程度需要はあるだろうし、公開してもいいんだけどね。
0 件のコメント:
コメントを投稿