Как получить доступ к структуре в памяти другой программы? - PullRequest
7 голосов
/ 13 февраля 2011

Я знаю, как импортировать и использовать процесс чтения / записи в 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 #?

Ответы [ 2 ]

8 голосов
/ 13 февраля 2011

Если вам требуется, чтобы структура была двоично-совместимой с неуправляемой программой, вы можете использовать атрибут [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, базовый принцип будет по-прежнему сохраняться (только в этот раз вам потребуется управлять памятью для структуры).

3 голосов
/ 13 февраля 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...