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.
精彩评论