Player Base/Entity Listの見つけ方

プレイヤーオブジェクト
 メモリに実体化されたプレイヤーの構造体 インスタンスまたはエンティティとも言う


プレイヤーベースポインター
 メモリに実体化されたプレイヤーオブジェクトの先頭アドレスを保持しているポインタ変数


Player Baseの見つけ方

仮にHPのアドレスを見つけたとします。次にHPのアドレスにアクセスしている命令を調べ、mov [edi+E4],eaxとなっていれば、おそらくediがプレイヤーオブジェクトの先頭アドレスです。あとはediの値でアドレス検索すれば、緑色のベースポインターのアドレスがヒットするはずです。ヒットしない場合はポインタースキャンを使ってください。


また、プレイヤーオブジェクトを見つければ必ずしも情報がざくざく見つかるわけではありません。例えば風来のシレン5plusの場合、2D画面上の座標はありましたが、肝心のHP、満腹度、経験値は別の構造体にありました。


これはゲームを作成したプログラマーが構造体をどう定義するかによって変わってきます。assault cubeのように1つの構造体にHP、名前、座標、弾丸などたくさんの値を定義していれば連鎖的に値を見つけることができます。


まずは何でもいいので値を見つけていき、ポインタースキャンスクリプトを使用して次回起動時からもその値を参照できるようにしておきます。次にその値の近辺(同じ構造体)に他の情報がないかダンプ画面とdissect data structureを使用してゲームを動かしながら探します。


全体の流れとしてはこんな感じです。


Entity Listとは

赤枠がプレイヤーベースポインター(PlayerBase)、青枠がプレイヤーオブジェクトの先頭アドレスです。


風来のシレン5plus
風来のシレン5plus


Counter Strike Source
Counter Strike Source


Entity ListとはEntity(実体)が格納されている配列のことです。
上の画像のオフセットに注目してみると風来のシレンは0x8バイトずつ、CSSは0x10バイトずつアドレスが離れていることが分かります。この2つのゲームの場合ポインター配列になっており、ポインターのアドレスが規則正しく並んでいるのが特徴的ですね。


Entity Listを見つける際はこの特徴を利用します。どちらもオフセット0、つまり配列の先頭にプレイヤーの実体があるのも重要な点です。


参考URL
Getting Started How to find the Entity List


関連記事

10 Comments

初級者

座標の見つけ方について

いつも分かりやすい記事を楽しみにしています。
記事のコメントで、「最近のゲームでいうとBIOHAZARD RE3では問題なく使えているので」と書かれてありました。
RE3をお持ちであることを前提に質問させてください。

いつもは上下軸の座標アドレスを見つけるために、
Unknown initial.../Float で初期検索したあと、
①階段を昇ったりしてプレイヤーの高度が上がったら、「Increased value」
②階段を降りたりしてプレイヤーの高度が下がったら、「Decreased value」
③プレイヤーが停止中に「Unchanged value」
を繰り返していました。(Sleeping DogsとDEATH STRANDINGはこの方法で見つかりました。)
しかし、RE3では③を実施するとFound:0となり、失敗します。
管理人さんのこれまでの経験からこの原因は分かりますでしょうか?
(DEADRISING 2 OFF THE RECORDも同様に失敗しました)

あと一つ、Sleeping DogsとDEATH STRANDINGでは、上下軸のアドレスを見つけたものの、空中状態で値をロックしても空中で静止してくれません。
たとえば、上下軸:10でロックしたとすると、10→9→10…を繰り返す感じです。
更新周期のようなものがあるのでしょうか?
上下軸:10→重力により落下して9→次の更新時にまた10→落下して9→更新して10… のように見えます。
この回避方法をご存じでしたら教えていただけませんか?
(重力を無効にする方法がある?)
よろしくお願いいたします。

ちーたー

なんでもチート

To 初級者さん

当サイトの記事を読んでいただき、ありがとうございます。
RE3に関してですが、同じ条件でwindows debugger,VEH debugger両方試しましたが問題なく値を絞り込めました。
なんででしょう。。弾丸のアドレスなどは通常通り検索できますか?

上下軸に関しては初級者さんと同じ手順で見つけています。
x,y,z coordinateのzが上下軸になりますね。
ただcheat engineで値を固定しただけだと下の動画(27:12秒頃)のように、プレイヤーが空中でガタガタするだけだと思います。
https://www.youtube.com/watch?v=0VTASBy-2Xc
ジャンプして限界値に達したあと下に落とそうとする命令と上で固定しようとするcheat engineの両者が戦っている感じですね。

空中でピタッと静止させるには、ジャンプしたときに実行される関数をアセンブリ言語で追いかけ、下に落とそうとする命令を突き止めnopで潰したり、特定の値で固定したりして試行錯誤していると何らかのタイミングで成功するかもしれません。
今後そういったチュートリアルが見つかればお知らせします。
あと上の動画はプレイヤーの座標とカメラの座標を見つける方法を解説していて、とても参考になるのでおすすめです。

  • 2021/01/20 (Wed) 06:42
  • REPLY

初心者

To なんでもチートさん

早速のご返信ありがとうございます。

