所以我正在阅读另一个程序的内存以进行逆向工程。我正在使用来自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条记录的总读取时间约为50毫秒,这是我期望阅读的内容!我确实需要能够达到1300条记录。)
请不要混淆代码,只是解释我应该做什么就足够了。当我使用这么多代码时,我经常苦苦挣扎,所以除非有人打算将一个能够读取所有这些内容的类放在一起,并使用一个结构来存储它(所以我可以将它转换为与我一起工作),我很欣赏字面上最小的代码。
答案 0 :(得分:3)
对于基本类型,如果您知道偏移量,则可以简单地将偏移n
(数据开头)中的位转换为n+1
,并使用BitConverter
转换为该类型。因为您无法使用ToInt32(byte[] value, int startIndex)
等方法指定结尾,所以您必须将字节复制到新数组中。
让我们假设这个例子的每个东西都是int
。我还将假设所有偏移都在一个数组中。字节是您从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 ++中从数据库读取时如何进行序列化)如果您有许多类型也可以事情比较简单。无论哪种方式,基本概念都是使用位转换器将您从其他程序读取的字节部分转换为数据结构中的各自属性。