質問:
逆アセンブラで静的ポインタを見つけることは可能ですか?
tested
2015-02-09 17:45:14 UTC
view on stackexchange narkive permalink

アセンブラ命令を見つけました: mov [esi + 2F]、dl 。 ESIは構造体またはクラスへの参照だと思います。 0x2F は、構造体/クラスのプロパティを参照するオフセットです。 ESIレジスタの値を見つけることは可能ですか?このクラスまたは構造体は、ゲームの開始時に初期化されると思います。

たとえば、GTAサンアンドレアスを逆転させようとしました。 GTASAの多くのメモリアドレスここ

このサイトでそのような情報を見つけました:0xB6F5F0-プレーヤーポインタ(CPed)。

私が今見つけているのはアドレスだと思います。しかし、ポインタースキャンなしでチートエンジンのようなデバッガーでそれを見つけるにはどうすればよいですか? asmコードでアドレスを検索したいのですが。可能ですか?

命令にブレークポイントを設定しようとしました。しかし、ESIアドレスは動的であるため、役に立たないと思います。 CPedの構造体/クラスは動的メモリ割り当てを使用していることを理解しています。

英語が下手で申し訳ありません。よろしくお願いします。

私は少し混乱しています。*「しかし、デバッガーでそれを見つける方法」*、デバッガーまたは逆アセンブラでESIの値を見つけたいですか?構造体/クラスのアドレスは動的である可能性が高いため、逆アセンブラで見つけることはできません。
ただし、@razはゲームで使用されるため、ポインターを格納する静的な場所が必要です。
それを「難しい」方法で行うか、ESIの最後の変更が何であるか、したがってその時点でのその値が何であるかがわかるまで、指示をさかのぼります。または、デバッガーにブレークポイントを設定し、この命令でESIの値を読み取るだけです。これを静的に実行したい特定の理由はありますか?
@AcidShoutなぜですか?オブジェクトの場合、実行時に割り当てられる可能性が高く、バイナリ内の静的な場所は必要ありません。それがグローバル変数でない限り、静的な場所を持つ理由はありません。
@razには、割り当てられたオブジェクトへのポインターを格納する変数がまだあり、そこから取得できます。その変数は静的になります
@AcidShoutはいをデバッグしている場合は、逆アセンブラでいいえ。
@razは、静的オフセットに格納されている_value_を取得することはできませんが、実行時に取得する部分であるため、とにかく必要ありません。ただし、実際のデータへの静的ポインタから開始します
@AcidShoutOPがグローバル変数のみを要求していることがわかりました。あなたは絶対に正しい、私の悪い。
1 回答:
rev
2015-02-09 20:55:14 UTC
view on stackexchange narkive permalink

はい、可能です

ほとんどのゲームでどのように行われるかを少し説明します(GTAを元に戻したことはありませんが、とにかくこのようなものだと思います)。

構造の静的および動的割り当てについて説明します。


静的な方法:

  GlobalGameInfo g_info; // ... g_info.some_data = 1;  

これは、IDAの静的オフセットになります。

  lea eax、 [g_info + 0xAABB]; 0xAABBが 'some_data' mov [eax]、1のオフセットであると仮定します;  

g_info は常に同じオフセットに留まるので、見つけたら、 g_info + offset を使用してデータを取得できます。

動的な方法:

  Player *プレーヤー; // Player *プレーヤー[<count>]またはPlayer **プレーヤーとして定義できます。 //同じです// ... player = new Player [players_count]; // ... player [1] .alive = false;  

結果は次のようになります:

 ;これは静的な場所であり、実際には「プレーヤー」変数です。 ;のメモリ内のオフセットを指すアドレスが含まれています。実際のプレーヤーstructuredword_xxxxdd? 

したがって、たとえば、 Cheat Engine、新しいアドレスを追加し、 Pointer をチェックし、 dword_xxxx xxxx 部分を追加し、オフセットします、必要なオフセットを入力します。たとえば、 alive がオフセット上にある players [1] .alive を取得します。 0x100の場合、次のように計算します。

  value_stored_in_dword_xxxx + sizeof(Player)* player_id + 0x100  

したがって、 dword_xxxx -> 0xAABBCCDD sizeof(Player)-> 0x204 player_id -> 8 、および offset -> 0x100 の場合、計算は次のようになります。

  0xAABBCCDD +(0x204 * 8)+ 0x100 // ^ base ^ size ^ id ^ offset  

mov [esi + 0x2F]を指定したので、dl

  • esi は構造体へのポインターです。上を見てください(逆アセンブリ内)。
    • mov esi、dword ptr [dword_xxxx] (おそらく)は、ポインタを逆参照していることを意味します。つまり、構造が動的に割り当てられます。
    • mov esi、offset dword_xxxx (おそらく)は、アドレス( xxxx 部分)を esi に割り当てているだけであることを意味します。これは静的アドレスです。

使用法

チートエンジン

Cheat Engineでは、ポインタとオフセットを入力するだけで簡単です。

Cheat Engine

ご覧のとおり、 0x5CCB138 dword_xxxx の場合、 dword_xxxx 内の値は 0x09021A00 であり、+ 0x142 (私のオフセット)は、ゲーム内の名前。

C

プログラムで実行する場合は、Cで次のように実行できます。

  PCHAR my_name = PCHAR(* PDWORD(0x5CCB138)+ 0x142); ^アドレスを保存| | ^取得するderef |オフセットを追加| ^キャスト| 0x09021A00 | // ->注意してください、最大長を超えないでください!// ->は、最後に「あなたの名前」の長さ+ 1 \ x00バイト//があることも覚えておいてください!charnew_name [] = "newName"; strncpy (my_name、new_name、sizeof(new_name)); //繰り返しますが、長さに注意してください! 

ただし、適切な方法は、次のように構造体全体を逆にすることです。

  struct player_data {int ID;文字名[15]; int some_data; ...;}; //各アイテムの順序/サイズが正しいことを確認してください!//単一のエラーが構造体全体を台無しにする可能性があります//ポインタを理解していると仮定しますplayer_data * data = *(player_data ** )0x5CCB138; //変更を行います//もう一度、長さに注意してください!//また、char * char new_name [] = "new name!"; strncpy(data->name)を使用するとsizeof()が機能しないことに注意してください、new_name、sizeof(new_name));
 


このQ&Aは英語から自動的に翻訳されました。オリジナルのコンテンツはstackexchangeで入手できます。これは、配布されているcc by-sa 3.0ライセンスに感謝します。
Loading...