Z軸のアドレスですが、海外のチーターさんが作成したテーブルのおかげで答えだけは分りました。
Z軸のアドレス
Base Address:"re3.exe"+08D84B28
Offset0:10
Offset1:18
Offset2:34
です。答えがわかっているため、このアドレスに注目しながら検索しましたが、やはり引っ掛かりませんでした。不思議です。
ちなみに、弾薬数のアドレスは通常通り検索ができました。

また何か思いつきましたら教えていただけますと幸いです。

>下に落とそうとする命令を突き止めnopで潰したり
良いヒントをいただきましたので、DEATH STRANDINGあたりで試してみたいと思います。
あと、勉強になる動画をご紹介いただきましてありがとうございました。
この投稿者さんの動画も一通りチェックしてみます。
(喋っている内容は一切理解できませんが)

よろしくお願いいたします。

ちーたー

なんでもチート

To 初心者さん

RE2でx y z座標を見つけることができました。
https://dl.dropboxusercontent.com/s/zobxisf61c5xt91/re2.gif
RE3でも手順は同じなので以下のやり方を試してみてください。

HPのアドレスを見つける(4バイト、全回復状態で1200)
HPのアドレスの上3桁だけ残し、残りを0で埋め、Memory Scan OptionsのStartに張り付ける
HPのアドレスの上3桁だけ残し、残りをFで埋め、Memory Scan OptionsのStopに張り付ける
https://dl.dropboxusercontent.com/s/iiym8u0a4r9nwld/Image123.png
その状態でunknown initial value,Floatで検索をかける
階段をのぼる → スタートボタンを押しゲームをポーズしてからIncreased → Unchanged
階段をおりる → スタートボタンを押しゲームをポーズしてからDecreased → Unchanged
最終的に200以下くらいまで絞り込めたら、アドレスリストに追加する

1. 全アドレスの1/4くらいを一気に固定し階段を降りたりして、プレイヤーに変化があるか観察する(グラフィックが一瞬乱れ、上に行こうとする)
2. 何も変化が起きなければ、固定しているアドレスをすべて削除する
1と2をZ軸が見つかるまで繰り返す

Z軸のアドレスから0x4バイト減算したアドレスがX軸、Z軸のアドレスに0x4バイト足したアドレスがY軸になります。
たまにy軸とz軸の位置が入れ替わっているゲームがあります。

RE3に関してはプレイヤーが立っている状態でも座標が微妙に変動しています。
階段にいる場合は特に。
なのでIncreased,Decreased,Unchangedで検索する際は、ゲームをポーズしてから行うのが得策です。
HPのアドレスを先に見つける理由はどのゲームでもHPのアドレスと座標はアドレスが近いことが多いからです。
そうすることで検索範囲を大幅に絞れます。
またこのゲームはZ軸の値を変えるとその位置で固定され、そのまま移動できます。
これはジャンプボタンが存在しないので、下に落とす命令がないからだと思います。

  • 2021/01/22 (Fri) 18:08
  • REPLY

初心者

お世話になります。
お礼が遅くなり申し訳ございません。
お陰様でRE3の座標アドレスを見つけることができました。ありがとうございます。
原因はUnchangedでサーチするときにゲームをポーズしなかったことでした。
次からは気を付けます。

追加で質問よろしいでしょうか?
・テレポートについて
 X,Y,Zそれぞれの座標アドレスが分かったことで、テレポートが可能になります。
 各軸のアドレスに「Set/Change dropdown selection options」で拠点のアドレスを登録しておき、拠点Aに行きたいときは、X軸,Y軸,Z軸それぞれのアドレスから「拠点A」をドロップダウンリストから選択する という感じです。
「ドロップダウンリストから選択する」という作業をX軸,Y軸,Z軸それぞれでやっているのですが(計3回)、この回数を減らすことはCheatEngineの仕組みとして可能でしょうか?

よろしくお願いいたします。

ちーたー

なんでもチート

To 初心者さん

Teleport Hackについてですが、スクリプトを組むのが手っ取り早いと思います。
以下がおおまかな流れです。

・find out what accesses this addressでx軸に常時アクセスしている命令を見つける
・find out what addresses this instruction accessesでその命令がアクセスしているアドレスを見つける
・アクセスしているアドレスが複数あればレジスタの状態を確認し、プレイヤーとその他を区別できる値を探す
・テレポートしたい場所の座標をあらかじめ書き留めておく
・上で見つけた命令にスクリプトを組む

RE2でやってみたところ上手くいったので、下記のCTを参考にしてみてください。
右クリックから名前を付けてリンク先を保存でダウンロードできます。
https://dl.dropboxusercontent.com/s/emuhb7x9qjz3nqi/re2.CT

また、ここではすべてを説明するのが難しいため後日記事にします。
しばらくお待ちください。

  • 2021/02/01 (Mon) 19:14
  • REPLY

初心者

To なんでもチートさん

何でわざわざそこまで・・・ありがとうございます。
下記のようにRE2とRE3はよく似ていました。周辺の命令もほぼ同じです。
(使い回し?)
re2.exe+EE0AD74: 8B 47 30 - mov eax,[rdi+30]
re3.exe+22834E4: 8B 47 30 - mov eax,[rdi+30]


