读取一块内存,将其存储到本地结构中

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)。我不确定最好的方法是什么。我研究了一下,看起来可以做一些事情,将整个东西基本上倒进我自己的结构中。我的问题是我不太清楚我实际需要做什么。我可以在脑海中看到它,但无法付诸于行动。我会扩展一下,以显示它实际上是一个二维数组,其结构如下:
    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类型,还有一些是字符串类型。我已经有了这个结构体。我不能保证每个偏移量的长度会占用整个“步骤”,但当我读取这些值时,我认为我需要每次声明一个新的结构体实例(我将每500ms左右读取它们,可能更多!250条记录的总读取时间约为50ms,这也是我期望的读取时间!但我确实需要能够处理多达1300)。
请不要提供混乱的代码,只需解释我应该做什么即可。当我处理这么多代码时,我遇到了很多困难,所以除非有人可以组合一个类来读取所有这些内容,并使用结构来存储它(这样我就可以将其转换为适用于我的结构),否则我真的希望最少的代码。
1个回答

3
对于原始类型,如果您知道偏移量,可以直接从数据的起始位置nn+1取出位,并使用BitConverter将其转换为该类型。由于无法使用诸如ToInt32(byte[]value,int startIndex)之类的方法指定结束位置,因此您需要将字节复制到新数组中。
让我们假设这个例子中所有内容都是int,同时也假设所有偏移量都在一个数组中。Bytes是您通过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);   
}

这只是一个很大的简化,但足以让您朝着正确的方向前进。您甚至可能不想使用循环(也许只需硬编码所有BitConverter指令,这就是在C/C++中从db读取时进行序列化的方法)。如果您有很多类型,那么事情也会更简单。无论哪种方式,基本概念都是使用位转换器将从其他程序读取的字节的部分转换为数据结构中相应的属性。


那看起来很容易处理,我认为我可以将这个概念适应到我的代码中。 - XtrmJosh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接