ステップ9

imageプラグインエラー : ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (step9.PNG)

Shared code: (PW=31337157)

このステップでは、異なるオブジェクトに対して同じコードが使用される場合の対処方法について説明します。

チュートリアルには簡単なゲームが埋め込んで有ります。
プレイヤーは4人で、2プレイヤーはあなたのチーム、もう2プレイヤーは敵チーム(COM)です。
あなたのタスクは、体力を書き込むコードを探して、体力値の固定をしないでこのゲームに勝つことです。
コードを改竄したら'Restart game and autoplay'を押して、あなたのコードが正しいかどうか確かめて下さい。

このチュートリアルでは構造体を理解・解析する力を養うことが目的となっています。
ゲームに勝つにはプレイヤーのオブジェクトと敵のオブジェクトを区別する方法を見つける必要があります。
(例えば、プレイヤー固有の位置やチームナンバー、プレイヤー名を参照するポインタを調べるなど...)
これが見つけられるかどうかは、ゲーム自体の複雑さとあなたの運に依存します。

最も簡単な勝利方法は、体力値の書き込みを行なっているアドレスを見つけて、''Dissect data/structure''機能を利用することです。
この機能で構造体の内容を可視化し、敵と味方を区別する何かを探すことができます。
区別する方法が見つかったら、味方チームが勝利するようなアセンブラスクリプトを埋め込みます。

ヒント

  1. 体力はfloat値です。
  2. 勝ち方は複数あります。

簡単な解答例

+ どうしても分からない場合用
まず、プレイヤーの体力値をバリュータイプをfloatにして絞り込みます。
絞りこんだら'Attack'ボタンを押した時に体力値を書き込む命令を探しましょう。
004250C0 - 89 45 FC - mov [ebp-04],eax
004250C3 - 8B 45 FC - mov eax,[ebp-04]
004250C6 - 89 43 04 - mov [ebx+04],eax <<
004250C9 - D9EE - fldz
004250CB - D9 43 04 - fld dword ptr [ebx+04]

EAX=42BC0000
EBX=022500A0
ECX=0169F4BC
EDX=0169F604
ESI=00000006
EDI=00000001
ESP=0169F484
EBP=0169F4CC
EIP=004250C9
ここでEAXレジスタにダメージを受けた後の体力値(float型)が格納されています。
ゲームに勝つために敵プレイヤーがダメージを受けた時は、体力値を0にしてしまおうと考えます。
これを行うには、敵と味方を区別する必要があります。

そこで構造体解析をして、敵と味方を区別する方法を見つけます。
先ほど、体力値へのアクセスを調べたところ、mov [ebx+04],eax と言う形でアクセスされていたことが分かりました。
ここでプレイヤーの構造体のポインタがebxに格納されていて、体力値にアクセスする時のオフセットが04hであると推測します。
よって、体力値のアドレスから04hを引いた値が構造体ポインタ(構造体の先頭アドレス)であるとして、構造体の内容を調べます。

メモリビューワのToolsタブからからDissect data/structureを選択(またはCtrl+D)して構造体解析ウインドウを起動します。
StructuresタブからDefeine new structureを選択(またはCtrl+N)して、新しい構造体を定義します。
構造体の名前とサイズを問われるので、適当に設定します。
ここではデフォルトのままでも構いません。

構造体のグループと、構造体のアドレスをセットできます。
Ctrl+Gでクループの追加、グループを選択した状態でCtrl+Aでアドレスを追加できます。
グループ名は右クリックからリネームすることができます。
Player1の構造体ポインタとC.Player3の構造体ポインタをそれぞれ与えると以下のようになりました。
imageプラグインエラー : ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (step9_1.PNG)

赤枠で囲まれた部分がおそらく構造体の全容です。
デフォルトではデータタイプがポインタになっていますが、各エレメントをダブルクリックすることでデータタイプや名前などを変更できます。
ざっと、情報を整理して前プレイヤーの構造体を比較すると次の画像のようになります。
imageプラグインエラー : ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (step9_2.PNG)

構造体の中にどちらのチームに属しているのかを示す値があることが分かりました。
そこで、この値を利用して、敵チームであるときはダメージを受けたら即死するようなスクリプトを埋め込みます。

[ENABLE]
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
 //place your code here
 cmp [ebx+10],01
 je originalcode
 mov [ebp-04],0
originalcode:
 mov eax,[ebp-04]
 mov [ebx+04],eax

exit:
 jmp returnhere

Tutorial-i386.exe+250C3:
 jmp newmem
 nop
returnhere:

[DISABLE]
dealloc(newmem)
"Tutorial-i386.exe"+250C3:
 mov eax,[ebp-04]
 mov [ebx+04],eax
 //Alt: db 8B 45 FC 89 43 04

スクリプトを実行したら、リスタート&オートプレイボタンをクリックしてゲームを実行します。
ゲームに勝つと、NEXTボタンがアクティブになります。
imageプラグインエラー : ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (step9_3.PNG)

チュートリアルはこれで終了となります。
チュートリアルで示した以外にもたくさんの便利な機能がチートエンジンには備わっています。
その他多くのテクニックについては実践を通して学んで行きましょう。
imageプラグインエラー : ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (step9_4.PNG)
最終更新:2014年07月10日 12:27