C# Memory class x86

Posts 1–15 of 31 · Page 1 of 3
C# Memory class x86
Hello MPGH, Today I'm going to be uploading a basic memory class for C# that I created in my spare time.

Features:
WriteBytes
WriteByte
WriteInt
WriteString
WriteFloat
ReadBytes
ReadByte
ReadInt
ReadString
ReadString Advanced
ReadFloat
PatternScan


Source:
Code:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
 
class Memory
{
    private IntPtr pHandel = IntPtr.Zero;
    private Process attachedProcess = null;
    private byte[] buffer;
 
    public bool Open_pHandel(string processName)
    {
        Process[] proc = Process.GetProcessesByName(processName);
 
        if (proc.Length == 0)
            return false;
        else if (proc.Length > 1)
            throw new Exception("More then one process found.");
        else
        {
            attachedProcess = proc[0];
            pHandel = proc[0].Handle;
            return true;
        }
    }
 
    #region x86
    #region Write
    public bool WriteBytes(int address, byte[] value, bool virtualProtect = false)
    {
        int countOfUsed = 0;
        bool result = false;
        uint oldProtection = 0;
 
 
        if (virtualProtect)
            Win32.x86.VirtualProtectEx(pHandel, address, (uint)value.Length, 0x40, out oldProtection);
 
        result = Win32.x86.WriteProcessMemory(pHandel, address, value, (uint)value.Length, out countOfUsed);
 
        if (virtualProtect)
            Win32.x86.VirtualProtectEx(pHandel, address, (uint)value.Length, oldProtection, out oldProtection);
 
        return result;
    }
 
    public bool WriteInt(int address, int value, bool virtualProtect = false)
    {
        buffer = BitConverter.GetBytes(value);
        return WriteBytes(address, buffer, virtualProtect);
    }
 
    public bool WriteByte(int address, byte value, bool virtualProtect = false)
    {
        buffer = new byte[] { value };
        return WriteBytes(address, buffer, virtualProtect);
    }
 
    public bool WriteString(int address, string value, bool virtualProtect = false)
    {
        buffer = Encoding.ASCII.GetBytes(value);//No unicode support atm
        return WriteBytes(address, buffer, virtualProtect);
    }
 
    public bool WriteFloat(int address, float value, bool virtualProtect = false)
    {
        buffer = BitConverter.GetBytes(value);
        return WriteBytes(address, buffer, virtualProtect);
    }
    #endregion
    #region Read
    public byte[] ReadBytes(int address, int length)
    {
        byte[] readBytes = new byte[length];
        int numBytesChanged = 0;
 
        Win32.x86.ReadProcessMemory(pHandel, address, readBytes, (uint)length, out numBytesChanged);
 
        return readBytes;
    }
 
    public int ReadInt(int address)
    {
        return BitConverter.ToInt32(ReadBytes(address, 4), 0);
    }
 
    public byte ReadByte(int address)
    {
        return ReadBytes(address, 1)[0];
    }
 
    public string ReadString(int address, int length)
    {//No unicode support
        return Encoding.ASCII.GetString(ReadBytes(address, length));
    }
 
    public string ReadStringAdvanced(int address, int maxStringLength = 1000)
    {//No unicode support
        string result = null;
        byte currentByte = 0;
 
        for (int i = 0; i < maxStringLength; i++)
        {
            currentByte = ReadByte(address + i);
 
            if (currentByte == 0x00)
                break;
            else
                result += (char)currentByte;
        }
 
        return result;
    }
 
    public float ReadFloat(int address)
    {
        return BitConverter.ToSingle(ReadBytes(address, 4), 0);
    }
    #endregion
    #region Scans
    public int PatternScan(string pattern)
    {
        string[] splitPattern = pattern.Split(' ');
        bool[] indexValid = new bool[splitPattern.Length];
        byte[] indexValue = new byte[splitPattern.Length];
 
        byte tempByte = (byte)0x00;
 
        for (int i = 0; i < splitPattern.Length; i++)
        {
            indexValid[i] = !(splitPattern[i] == "??" || splitPattern[i] == "?");
            if (Byte.TryParse(splitPattern[i], out tempByte))
                indexValue[i] = tempByte;
            else
                indexValid[i] = false;
        }
 
        int startOfMemory = attachedProcess.MainModule.BaseAddress.ToInt32();
        int endOfMemory = attachedProcess.MainModule.ModuleMemorySize;
 
        for (int currentMemAddy = startOfMemory; currentMemAddy < endOfMemory; currentMemAddy++)
        {
            bool complete = false;
            for (int i = 0; i < splitPattern.Length; i++)
            {
                if (!indexValid[i])
                    continue;
 
                tempByte = ReadByte(currentMemAddy + i);
 
                if (tempByte != indexValue[i])
                    break;
 
                if (i == splitPattern.Length - 1)
                    complete = true;
 
                if (complete)
                    break;
            }
 
            if (complete)
                return currentMemAddy;
        }
 
        throw new Exception("Pattern not found!");
        return 0;
    }
    #endregion
    #endregion
 
