4

だから私はリバース エンジニアリングの目的で別のプログラムのメモリを読んでいます。kernel32.dll の関数を使用しています。

関数は次のようになります。

ReadProcessMemory(Handle, new IntPtr(Address), buffer, BytesToRead, out ptrBytesRead);

次のように、メモリを少しずつ読み取るために使用しています。

    public static int ReadInt32(IntPtr Handle, long Address)
    {
        return BitConverter.ToInt32(ReadBytes(Handle, Address, 4), 0);
    }

次に、プログラム ハンドルと読み取り対象のアドレスを使用して ReadInt32 を呼び出し、静的ではないプログラムのベース アドレスを追加します。

私がやりたいのは、メモリのチャンク全体を読み取ることです (最大 1300 レコード、各レコードには 0xB0 のメモリ ステップがあります)。

これについてどうするのが最善の方法なのか正確にはわかりません。私はそれを調べましたが、すべてを取り、基本的にそれを自分の構造にダンプすることができるようです。私が抱えている問題は、実際に何をする必要があるのか​​ よくわからないことです。心の中では見えますが、紙にペンで書くことはできません。

展開して、実際には 2 次元配列であることを示します。構造は次のようになります。

    int OFFSET_CREATURE_ID = 0;
    int OFFSET_CREATURE_TYPE = 3;
    int OFFSET_CREATURE_NAME = 4;
    int OFFSET_CREATURE_Z = 36;
    int OFFSET_CREATURE_Y = 40;
    int OFFSET_CREATURE_X = 44;
    int OFFSET_CREATURE_IS_WALKING = 80;
    int OFFSET_CREATURE_DIRECTION = 84;
    int OFFSET_CREATURE_OUTFIT = 100;
    int OFFSET_CREATURE_OUTFIT_HEAD = 104;
    int OFFSET_CREATURE_OUTFIT_BODY = 108;
    int OFFSET_CREATURE_OUTFIT_LEGS = 112;
    int OFFSET_CREATURE_OUTFIT_FEET = 116;
    int OFFSET_CREATURE_OUTFIT_ADDON = 120;
    int OFFSET_CREATURE_LIGHT = 124;
    int OFFSET_CREATURE_LIGHT_COLOR = 128;
    int OFFSET_CREATURE_HP_BAR = 140;
    int OFFSET_CREATURE_WALK_SPEED = 144;
    int OFFSET_CREATURE_IS_VISIBLE = 148;
    int OFFSET_CREATURE_SKULL = 152;
    int OFFSET_CREATURE_PARTY = 156;
    int OFFSET_CREATURE_WARICON = 164;
    int OFFSET_CREATURE_ISBLOCKING = 168;

これらの各オフセットは、構造内の異なる要素に割り当てる必要があります。それらのいくつかは、bool、int、および string です。私は構造体を持っています。長さが各オフセットの「ステップ」全体を消費することを保証することはできませんが、これらの値を読み取るときは、毎回構造体の新しいインスタンスを宣言する必要があると思います (500ms ごとに読み取ります。おそらくそれ以上! 250 レコードの合計読み取り時間は約 50 ミリ秒であり、これは私が期待する読み取り時間です! ただし、最大 1300 まで実行できる必要があります)。

紛らわしいコードはやめてください。何をすべきかを説明するだけで十分です。この量のコードで作業しているとき、私は非常に苦労しているので、誰かがこれをすべて読み取るクラスをまとめて、それを格納するための構造を持たない限り (そのため、私はそれを自分で動作するように変換できます)、文字通り最小限のコードに感謝します。

4

1 に答える 1

3

プリミティブ型の場合、オフセットがわかっている場合は、単純にオフセットn(データの先頭) からビットを取得しn+1、aBitConverterを使用して型に変換できます。ToInt32(byte[] value, int startIndex)バイトを新しい配列にコピーする必要があるなどのメソッドで終了を指定できないためです。

intすべてがこの例の場合だと仮定しましょう。また、すべてのオフセットが配列内にあると仮定します。Bytes は取得した memblock ですReadInt32

int[] values = new int[Bytes.Length/4];
byte[] current = new byte[4];
BitConverter bc = new BitConvert();
for (i = 0; i < Bytes.Length/4 -1; i++)
{
     Buffer(Bytes, i(4), current, 0, 4); 
     values[i] = bc.ToInt32(current, 0);   
}

これは非常に単純化されていますが、正しい方向に進むには十分なはずです。ループを使用したくない場合もあります ( BitConverterC/C++ でデータベースから読み取るときにシリアル化を行う方法であるすべての命令をハードコーディングするだけかもしれません)。いずれにせよ、基本的な概念は、ビットコンバーターを使用して、他のプログラムから読み取ったバイトのセクションをデータ構造のそれぞれのプロパティに変換することです。

于 2012-11-17T00:55:34.030 に答える