Как получить доступ к структуре в другой памяти программы?

Я знаю, как импортировать и использовать read / writeprocessmomory в C #. Я работаю над игровым тренером. Мне нужно иметь «прямой» доступ к другой памяти процессов, переданной в структуру. Я могу использовать readprocessmemory или writeprocessmemory, но для многих структур потребуется много времени для реализации.

В C ++ есть такая структура:

class CRenderer { public: char unknown0[1692]; //0x0000 BYTE ID07D54FC8; //0x069C BYTE drawObjects; //0x069D BYTE drawDeferred; //0x069E BYTE drawParticles; //0x069F BYTE ID07E1CA70; //0x06A0 BYTE drawBundledMeshes; //0x06A1 BYTE drawStaticMeshes; //0x06A2 BYTE drawSkinnedMeshes; //0x06A3 BYTE drawRoads; //0x06A4 BYTE drawTerrain; //0x06A5 BYTE drawUnderGrowth; //0x06A6 BYTE drawOverGrowth; //0x06A7 BYTE drawNameTags; //0x06A8 BYTE drawTrees; //0x06A9 BYTE ID07E1CE70; //0x06AA BYTE ID07E1CDF0; //0x06AB BYTE DrawFPS; //0x06AC BYTE ID07E1CEF0; //0x06AD BYTE ID07E1C8F0; //0x06AE BYTE ID07E1C870; //0x06AF BYTE drawGraphs; //0x06B0 BYTE ID07D55048; //0x06B1 BYTE drawSkyDome; //0x06B2 BYTE drawSunFlare; //0x06B3 BYTE drawPostProduction; //0x06B4 BYTE ID07D550C8; //0x06B5 char unknown1718[6534]; //0x06B6 };//Size=0x203C(8252) 

Как представить эту структуру в C #? Каков самый простой способ достичь такого:

 //C++ DWORD RendererBase = (DWORD)GetModuleHandle( "RendDx9.dll" ); //Gets the base address of RenDX9.dll DWORD RendererOffset = RendererBase + 0x23D098; //Static address CRenderer *cRenderer = *(CRenderer**)RendererOffset; //Points to the class using the static offset cRenderer->drawSkyDome = 0; //No Sky cRenderer->DrawFPS = 1; //Show FPS 

В C # я хочу использовать его так:

 cRenderer.drawSkyDome = 0; //No Sky cRenderer.DrawFPS = 1; //Show FPS 

Как использовать другую память процесса как структуру в моем приложении C #?

Если вам нужна структура, бинарная совместимая с не управляемой программой, вы можете использовать [StructLayout] и его друзей. Например, в вашем случае это будет что-то вроде:

 [DllImport("kernel32.dll", CharSet=CharSet.Auto)] public static extern IntPtr GetModuleHandle(string lpModuleName); [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct RendererData { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1692)] public byte[] Unknown; public byte ID07D54FC8; public byte DrawObjects; public byte DrawDeferred; // ... public byte DrawFPS; // ... public byte DrawSkyDome; // ... } void Main() { IntPtr rendererBase = GetModuleHandle("RendDx9.dll"); if (rendererBase == IntPtr.Zero) { throw new InvalidOperationException("RendDx9.dll not found"); } IntPtr rendererAddr = IntPtr.Add(rendererBase, 0x23D098); var data = new RendererData(); Marshal.PtrToStructure(rendererAddr, data); data.DrawSkyDome = 0; data.DrawFPS = 1; Marshal.StructureToPtr(data, rendererAddr, false); } 

Я не уверен, что вы сможете получить доступ к данным другого модуля таким образом, но вы можете заменить метод ReadProcessMemory / WriteProcessMemory , основной принцип все равно будет выполняться (только на этот раз вам нужно будет управлять память для структуры).

Если вы хотите читать или записывать память, принадлежащую другому процессу, вам нужно использовать ReadProcessMemory и WriteProcessMemory . Это единственный способ сделать это.

Для того, что вы пытаетесь сделать, будет недостаточно, чтобы записать значения памяти в другой процесс. Вероятно, вам также необходимо вызвать некоторые методы. Если эти переменные, которые вы изменяете, являются свойствами, тогда необходимо будет вызвать метод доступа к свойствам. Если переменная содержит что-то динамическое (например, список, строка), то WriteProcessMemory не выполнит свою работу.

Такие вещи обычно выполняются с помощью четко определенного интерфейса (и API), своего рода плагиновую архитектуру и т. Д.