[Release][C#] In/Out of Process Memory Class menu

Shout-Out

User Tag List

Results 1 to 10 of 10
  1. #1
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Release][C#] In/Out of Process Memory Class

    Yes it's missing functionality. No I don't care.

    Yes it's quite ugly due to the crazy defines. No, I don't care.

    There are quite possibly some bugs, but none that I can see. (I didn't bother to test it to be honest)

    It's clean, and fast. (Strip away the preprocessor defs and you'll see.)

    A single comment switches the entire class to in or out of process mode.

    Out of process mode requires ReadProcessMemory and of WriteProcessMemory.

    In process only requires WriteProcessMemory. (To do bulk writing easily.)

    It should show people how to use pointers in C# (hopefully) a little bit. This is *very* simple code, so I don't expect many questions to be raised, other than a few implementation details, such as copying structs to local memory before reading/returning. It's actually faster to do it this way, and it allows you to leverage the Marshaler to do most of the work for you.

    Note: In process users can define proper unmanaged structs, and directly dereference them in memory. Unfortunately, generic types don't allow me to use the functionality, so it's kind of a moot point.

    Example:

    Code:
        struct SomeStruct
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
            public int[] SomeInts;
        }
    Is a managed struct, which requires you to run through the marshaler.

    Code:
        unsafe struct SomeStruct
        {
            public fixed int SomeInts [10];
        }
    Is an unmanaged struct. You can directly dereference it via:

    Code:
                SomeStruct myStruct = *(SomeStruct*) address;
    Which is far faster than running it through the Marshaler. (I highly suggest you do this whenever possible!) You can even keep just a pointer to the struct, and use the -> syntax to access members. (Great for getting/setting global structs in WoW.)

    Example of the above:

    Code:
    WoWCTM->Position.X = clickPos.X;
    Once you grab the struct pointer once, you won't need to read/write memory again, as you can directly access it.

    Anyhow! With that said, here's the code.

    If you find bugs, just post them, I'll fix them ASAP.

    Code:
    // Comment this out if you want to use this class out of process.
    //#define IN_PROC
    // Comment this out if you want boolean values to be read as a byte, instead of a 4 byte integer.
    #define BOOL_AS_INT
    // Comment this out if you want 'char' to be treated as a double byte character.
    #define CHAR_AS_SHORT
    // Comment this out if you want to treat strings as ANSI strings. Otherwise, it will use Unicode. (MBCS)
    #define UNICODE_STRINGS
    
    using System;
    using System.Runtime.InteropServices;
    using System.Text;
    
    #if !IN_PROC
    using System.Collections.Generic;
    #endif
    
    namespace MemoryLib
    {
        public static class Memory
        {
            public static T Read<T>(IntPtr address)
            {
                object ret;
    #if IN_PROC
                unsafe
                {
                    if (typeof (T) == typeof (IntPtr))
                        ret = *(IntPtr*) address;
                    else
                        switch (Type.GetTypeCode(typeof (T)))
                        {
                            case TypeCode.Boolean:
    #if BOOL_AS_INT
                                ret = *(int*) address != 0;
    #else
                            ret = *(byte*) address != 0;
    #endif
    
                                break;
                            case TypeCode.Char:
    #if CHAR_AS_SHORT
                                ret = (char) *(short*) address;
    #else
                            ret = (char) *(byte*) address;
    #endif
                                break;
                            case TypeCode.SByte:
                                ret = *(sbyte*) address;
                                break;
                            case TypeCode.Byte:
                                ret = *(byte*) address;
                                break;
                            case TypeCode.Int16:
                                ret = *(short*) address;
                                break;
                            case TypeCode.UInt16:
                                ret = *(ushort*) address;
    
                                break;
                            case TypeCode.Int32:
                                ret = *(int*) address;
                                break;
                            case TypeCode.UInt32:
                                ret = *(uint*) address;
                                break;
                            case TypeCode.Int64:
                                ret = *(long*) address;
                                break;
                            case TypeCode.UInt64:
                                ret = *(ulong*) address;
                                break;
                            case TypeCode.Single:
                                ret = *(float*) address;
                                break;
                            case TypeCode.Double:
                                ret = *(double*) address;
                                break;
                            case TypeCode.Decimal:
                                ret = *(decimal*) address;
                                break;
                            case TypeCode.String:
    #if UNICODE_STRINGS
                                ret = Marshal.PtrToStringUni(address);
    #else
                            ret = Marshal.PtrToStringAnsi(address);
    #endif
                                break;
                            default:
                                // Probably shouldn't do this, but whatever. :)
                                // This should let us use classes instead of structs.
                                // However, structs will be more accurate, and less volitile.
                                ret = Marshal.PtrToStructure(address, typeof (T));
                                break;
                        }
                }
    #else // OUT OF PROCESS
                if (typeof(T) == typeof(string))
                {
                    var bytes = new List<byte>();
                    int offset = 0;
                    byte lastByte;
                    while ((lastByte = Read<byte>((IntPtr)(address.ToInt32() + offset))) != 0)
                    {
                        offset++;
                        bytes.Add(lastByte);
                    }
    #if UNICODE_STRINGS
                    ret = Encoding.Unicode.GetString(bytes.ToArray());
    #else
                            ret = Encoding.ASCII.GetString(bytes.ToArray());
    #endif
                    return (T) ret;
                }
    
                int numBytes = Marshal.SizeOf(typeof (T));
                if (typeof(T) == typeof(IntPtr))
                {
                    // Note: This will work on x86/x64, due to how IntPtr changes
                    // its size depending on platform. (4 bytes for x86, 8 bytes for x64)
                    // It's valid to set an IntPtr as a long. (It will auto-convert properly)
                    ret = (IntPtr) BitConverter.ToInt64(Win32.ReadBytes(address, numBytes), 0);
                }
                else
                    switch (Type.GetTypeCode(typeof(T)))
                    {
                        case TypeCode.Boolean:
    #if BOOL_AS_INT
                            ret = BitConverter.ToInt32(Win32.ReadBytes(address, 4), 0) != 0;
    #else
                            ret = Win32.ReadBytes(address, 1)[0] != 0;
    #endif
    
                            break;
                        case TypeCode.Char:
    #if CHAR_AS_SHORT
                            ret = BitConverter.ToChar(Win32.ReadBytes(address, 2), 0);
    #else
                            ret = (char) Win32.ReadBytes(address, 1)[0];
    #endif
                            break;
                        case TypeCode.SByte:
                            ret = (sbyte)Win32.ReadBytes(address, numBytes)[0];
                            break;
                        case TypeCode.Byte:
                            ret = Win32.ReadBytes(address, numBytes)[0];
                            break;
                        case TypeCode.Int16:
                            ret = BitConverter.ToInt16(Win32.ReadBytes(address, numBytes), 0);
                            break;
                        case TypeCode.UInt16:
                            ret = BitConverter.ToUInt16(Win32.ReadBytes(address, numBytes), 0);
                            break;
                        case TypeCode.Int32:
                            ret = BitConverter.ToInt32(Win32.ReadBytes(address, numBytes), 0);
                            break;
                        case TypeCode.UInt32:
                            ret = BitConverter.ToUInt32(Win32.ReadBytes(address, numBytes), 0);
                            break;
                        case TypeCode.Int64:
                            ret = BitConverter.ToInt64(Win32.ReadBytes(address, numBytes), 0);
                            break;
                        case TypeCode.UInt64:
                            ret = BitConverter.ToUInt64(Win32.ReadBytes(address, numBytes), 0);
                            break;
                        case TypeCode.Single:
                            ret = BitConverter.ToSingle(Win32.ReadBytes(address, numBytes), 0);
                            break;
                        case TypeCode.Double:
                            ret = BitConverter.ToDouble(Win32.ReadBytes(address, numBytes), 0);
                            break;
                        default:
                            // Yes, sadly, this is the easiest (and somewhat fastest)
                            // way to do this.
                            // Allocate the required amount of memory to store the struct.
                            IntPtr dataStore = Marshal.AllocHGlobal(numBytes);
                            // Read the data from the process.
                            byte[] data = Win32.ReadBytes(address, numBytes);
                            // Copy the data to our own memory, so we can make the Marshaler read
                            // from there (thus; doing all the byte packing, alignment, etc, for us.)
                            Marshal.Copy(data, 0, dataStore, numBytes);
                            ret = Marshal.PtrToStructure(dataStore, typeof(T));
                            // Make sure we release the memory we allocated, to avoid memory leaks.
                            Marshal.FreeHGlobal(dataStore);
                            break;
                    }
    #endif
                return (T) ret;
            }
    
            public static T ReadStruct<T>(IntPtr address) where T : struct
            {
    #if IN_PROC
                return (T) Marshal.PtrToStructure(address, typeof (T));
    #else
                unsafe
                {
                    int numBytes = Marshal.SizeOf(typeof (T));
                    byte* dataStore = stackalloc byte[numBytes];
                    byte[] data = Win32.ReadBytes(address, numBytes);
                    Marshal.Copy(data, 0, (IntPtr)dataStore, numBytes);
                    var ret = (T)Marshal.PtrToStructure((IntPtr)dataStore, typeof(T));
                    return ret;
                }
    #endif
            }
    
            public static void Write<T>(IntPtr address, T value)
            {
                if (value is string)
                {
                    // Laziness ftw.
    #if !UNICODE_STRINGS
                    Win32.WriteBytes(address, Encoding.ASCII.GetBytes(value as string));
    #else
                    Win32.WriteBytes(address, Encoding.Unicode.GetBytes(value as string));
    #endif
                }
                else
                {
    #if IN_PROC
                    Marshal.StructureToPtr(value, address, true);
    #else
                    int numBytes = Marshal.SizeOf(value);
                    unsafe
                    {
                        byte* bytes = stackalloc byte[numBytes];
                        Marshal.StructureToPtr(value, (IntPtr) bytes, true);
                        byte[] writeBytes = new byte[numBytes];
                        Marshal.Copy((IntPtr) bytes, writeBytes, 0, numBytes);
                        Win32.WriteBytes(address, writeBytes);
                    }
    #endif
                }
            }
        }
    }
    Last edited by Apoc; 03-10-2010 at 04:56 PM. Reason: Copy/paste code is BAD

    [Release][C#] In/Out of Process Memory Class
  2. #2
    Danne206's Avatar Contributor
    Reputation
    183
    Join Date
    Jan 2008
    Posts
    717
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks alot mate! I appreciate it!
    Dahnniel [DOT] s [AT] gmail [DOT] com

  3. #3
    miceiken's Avatar Contributor Authenticator enabled
    Reputation
    209
    Join Date
    Dec 2007
    Posts
    401
    Thanks G/R
    7/9
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    When reading strings this throws an exception
    int numBytes = Marshal.SizeOf(typeof(T));
    Type 'System.String' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed.

  4. #4
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Fix't. Forgot to check for string types before anything else in the OOP mode.

  5. #5
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Apoc View Post
    Fix't. Forgot to check for string types before anything else in the OOP mode.
    Silly rabbit, Trix are for kids!

  6. #6
    miceiken's Avatar Contributor Authenticator enabled
    Reputation
    209
    Join Date
    Dec 2007
    Posts
    401
    Thanks G/R
    7/9
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks alot

  7. #7
    kolis764's Avatar Member
    Reputation
    -5
    Join Date
    Feb 2007
    Posts
    18
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    trying to have a "rugged" attitude on the internet, fail.

  8. #8
    Apoc's Avatar Angry Penguin
    Reputation
    1388
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/13
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by kolis764 View Post
    trying to have a "rugged" attitude on the internet, fail.
    Wat ?

  9. #9
    Cypher's Avatar Kynox's Sister's Pimp
    Reputation
    1358
    Join Date
    Apr 2006
    Posts
    5,368
    Thanks G/R
    0/6
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Originally Posted by Apoc View Post
    Wat ?
    I think he's trying to say that when you said "I don't care" in your post that you were trying to come off as 'tough' or 'rugged'...

    But, whatever... Personally I don't care what he was trying to say, because whatever it was, I'm sure it was stupid.

  10. #10
    Dragoneon[FTW]'s Avatar Private
    Reputation
    1
    Join Date
    Mar 2010
    Posts
    1
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    nice
    very helpful to beginners

Similar Threads

  1. In Process vs. Out of Process memory editing
    By motodrizzle in forum Programming
    Replies: 2
    Last Post: 07-16-2013, 08:23 AM
  2. [Code Release] C#, Out Of Process - Get Player Name
    By SwInY in forum WoW Memory Editing
    Replies: 4
    Last Post: 05-04-2011, 04:31 PM
  3. a little bit of c++ and reading process memory..
    By arynock in forum WoW Memory Editing
    Replies: 10
    Last Post: 05-22-2008, 04:12 AM
  4. Out of EotS - any class
    By thaer in forum World of Warcraft Exploits
    Replies: 8
    Last Post: 02-28-2008, 08:33 PM
  5. EotS get out of bubble [All classes]
    By Tenni-T in forum World of Warcraft Exploits
    Replies: 10
    Last Post: 08-29-2007, 03:25 AM
All times are GMT -5. The time now is 07:25 PM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search