Я сделал метод, который будет читать мульти-указатель, предоставляя требуемые смещения + начальный адрес. (Код ниже). Подводя итог, я пытаюсь упростить этот метод, и ниже я объясню свою проблему.
Я боролся с преобразованием. Параметр представляет собой IntPtr, а выходной адрес для чтения представляет собой байтовый массив, моей первой идеей было: «Преобразовать байтовый массив в IntPtr, обработать его и, наконец, преобразовать последний адрес для чтения в int32 (поскольку последний адрес не является указателем). он никогда не будет прочитан, поэтому преобразование в Int32 должно быть в порядке) «,
Однако это не дало хорошего результата. Поэтому в настоящее время я застрял с решением преобразования байтового массива в Int32, а затем Int32 в IntPtr. Люди говорят, что битконвертер — это плохой подход, потому что он может вызвать проблемы на 64-битных платформах, и я также считаю, что есть подход, который может дать лучшую производительность (так как я конвертирую объект 2 раза).
Наконец, если кто-то думает, что было бы возможно создать подобную функцию в C ++, а затем P / Invoke в C # (я думаю, это будет более эффективно?), Скажите, пожалуйста. (Я пытаюсь адаптировать свои знания программирования. И нахожу сочетание языков очень интересным)
[DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")]
public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,
[In, Out] byte[] buffer, Int32 sizeout, out IntPtr lpNumberOfBytesRead);
public Int32 ReadBytes(IntPtr Handle, IntPtr Address, int[] Offsets, int BytesToRead = 4)
{
IntPtr ptrBytesRead;
byte[] value = new byte[BytesToRead];
ReadProcessMemory(Handle, Address, value, BytesToRead, out ptrBytesRead);
//Read Offsets
for (int i = 0; i < Offsets.Length; i++)
{
ReadProcessMemory(Handle,
new IntPtr(BitConverter.ToInt32(value, 0) + Offsets[i]),
value,
BytesToRead,
out ptrBytesRead);
}
return BitConverter.ToInt32(value, 0);
}
Любые идеи по оптимизации этого метода были бы очень благодарны! Спасибо заранее!
Как сказал @usr, производительность кода будет полностью зависеть от обращений к ReadProcessMemory
, Вы не должны ожидать улучшения производительности по сравнению с текущим уровнем.
Однако вы можете сделать код намного проще для чтения, избегая байтовых массивов и BitConverter
, Как это:
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
out IntPtr lpBuffer,
IntPtr nSize,
out IntPtr lpNumberOfBytesRead
);
private static IntPtr ReadProcessPointer(IntPtr hProcess, IntPtr Address)
{
IntPtr result;
IntPtr NumberOfBytesRead;
if (ReadProcessMemory(hProcess, Address, out result, (IntPtr)IntPtr.Size, out NumberOfBytesRead) == 0)
throw new Win32Exception();
return result;
}
public static IntPtr FollowPointers(IntPtr hProcess, IntPtr Address, int[] Offsets)
{
IntPtr ptr = ReadProcessPointer(hProcess, Address);
for (int i = 0; i < Offsets.Length; i++)
ptr = ReadProcessPointer(hProcess, ptr + Offsets[i]);
return ptr;
}
Других решений пока нет …