C# - reading and writing memory for game trainer

I'm interested in creating a small trainer for a single player game I made and want to know how to read/write memory with C# given a specific

memory address.

I found the memory addresses which hold the score (int '004F19EC') and

player x position (float '01150630') and want to use them to produce

variables in C# to track them and manipulate them.

I couldn't find much info on how to do this. It seems I use the Marshal class but I'm having trouble figuring it out. If someone could show a sample of how this is done, I'd appreciate it.

[555 byte] By [Apathy] at [2007-12-25]
# 1
Is it managed memory or unmanaged memory? If it is managed (i.e. managed by the CLR) memory you shouldnt reference it directly as the address will change when the GC compacts the heap.
NikhilRajwade at 2007-8-31 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 2
The game I made uses managed memory, but I panned on using it as a test game. Since there's a difference, I'll just use a game with unmanaged memory instead. Let's assume it's unmanaged memory I'm dealing with.
Apathy at 2007-8-31 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 3
You need to get an IntPtr (pointer) to that unmanaged memory structure and use the static methods on the System.Runtime.InteropServices.Marshal class (eg. Marshal.ReadInt32(), Marshal.PtrtoStructure() etc) to be able to create managed objects that you can use in your managed app.
NikhilRajwade at 2007-8-31 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 4
I've looked at the Marshal methods but can't figure out how to actually create a variable out of an address such as '004F19EC'. No methods seem to have such a parameter.

Suppose I have an int and a pointer to the score in the game.

int score = 0;
IntPtr pScore = new IntPtr();

I'm trying to figure out how to tie pScore with '004F19EC'.

Then I assume I can manipulate the score with something like this.

score = Marshal.ReadInt32(pScore);
Marshal.WriteInt32(pScore, 500);

Edit:

I think I figured out how to allocate the pointer, but the value seems to be wrong.

IntPtr pScore = new IntPtr(0x004F19EC);
int score = Marshal.ReadInt32(pScore);
this.Text = score.ToString();

The value stored in score shows as '16387888' when the game's score is actually '27520'. The memory reader I used to find the address lists the value as consisting of 4 bytes. Maybe I'm not using the right variable type. Anyone know how I can get the score to be stored as 27520?

Apathy at 2007-8-31 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 5

Yes, but first you need to provide a mechanism to marshal that memory across. If the unmanaged game runs in its own process that memory address is protected by the process boundary. Therefore your .NET application should run in that processes address space in order to access that address.

Your options are as follows

a) Run your managed code in the unmanaged process address space.

b) Run the unmanaged code in the managed process address space.

NikhilRajwade at 2007-8-31 > top of Msdn Tech,.NET Development,Common Language Runtime...
# 6

Marshal.Write* is for writing within your own process. If the memory is in another process, then you need to pinvoke to kernel32!WriteProcessMemory.

Check out pinvoke.net for help with the pinvoke definitions: http://pinvoke.net/default.aspx/kernel32.WriteProcessMemory

MikeStall-MSFT at 2007-8-31 > top of Msdn Tech,.NET Development,Common Language Runtime...

.NET Development

Site Classified