    private static class Win32
    {
        public static class NativeMethods
        {
            #region IsWow64Process
            public static bool IsWow64Process(IntPtr handel)
            {
                bool isTarget64Bit = false;
                IsWow64Process(handel, out isTarget64Bit);
                return isTarget64Bit;
            }
 
            [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
            #endregion
        }
 
        public static class x64
        {
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern bool VirtualProtectEx(IntPtr hProcess, long lpAddress, UInt32 dwSize, uint flNewProtect, out uint lpflOldProtect);
 
            [DllImport("kernel32.dll")]
            public static extern bool ReadProcessMemory(IntPtr hProcess, long lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesWritten);
 
            [DllImport("kernel32.dll")]
            public static extern bool WriteProcessMemory(IntPtr hProcess, long lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesWritten);
        }
 
        public static class x86
        {
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern bool VirtualProtectEx(IntPtr hProcess, int lpAddress, UInt32 dwSize, uint flNewProtect, out uint lpflOldProtect);
 
            [DllImport("kernel32.dll")]
            public static extern bool ReadProcessMemory(IntPtr hProcess, int lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesWritten);
 
            [DllImport("kernel32.dll")]
            public static extern bool WriteProcessMemory(IntPtr hProcess, int lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesWritten);
        }
    }
}
usage:
Code:
if(Open_pHandel("processName"))
{
     int address = PatternScan("02 255 12 41 ?? 54 ? 12 ? 52 ?? 23");
     WriteBytes(address, new byte[] {0x00, 0x00});
}
Midway typing this I noticed I left the gas on, on the stove and I got a massive headache xd whoops

Features I will add later:
x64 support.
idk what else


Press thanks if this helps you!
Thanks James, greet work,helpfull for newbie
Quote Originally Posted by Silent View Post
Hello MPGH, Today I'm going to be uploading a basic memory class for C# that I created in my spare time.

Features:
haha thanks man, just started to switch to C#, very useful
Quote Originally Posted by Silent View Post
Hello MPGH, Today I'm going to be uploading a basic memory class for C# that I created in my spare time.

Features:
WriteBytes
WriteByte
WriteInt
WriteString
WriteFloat
ReadBytes
ReadByte
ReadInt
ReadString
ReadString Advanced
ReadFloat
PatternScan


Source:
Code:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
 
class Memory
{
    private IntPtr pHandel = IntPtr.Zero;
    private Process attachedProcess = null;
    private byte[] buffer;
 
    public bool Open_pHandel(string processName)
    {
        Process[] proc = Process.GetProcessesByName(processName);
 
        if (proc.Length == 0)
            return false;
        else if (proc.Length > 1)
            throw new Exception("More then one process found.");
        else
        {
            attachedProcess = proc[0];
            pHandel = proc[0].Handle;
            return true;
        }
    }
 
    #region x86
    #region Write
    public bool WriteBytes(int address, byte[] value, bool virtualProtect = false)
    {
        int countOfUsed = 0;
        bool result = false;
        uint oldProtection = 0;
 
 
        if (virtualProtect)
            Win32.x86.VirtualProtectEx(pHandel, address, (uint)value.Length, 0x40, out oldProtection);
 
        result = Win32.x86.WriteProcessMemory(pHandel, address, value, (uint)value.Length, out countOfUsed);
 
        if (virtualProtect)
            Win32.x86.VirtualProtectEx(pHandel, address, (uint)value.Length, oldProtection, out oldProtection);
 
        return result;
    }
 
    public bool WriteInt(int address, int value, bool virtualProtect = false)
    {
        buffer = BitConverter.GetBytes(value);
        return WriteBytes(address, buffer, virtualProtect);
    }
 
    public bool WriteByte(int address, byte value, bool virtualProtect = false)
    {
        buffer = new byte[] { value };
        return WriteBytes(address, buffer, virtualProtect);
    }
 
