开发者

How to access structure in other program's memory?

开发者 https://www.devze.com 2023-02-10 10:26 出处:网络
I know how to import and use read/writeprocessmomory in C#. I\'m working on game trainer. I need to have \"direct\" access to other process memory casted to struct. I can use readprocessmemory or writ

I know how to import and use read/writeprocessmomory in C#. I'm working on game trainer. I need to have "direct" access to other process memory casted to struct. I can use readprocessmemory or writeprocessmemory but that would take much time to inplement for many structures.

There is this structure in 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)

How to represent that structure in C#? What is the开发者_C百科 easiest way to achive sth like this:

//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

In C# I want to be able to use it like this:

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

How to use other process memory as struct in my C# application?


If you need a structure to be binary compatible with a non-managed program, you can use the [StructLayout] attribute and its friends. E.g. in your case it would be something like:

[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);
}

I am not sure if you would be able to access the data of the other module in such a direct way, but you can replace the method with ReadProcessMemory/WriteProcessMemory, the basic principle would still hold (only this time, you would need to manage the memory for the structure).


If you want to read or write memory that is owned by a different process you need to use ReadProcessMemory and WriteProcessMemory. That's the only way to do it.

For what you are trying to do, it won't be enough to write the memory values into the other process. You'd likely need to invoke some methods as well. If these variables that you are modifying are properties, then the property access method would need to be called. If the variable holds something dynamic (e.g. a list, a string), then WriteProcessMemory is not going to get the job done.

This sort of thing is usually done with a well-defined interface (and API), some sort of plug-in architecture etc.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号