我知道如何在C#中导入和使用read / writeprocessmomory.
我正在研究游戏培训师.我需要“直接”访问转换为struct的其他进程内存.我可以使用readprocessmemory或writeprocessmemory,但这需要很多时间来实现许多结构.
我正在研究游戏培训师.我需要“直接”访问转换为struct的其他进程内存.我可以使用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#应用程序中使用其他进程内存作为struct?
解决方法
如果您需要一个与非托管程序二进制兼容的结构,则可以使用[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替换该方法,基本原则仍然适用(只有这一次,你需要管理结构的记忆).