    public bool WriteString(int address, string value, bool virtualProtect = false)
    {
        buffer = Encoding.ASCII.GetBytes(value);//No unicode support atm
        return WriteBytes(address, buffer, virtualProtect);
    }
 
    public bool WriteFloat(int address, float value, bool virtualProtect = false)
    {
        buffer = BitConverter.GetBytes(value);
        return WriteBytes(address, buffer, virtualProtect);
    }
    #endregion
    #region Read
    public byte[] ReadBytes(int address, int length)
    {
        byte[] readBytes = new byte[length];
        int numBytesChanged = 0;
 
        Win32.x86.ReadProcessMemory(pHandel, address, readBytes, (uint)length, out numBytesChanged);
 
        return readBytes;
    }
 
    public int ReadInt(int address)
    {
        return BitConverter.ToInt32(ReadBytes(address, 4), 0);
    }
 
    public byte ReadByte(int address)
    {
        return ReadBytes(address, 1)[0];
    }
 
    public string ReadString(int address, int length)
    {//No unicode support
        return Encoding.ASCII.GetString(ReadBytes(address, length));
    }
 
    public string ReadStringAdvanced(int address, int maxStringLength = 1000)
    {//No unicode support
        string result = null;
        byte currentByte = 0;
 
        for (int i = 0; i < maxStringLength; i++)
        {
            currentByte = ReadByte(address + i);
 
            if (currentByte == 0x00)
                break;
            else
                result += (char)currentByte;
        }
 
        return result;
    }
 
    public float ReadFloat(int address)
    {
        return BitConverter.ToSingle(ReadBytes(address, 4), 0);
    }
    #endregion
    #region Scans
    public int PatternScan(string pattern)
    {
        string[] splitPattern = pattern.Split(' ');
        bool[] indexValid = new bool[splitPattern.Length];
        byte[] indexValue = new byte[splitPattern.Length];
 
        byte tempByte = (byte)0x00;
 
        for (int i = 0; i < splitPattern.Length; i++)
        {
            indexValid[i] = !(splitPattern[i] == "??" || splitPattern[i] == "?");
            if (Byte.TryParse(splitPattern[i], out tempByte))
                indexValue[i] = tempByte;
            else
                indexValid[i] = false;
        }
 
        int startOfMemory = attachedProcess.MainModule.BaseAddress.ToInt32();
        int endOfMemory = attachedProcess.MainModule.ModuleMemorySize;
 
        for (int currentMemAddy = startOfMemory; currentMemAddy < endOfMemory; currentMemAddy++)
        {
            bool complete = false;
            for (int i = 0; i < splitPattern.Length; i++)
            {
                if (!indexValid[i])
                    continue;
 
                tempByte = ReadByte(currentMemAddy + i);
 
                if (tempByte != indexValue[i])
                    break;
 
                if (i == splitPattern.Length - 1)
                    complete = true;
 
                if (complete)
                    break;
            }
 
            if (complete)
                return currentMemAddy;
        }
 
        throw new Exception("Pattern not found!");
        return 0;
    }
    #endregion
    #endregion
 
    private static class Win32
    {
        public static class NativeMethods
        {
            #region IsWow64Process
            public static bool IsWow64Process(IntPtr handel)
            {
                bool isTarget64Bit = false;
                IsWow64Process(handel, out isTarget64Bit);
                return isTarget64Bit;
            }
 
            [DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
            [return: MarshalAs(UnmanagedType.Bool)]
            private static extern bool IsWow64Process([In] IntPtr process, [Out] out bool wow64Process);
            #endregion
        }
 
        public static class x64
        {
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern bool VirtualProtectEx(IntPtr hProcess, long lpAddress, UInt32 dwSize, uint flNewProtect, out uint lpflOldProtect);
 
            [DllImport("kernel32.dll")]
            public static extern bool ReadProcessMemory(IntPtr hProcess, long lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesWritten);
 
            [DllImport("kernel32.dll")]
            public static extern bool WriteProcessMemory(IntPtr hProcess, long lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesWritten);
        }
 
        public static class x86
        {
            [DllImport("kernel32.dll", SetLastError = true)]
            public static extern bool VirtualProtectEx(IntPtr hProcess, int lpAddress, UInt32 dwSize, uint flNewProtect, out uint lpflOldProtect);
 
            [DllImport("kernel32.dll")]
            public static extern bool ReadProcessMemory(IntPtr hProcess, int lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesWritten);
 