・find out what accesses this addressでx軸に常時アクセスしている命令を見つける
(re3.exe+22834E4: 8B 47 30 - mov eax,[rdi+30])
・find out what addresses this instruction accessesでその命令がアクセスしているアドレスを見つける
(28個のアドレスがヒット)
・アクセスしているアドレスが複数あればレジスタの状態を確認し、プレイヤーとその他を区別できる値を探す
(理解できませんでしたが、X軸のアドレス1個をグループ1,それ以外のアドレス27個をグループ2にして、
グループ1と2を区別するアドレスを探しました。
→[RDI+120+0+A60]がグループ1=1、グループ2=0だったのでコレかな?)

作成いただいたスクリプトにr15という知らないレジスタが出てきたので
迷子になりました。。。

おとなしく記事を待たせていただこうと思います。

お手数をおかけして恐縮ですが、記事を楽しみにしています。
よろしくお願いいたします。

ちーたー

なんでもチート

To 初心者さん

区別できる値を・・・と書きましたが、よく考えるとBaseAddressとOffsetが分かっているのでその工程は必要ありませんでした。申し訳ないです。
RE3でもTeleport Hackを作成したので参考にしてみてください。
aobが一緒であれば、そのまま使用できるはずです。
https://dl.dropboxusercontent.com/s/y2t599ge5xw8knr/re3.ct

最初のネメシス戦で戦闘開始後、F1を押すと足場の上にテレポートします。
https://dl.dropboxusercontent.com/s/iiym8u0a4r9nwld/Image123.png

  • 2021/02/07 (Sun) 11:04
  • REPLY

初心者

To なんでもチートさん

お世話になります。
テーブル作成ありがとうございます。無事動作を確認できました。
push rax
push rbx
mov rax,[re3.exe+8D84B28]
mov rbx,[rax+10]
mov rax,[rbx+18]
mov rbx,[xpos]
mov [rax+30],rbx

push rbx
mov rbx,[xpos]
mov [rdi+30],rbx
に変更してもうまくいきました。(勉強になりました。)
ただ、他の値でも試してみましたが、見えない壁を超えることができないようです。これを超えることが課題です。

追加で質問よろしいでしょうか?
・コードを見ていても「F1」キーで有効というのが分かりませんでした。どういったカラクリでしょうか?
・「Teleport Hack」と「F1: 足場の上にテレポートする(最初?のネメシス戦)」の2個でセットですよね?
場所を1か所追加する度に2個増えるということでしょうか?
・上記を回避したく、「Teleport Hack」の中に2個目の座標を追加しようとしました。
cmp [flag],1
je load1(xpos1,ypos1,zpos1の座標に飛ばしたい)
cmp [flag],2
je load2(xpos2,ypos2,zpos2の座標に飛ばしたい)
 のようにしたところ、
 Value欄に1を入れたら、xpos1,ypos1,zpos1の座標に飛びましたが、
 Value欄に2を入れても、移動しませんでした。
 何がまずかったでしょうか?(そもそもflagは0/1しかダメ?)

 恐れ入りますが、ご教授のほどよろしくお願いいたします。

ちーたー

なんでもチート

今質問していただいている内容を記事で書いているところだったのですが、やろうとしていたことがうまくいかないことが分かり、一旦保留しました。ですので、取り急ぎこちらで回答します。

この命令はプレイヤーの座標以外にもゾンビの座標など複数のアドレスにアクセスしています。
push rbx
mov rbx,[xpos]
mov [rdi+30],rbx
としてしまうと、正常に動作するときもありますが、ゾンビも一緒にテレポートするなど不具合が発生します。
上記の理由からBaseAddressとOffsetを使用してピンポイントでプレイヤーの座標を書き換えています。
ポインターを一つずつたどっていくため、コードが冗長になってしまいましたが、もう少しスマートなやり方があるかもしれません。

>コードを見ていても「F1」キーで有効というのが分かりませんでした。
flagの行を右クリックしてSet hotkeysから下記画像のように設定します。
https://dl.dropboxusercontent.com/s/fzsgexjqoc84q24/hotkey.png
そうするとF1キーを押したときにflagに1がセットされるようになります。
flagの値に関しては、2や3でも動作するはずです。

>「Teleport Hack」と「F1: 足場の上にテレポートする(最初?のネメシス戦)」の2個でセットですよね?
>場所を1か所追加する度に2個増えるということでしょうか?
2個でセットですが、増えるのは1つだけです。
場所を追加するにはスクリプト内でflag2という変数を確保し、シンボルに登録します。
次に、下記画像のように新規にアドレスとして追加します。
https://dl.dropboxusercontent.com/s/e9h03bw7600tomf/flag2.png
あとはflag2の行を右クリックから、Set hotkeysと進み、ホットキーとset value toで値を2か3に設定すれば完成です。

>見えない壁を超えることができないようです。
衝突回避チート(No collision)と併用すれば、縦横無尽にテレポートできるかもしれません。
またそれに関するtutorialがあればお知らせします。

  • 2021/02/10 (Wed) 20:16
  • REPLY