Results 1 to 5 of 5
  1. #1
    hooch's Avatar
    Join Date
    Aug 2007
    Gender
    male
    Posts
    208
    Reputation
    6
    Thanks
    1,195
    My Mood
    Hungover

    Arrow [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.
    Last edited by hooch; 02-20-2011 at 06:13 AM.

  2. The Following User Says Thank You to hooch For This Useful Post:

    J4ckD (12-03-2011)

  3. #2
    ♪~ ᕕ(ᐛ)ᕗ's Avatar
    Join Date
    Jun 2010
    Gender
    male
    Location
    Uterus
    Posts
    9,111
    Reputation
    1096
    Thanks
    1,971
    My Mood
    Doh
    None of the two pages of MDSN can be seen, also please explain better, what is WinMine and etc... This is a useful tutorial

  4. #3
    hooch's Avatar
    Join Date
    Aug 2007
    Gender
    male
    Posts
    208
    Reputation
    6
    Thanks
    1,195
    My Mood
    Hungover
    Quote Originally Posted by 3Li0 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.

  5. #4
    AeroMan's Avatar
    Join Date
    Dec 2008
    Gender
    male
    Location
    Hell
    Posts
    3,291
    Reputation
    189
    Thanks
    3,049
    My Mood
    Busy
    nice tutorial

  6. #5
    hooch's Avatar
    Join Date
    Aug 2007
    Gender
    male
    Posts
    208
    Reputation
    6
    Thanks
    1,195
    My Mood
    Hungover
    Quote Originally Posted by AeroMan View Post
    nice tutorial

    No problem.
    Just press thx button under my post