            [DllImport("kernel32.dll")]
            public static extern bool WriteProcessMemory(IntPtr hProcess, int lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out int lpNumberOfBytesWritten);
        }
    }
}
usage:
Code:
if(Open_pHandel("processName"))
{
     int address = PatternScan("02 255 12 41 ?? 54 ? 12 ? 52 ?? 23");
     WriteBytes(address, new byte[] {0x00, 0x00});
}
Midway typing this I noticed I left the gas on, on the stove and I got a massive headache xd whoops

Features I will add later:
x64 support.
idk what else


Press thanks if this helps you!
Little Question, Is It Like
Code:
WriteByte(Addres, Value)
Quote Originally Posted by Recigy View Post
Little Question, Is It Like
Code:
WriteByte(Addres, Value)
You need to call open phandle before writing memoery though.

EDIT: and you need to add ";" at the end
Quote Originally Posted by Silent View Post


You need to call open phandle before writing memoery though.

EDIT: and you need to add ";" at the end
Thanks Bro!
I'm Using AMDUser's MemoryClass So Yeh I'm Kinda New To This =)
Why did you decide not to include unicode support? Literally the same thing as your ascii code...

Code:
public string ReadStringUnicode(int address, int length)
    {//Now with unicode support.
        return Encoding.Unicode.GetString(ReadBytes(address, length));
    }
Quote Originally Posted by HexMurder View Post
Why did you decide not to include unicode support? Literally the same thing as your ascii code...

Code:
public string ReadStringUnicode(int address, int length)
    {//Now with unicode support.
        return Encoding.Unicode.GetString(ReadBytes(address, length));
    }
Hahahaahha broo could u please accept my skype? I still remember the zombies hack u made xD
Quote Originally Posted by Recigy View Post
Hahahaahha broo could u please accept my skype? I still remember the zombies hack u made xD
I have a lot of skype requests. What is your name? lol
Quote Originally Posted by HexMurder View Post


I have a lot of skype requests. What is your name? lol
Secret.recigy
Quote Originally Posted by HexMurder View Post
Why did you decide not to include unicode support? Literally the same thing as your ascii code...

Code:
public string ReadStringUnicode(int address, int length)
    {//Now with unicode support.
        return Encoding.Unicode.GetString(ReadBytes(address, length));
    }
Never thought to add the option. thanks though.
Quote Originally Posted by HexMurder View Post
Why did you decide not to include unicode support? Literally the same thing as your ascii code...
Taking it a step further

Code:
public string ReadString(int address, int length, Encoding encoding)
{
  //Now with everything support.
  return encoding.GetString(this.ReadBytes(address, length));
}
Quote Originally Posted by Biesi View Post


Taking it a step further

Code:
public string ReadString(int address, int length, Encoding encoding)
{
  //Now with everything support.
  return encoding.GetString(this.ReadBytes(address, length));
}
Sad to admit this but i actually had to boot my IDE up to see if that was a read thing lmao.
Some general improvements I'd recommend for this class are:

- Use the sealed (and optionally internal) keyword unless you explicitly want people to overwrite your class (which doesn't make sense in this case imo)
- Make the class open the handle on creation of the instance.
- Use Win32 calls to get the handle and pass the VMRead and VMWrite access rights.
As Microsoft states
Only processes started through a call to M:System.Diagnostics.Process.Start set the P:System.Diagnostics.Process.Handle property of the corresponding T:System.Diagnostics.Process instances.
- Implement IDisposable and a finalizer and close the handle when the class gets finalized or disposed (in case you're opening a native handle yourself)
- Implement support for Encodings (best would be to passed as a parameter in the constructor and then used for read and write operations)
- Fix your code-style and naming to obey the general rules that apply for C#
- Don't use constant numbers for your calls to VirtualProtectEx, create an enum (using the Flags attribute) for that
- Throw a Win32Exception depending on Marshal.GetLastWin32Error
- Do not throw exceptions of type Exception (that's considered bad practice since they're a pain in the ass to catch)
- Use method overloading rather than optional parameters

I hope you won't consider this as hate or bashing in any way. I just want you to improve your coding style (regarding C# and .NET) to things that might be considered best practice

I'd also recommend you to get your hands on an educational copy of ReSharper or use the Visual Studio Code Analysis (I don't know whether this is part of the community edition) as they provide great features to analyze your code and recommend (or enforce) changes

Feel free to contact me for resources or questions regarding the suggestions I made. I'm always glad to help people who are interested in learning
Posts 1–15 of 31 · Page 1 of 3

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us