Arrow[Tutorial][C#] Reading struct from game

Posts 15 of 5 · Page 1 of 1
[Tutorial][C#] Reading struct from game
Hello.
This is my first tutorial. I hope you like it.
Consider this. You have reversed struct in game using ReClass.
ReClass generated code for this struct but in C++.
This is for WinMine.exe:

Code:
class CGame
{
public:
		char unknown0[280]; //0x0000
	__int32 xPressed; //0x0118  
	__int32 yPressed; //0x011C  
		char unknown288[32]; //0x0120
	__int32 MouseDown; //0x0140  
		char unknown324[28]; //0x0144
	__int32 GameStatus; //0x0160 3-win, 2-boom,  
	__int32 IsInGame; //0x0164  
		char unknown360[44]; //0x0168
	__int32 MinesLeft; //0x0194  
		char unknown408[408]; //0x0198
	__int32 LevelMines; //0x0330  
	__int32 Colls; //0x0334  
	__int32 Rows; //0x0338  
		char unknown828[868]; //0x033C
	__int32 GameType; //0x06A0 0-easy, ..., 3-custom 
		char unknown1700[40]; //0x06A4
	__int32 EasyBestScore; //0x06CC  
	__int32 MediumBestScore; //0x06D0  
	__int32 HardBestScore; //0x06D4  
	char PlayerEasyName[64]; //0x06D8  
	char PlayerMediumName[64]; //0x0718  
	char PlayerHardName[64]; //0x0758  
	__int32 NumLastHitsDiscovered; //0x0798  
	__int32 TimePlayed; //0x079C  
		char unknown1952[4]; //0x07A0
	__int32 DiscoveredFields; //0x07A4  
}//Size=0x07A8(1960)
Now this is the same struct in C#:
Code:
    [StructLayout(LayoutKind.Explicit)]
    public struct WinMineGameStruct
    {
        [FieldOffset(0x118)]
        public Int32 xPressed;
        [FieldOffset(0x118)]
        public Int32 yPressed;
        [FieldOffset(0x140)]
        public Int32 MouseDown;
        [FieldOffset(0x160)]
        public Int32 GameStatus;
        [FieldOffset(0x164)]
        public Int32 IsInGame;
        [FieldOffset(0x194)]
        public Int32 MinesLeft;
        [FieldOffset(0x330)]
        public Int32 LevelMines;
        [FieldOffset(0x334)]
        public Int32 Colls;
        [FieldOffset(0x338)]
        public Int32 Rows;
        [FieldOffset(0x6a0)]
        public Int32 GameType;
        [FieldOffset(0x6cc)]
        public Int32 EasyBestScore;
        [FieldOffset(0x6d0)]
        public Int32 MediumBestScore;
        [FieldOffset(0x6d4)]
        public Int32 HardBestScore;
        [FieldOffset(0x6d8)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public Char[] PlayerEasyName;
        [FieldOffset(0x718)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public Char[] PlayerMediumName;
        [FieldOffset(0x758)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public Char[] PlayerHardName;
        [FieldOffset(0x798)]
        public Int32 NumLastHitDiscovered;
        [FieldOffset(0x79c)]
        public Int32 TimePlayed;
        [FieldOffset(0x7a4)]
        public Int32 DiscoveredFields;
    }
You can read more about Struct Layout and Field Offset attributes there:


Now.
I will not tell you how to read byte array from memory.
If you are reading this you should already know this.
In my example ProcessReaderWriter is wrppper for ReadProcessMemory winsows's function.

So there it is.

Code:
using System;
using System****ntime.InteropServices;
using ProcessMemoryReader;

namespace Tester
{
    [StructLayout(LayoutKind.Explicit)]
    public struct WinMineGameStruct
    {
        [FieldOffset(0x118)]
        public Int32 xPressed;
        [FieldOffset(0x118)]
        public Int32 yPressed;
        [FieldOffset(0x140)]
        public Int32 MouseDown;
        [FieldOffset(0x160)]
        public Int32 GameStatus;
        [FieldOffset(0x164)]
        public Int32 IsInGame;
        [FieldOffset(0x194)]
        public Int32 MinesLeft;
        [FieldOffset(0x330)]
        public Int32 LevelMines;
        [FieldOffset(0x334)]
        public Int32 Colls;
        [FieldOffset(0x338)]
        public Int32 Rows;
        [FieldOffset(0x6a0)]
        public Int32 GameType;
        [FieldOffset(0x6cc)]
        public Int32 EasyBestScore;
        [FieldOffset(0x6d0)]
        public Int32 MediumBestScore;
        [FieldOffset(0x6d4)]
        public Int32 HardBestScore;
        [FieldOffset(0x6d8)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public Char[] PlayerEasyName;
        [FieldOffset(0x718)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public Char[] PlayerMediumName;
        [FieldOffset(0x758)]
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
        public Char[] PlayerHardName;
        [FieldOffset(0x798)]
        public Int32 NumLastHitDiscovered;
        [FieldOffset(0x79c)]
        public Int32 TimePlayed;
        [FieldOffset(0x7a4)]
        public Int32 DiscoveredFields;
    }

    class Winmine
    {
        WinMineGameStruct WinMineStruct;
        ProcessReaderWriter Reader;

        public Winmine(ProcessReaderWriter reader)
        {
            Reader = reader;
            WinMineStruct = new WinMineGameStruct();
        }

        public void ReadGame()
        {
            Byte[] rawStruct = Reader.GetByteArray((IntPtr)0x1005000, 0x7A8);
            WinMineStruct = ByteArrayToStructure<WinMineGameStruct>(rawStruct);
        }

        public T ByteArrayToStructure<T>(byte[] bytes) where T : struct
        {
            GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned);
            T stuff = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),
                typeof(T));
            handle.Free();
            return stuff;
        }
    }
}
If you have any question ask there. I'll not answer any questions sent on PM.
None of the two pages of MDSN can be seen, also please explain better, what is WinMine and etc... This is a useful tutorial
Quote Originally Posted by user590177 View Post
None of the two pages of MDSN can be seen, also please explain better, what is WinMine and etc... This is a useful tutorial
Winmine is windows minesweeper game.
nice tutorial
Quote Originally Posted by AeroMan View Post
nice tutorial

No problem.
Just press thx button under my post
Posts 15 of 5 · Page 1 of 1

Post a Reply

Tags for this Thread

None

Need help?