Structs are a huge part of both external and internal hacks. However, many people new to hacking are confused by what they are, and how to use them. In this tutorial, I will show how to read and use structs in noob-friendly C# (Go on @Isaakske ;p).
Structs (or structures) are groups of variables of a fixed size. This means a series of them may be read from memory easily. For my example, I will be using the Client_t struct for MW3 1.9.433 (thanks to @Jorndel for posting):
First off, we'll create a C# Class:Code:typedef struct { int Valid; //0x0 (0xAD28F8) char _0x0004[0x8]; //0x4 char Name[16]; //0xC (0xAD2904) int Team; //0x1C (0xAD2914) char _0x0020[0x4]; //0x20 int Rank; //0x24 (0xAD291C) char _0x0028[0x10]; //0x28 int Perk; //0x38 (0xAD2930) char _0x003C[0x8]; //0x3C int Score; //0x44 (0xAD293C) char _0x0048[0x458]; //0x48 int Attacking; //0x4A0 (0xAD2D98) char _0x04A4[0x4]; //0x4A4 int Zooming; //0x4A8 (0xAD2DA0) char _0x04AC[0xB8]; //0x4AC }client_t; //[Addr: 0xAD28F8] [Size: 0x564]
Next, we create a function to read the class from game memory. The numbers on the right of the struct come into play here, as each one represents the variables' offset from the start of the struct. This is what I came up with (using Jorndel's trainer class as a base):Code:class Client_t { public int valid; public string name; public int team; public int rank; public int perk; public int score; public int attacking; public int zooming; }
Here, the base Address is 0xAD28F8, and the Size is 0x564. Since we know there are 18 clients max in MW3, we can create this function:Code:public static Client_t ReadClient(int Address) { int A = Address; Client_t ret = new Client_t(); ret.valid = ReadInteger(A); ret.name = ReadString(A + 0xC, 15); ret.team = ReadInteger(A + 0x1C); ret.rank = ReadInteger(A + 0x24); ret.perk = ReadInteger(A + 0x38); ret.score = ReadInteger(A + 0x44); ret.attacking = ReadInteger(A + 0x4A0); ret.zooming = ReadInteger(A + 0x4A8); return ret; }
And you're done. Leave any questions down in the comments with a mention, and I'll answer as many as I can. Happy fragging!Code:Client_t[] clients = new Client_t[18]; int a = 0xAD28F8; for (int i = 0; i < clients.Length; i++) { clients[i] = ReadClient(a); a += 0x564; }
@rawr im a tiger
Started by basicly copying and pasting to try and understand it ... I get knocked off right away D:
Every Client_t is marked as an error ... Error 1 Expected class, delegate, enum, interface, or struct.Code:using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MW3Kill { class Client_t { public int valid; public string name; public int team; public int rank; public int perk; public int score; public int attacking; public int zooming; } public static Client_t ReadClient(int Address) { int A = Address; Client_t ret = new Client_t(); ret.valid = ReadInteger(A); ret.name = ReadString(A + 0xC, 15); ret.team = ReadInteger(A + 0x1C); ret.rank = ReadInteger(A + 0x24); ret.perk = ReadInteger(A + 0x38); ret.score = ReadInteger(A + 0x44); ret.attacking = ReadInteger(A + 0x4A0); ret.zooming = ReadInteger(A + 0x4A8); return ret; } Client_t[] clients = new Client_t[18]; int a = 0xAD28F8; for (int i = 0; i < clients.Length; i++) { clients[i] = ReadClient(a); a += 0x564; } }
While Client_t is my class ...
@rawr im a tiger
Im so sorry im so nooby
So basicly, i replaced them to get the error of Client_t gone ... New error pops up : Error 1 An object reference is required for the non-static field, method, or property 'MW3Kill.Client_t.ReadInteger(int, int)'. It points at -> ReadString(A + 0xC, 15); And everything with ReadString in itCode:using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; namespace MW3Kill { class Client_t { public int valid; public string name; public int team; public int rank; public int perk; public int score; public int attacking; public int zooming; #region Basic Stuff [DllImport("kernel32.dll")] private static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten); [DllImport("kernel32.dll")] private static extern Int32 WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesWritten); IntPtr pHandel; public bool Process_Handle(string ProcessName) { try { Process[] ProcList = Process.GetProcessesByName(ProcessName); if (ProcList.Length == 0) return false; else { pHandel = ProcList[0].Handle; return true; } } catch (Exception ex) { Console.Beep(); Console.WriteLine("Process_Handle - " + ex.Message); return false; } } private byte[] Read(int Address, int Length) { byte[] Buffer = new byte[Length]; IntPtr Zero = IntPtr.Zero; ReadProcessMemory(pHandel, (IntPtr)Address, Buffer, (UInt32)Buffer.Length, out Zero); return Buffer; } private void Write(int Address, int Value) { byte[] Buffer = BitConverter.GetBytes(Value); IntPtr Zero = IntPtr.Zero; WriteProcessMemory(pHandel, (IntPtr)Address, Buffer, (UInt32)Buffer.Length, out Zero); } #endregion #region Write Functions (Integer & String) public void WriteInteger(int Address, int Value) { Write(Address, Value); } public void WriteString(int Address, string Text) { byte[] Buffer = new ASCIIEncoding().GetBytes(Text); IntPtr Zero = IntPtr.Zero; WriteProcessMemory(pHandel, (IntPtr)Address, Buffer, (UInt32)Buffer.Length, out Zero); } public void WriteBytes(int Address, byte[] Bytes) { IntPtr Zero = IntPtr.Zero; WriteProcessMemory(pHandel, (IntPtr)Address, Bytes, (uint)Bytes.Length, out Zero); } public void WriteNOP(int Address) { byte[] Buffer = new byte[] { 0x90, 0x90, 0x90, 0x90, 0x90 }; IntPtr Zero = IntPtr.Zero; WriteProcessMemory(pHandel, (IntPtr)Address, Buffer, (UInt32)Buffer.Length, out Zero); } #endregion #region Read Functions (Integer & String) public int ReadInteger(int Address, int Length = 4) { return BitConverter.ToInt32(Read(Address, Length), 0); } public string ReadString(int Address, int Length = 4) { return new ASCIIEncoding().GetString(Read(Address, Length)); } public byte[] ReadBytes(int Address, int Length) { return Read(Address, Length); } #endregion public static Client_t ReadClient(int Address) { int A = Address; Client_t ret = new Client_t(); ret.valid = ReadInteger(A); ret.name = ReadString(A + 0xC, 15); ret.team = ReadInteger(A + 0x1C); ret.rank = ReadInteger(A + 0x24); ret.perk = ReadInteger(A + 0x38); ret.score = ReadInteger(A + 0x44); ret.attacking = ReadInteger(A + 0x4A0); ret.zooming = ReadInteger(A + 0x4A8); Client_t[] clients = new Client_t[18]; int a = 0xAD28F8; for (int i = 0; i < clients.Length; i++) { clients[i] = ReadClient(a); a += 0x564; } return ret; } } }
replace public by static isaakske...
@everyone, sorry if it's wrong, i'm also n00b xD
First of all, the way you've write the struct its no managed code, i guess (I'm a kinda noob at C# as well), here's how they should look like:
Secondly, this way to read the struct is the really really bad.. I mean, if the struct has, let's say 20 fields to be read... you gonna have to write 20 lines of code when you can "easily" do it on 3:Code:[StructLayout(LayoutKind.Explicit)] struct ClientT { [FieldOffset(0x0), MarshalAs(UnmanagedType.Bool)] public bool Valid; [FieldOffset(0xC), MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string Name; [FieldOffset(0x1C)] public Int32 Team; [FieldOffset(0x24)] public Int32 Rank; [FieldOffset(0x38)] public Int32 Perk; [FieldOffset(0x44)] public Int32 Score; [FieldOffset(0x4A0), MarshalAs(UnmanagedType.Bool)] public bool Attacking; [FieldOffset(0x4A8), MarshalAs(UnmanagedType.Bool)] public bool Zooming; }
And the ReadBytes method:Code:private const int MAXPLAYERS = 18; ClientT[] Client; unsafe void ReadGame() { while (true) { //Call it on another thread OFC... fixed (byte* pBuffer = ReadBytes(OFFS_Client, sizeOfClient * MAXPLAYERS)) { for (int i = 0; i < MAXPLAYERS; i++) { Client[i] = *(ClientT*) (pBuffer + sizeOfClient * i); } } } }
BTW, this is from and old External Radar that I was making... Now feel free to knock you head on the wall trying to understand... (I did that)Code:private byte[] ReadBytes(int Adress, int Size) { byte[] read = new byte[Size]; int bytesRead; ReadProcessMemory(MW3Process, (IntPtr) Adress, read, Size, out bytesRead); return read; }
EDIT: Here's the source of the radar with all structs and reading methods on C#. The radar IS REALLY BUGGED, that's why I gave up on it... As I said I'm not good with C# as well
It's just source code.. but here a virus scan anyway
https://www.virustotal.com/file/28c2...is/1344401195/
Last edited by MarkHC; 08-08-2012 at 01:05 AM.
CoD Minion from 09/19/2012 to 01/10/2013
barata55 (08-09-2012)
why not just create the struct as it is with correct size and stuff, rather than making a custom one and reading values to it separately.
Also i'm assuming ReadInteger() uses ReadProcessMemory(), calling RPM so many times is gona make your shizz run slower.
Create the struct as its supposed to be with correct size and stuff and not a custom one. Then before you use the struct for your aimbot or esp or whatever, read the whole client struct in game memory to your allocated 18 client structs, with size of 0x564 * 18.
Also why not just do something like this .. saves the need to input address each time
instead ofCode:public static Client_t ReadClient(int clientnum) { int A = 0xAD28F8 + ( 0x564 * clientnum ); Client_t ret = new Client_t();
I have never coded in C#, but i smell memory leaks ... not sure, why dont you do something like this?public static Client_t ReadClient(int Address)
{
int A = Address;
Client_t ret = new Client_t();
and so on... because you've already allocated memory for those 18 clients here ... ?Code:public static void ReadClient(int clientnum, Client_t* client) { int A = 0xAD28F8 + ( 0x564 * clientnum ); client->valid = ReadInteger(A);
and just pass the pointer of client and modify its values in the func ...Code:Client_t[] clients = new Client_t[18]; int a = 0xAD28F8; for (int i = 0; i < clients.Length; i++) { clients[i] = ReadClient(a); a += 0x564; }
but then again ive never coded in C# and not even sure new Client_t(); means as it would in C++.
Last edited by intervention61; 08-08-2012 at 10:56 AM.
"Joker: why the hakcer are steaklign us name it´s the greatest asshole and motherfucker and i fuck him or her mother"
barata55 (08-09-2012),rawr im a tiger (03-15-2013)