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,还有一些是string。我有结构。我不能保证长度会消耗每个偏移量的整个“步骤”,尽管当我读取这些值时,我认为我需要每次声明一个新的结构实例(我将每 500 毫秒左右读取一次,也许更多!250 条记录的总读取时间约为 50 毫秒,这是我期望读取的时间!我确实需要能够做到 1300 条)。

请不要混淆代码,只需解释我应该做什么就足够了。当我使用这么多代码时,我很挣扎,所以除非有人将一个可以阅读所有这些内容的类放在一起,并有一个结构来存储它(这样我就可以将它转换为我的工作),我会欣赏字面上最少的代码。

4

1 回答 1

3

对于原始类型,如果您知道偏移量,您可以简单地从偏移量n(数据的开头)获取位n+1并使用 aBitConverter转换为类型。因为您无法使用诸如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++ 中的数据库读取时进行序列化的方式)如果您有许多类型,这也会使事情变得更简单。无论哪种方式,基本概念都是使用位转换器将您从其他程序读取的字节部分转换为数据结构中它们各自的属性。

于 2012-11-17T00:55:34.030 回答