C# Write process memory

08/15/2008 16:00 Miv#1
ok so i have a question about how do i use the api function writeprocessmemory in C#, i already have readprocessmemory but i can't seem to get writeprocessmemory... so if anyone could show me the call and an example (preferably a pinball example) it would be very helpful :)


heres what i have so far:
PHP Code:
        //==============================================================================================//
        // Function:            MemoryOpen(int ProcessID[, Enum DesiredAccess[, bool InheritHandle]]))  //
        //______________________________________________________________________________________________//
        // Description:         Opens a process and enables all possible access rights to the process,  //
        //                      the Process ID of the process is used to specify which process to open. //
        //______________________________________________________________________________________________//
        // Parameter(s):        int ProcessID - The Process ID of the program you want to open.         //
        //                                                                                              //
        //                      Enum DesiredAccess - The desired access.                                //
        //                                                -All                                          //
        //                                                -Terminate                                    //
        //                                                -CreateThread                                 //
        //                                                -VMOperation                                  //
        //                                                -VMRead                                       //
        //                                                -VMWrite                                      //
        //                                                -DupHandle                                    //
        //                                                -SetInformation                               //
        //                                                -QueryInformation                             //
        //                                                -Synchronize                                  //
        //                                                                                              //
        //                      Bool InheritHandle - All processes created by this process will inherit //
        //                                           the access handle.                                 //
        //                                                -true                                         //
        //                                                -false                                        //
        //______________________________________________________________________________________________//
        // Return Value(s):     On Success - Returns the process handle                                 //
        //                        On Failure - Returns 0                                                  //
        //==============================================================================================//
        
[DllImport("kernel32.dll")]
        static 
extern IntPtr OpenProcess(UInt32 dwDesiredAccessbool bInheritHandleint dwProcessId);


        static public 
IntPtr MemoryOpen(int ProcessID)
        {
            
System.Diagnostics.Process MyProc System.Diagnostics.Process.GetProcessById(ProcessID);
            if (
MyProc.HandleCount 0)
            {
                
IntPtr hProcess OpenProcess(0x1F0FFFtrueProcessID); ;
                return 
hProcess;
            }
            else
            {
                return (
IntPtr)0x00000000;
            }

        }

        static public 
IntPtr MemoryOpen(int ProcessIDProcessAccessFlags DesiredAccess)
        {
            
System.Diagnostics.Process MyProc System.Diagnostics.Process.GetProcessById(ProcessID);
            if (
MyProc.HandleCount 0)
            {
                
IntPtr hProcess OpenProcess((uint)DesiredAccesstrueProcessID); ;
                return 
hProcess;
            }
            else
            {
                return (
IntPtr)0x00000000;
            }

        }

        static public 
IntPtr MemoryOpen(int ProcessIDProcessAccessFlags DesiredAccessbool InheritHandle)
        {
            
System.Diagnostics.Process MyProc System.Diagnostics.Process.GetProcessById(ProcessID);
            if (
MyProc.HandleCount 0)
            {
                
IntPtr hProcess OpenProcess((uint)DesiredAccessInheritHandleProcessID); ;
                return 
hProcess;
            }
            else
            {
                return (
IntPtr)0x00000000;
            }

        }

        [
Flags]
        public 
enum ProcessAccessFlags uint
        
{
            
All 0x001F0FFF,
            
Terminate 0x00000001,
            
CreateThread 0x00000002,
            
VMOperation 0x00000008,
            
VMRead 0x00000010,
            
VMWrite 0x00000020,
            
DupHandle 0x00000040,
            
SetInformation 0x00000200,
            
QueryInformation 0x00000400,
            
Synchronize 0x00100000
        
}

        
//==============================================================================================//
        // Function:           MemoryRead(IntPtr OpenedHandle, IntPtr BaseAddress, UInt32 Size,         //
        //                                 ref UInt32 Bytes)                                            //
        //______________________________________________________________________________________________//
        // Description:        Reads the specified amount of bytes from a memory address.               //
        //______________________________________________________________________________________________//
        // Parameter(s):       IntPtr OpenedHandle - The handle of the opened process returned by       //
        //                                           MemoryOpen.                                        //
        //                                                                                              //
        //                     IntPtr BaseAddress - A pointer to the base address in the specified      //
        //                                          process from which to read. Before any data transfer// 
        //                                          occurs, the system verifies that all data in the    //
        //                                          base address and memory of the specified size is    //
        //                                          accessible for read access, and if it is not        //
        //                                          accessible the function fails.                      //
        //                                                                                              //
        //                     UInt32 Size - The number of bytes to be read from the specified process. //
        //                                                                                              //
        //                     ref UInt32 Bytes - A pointer to a variable that receives the number of   //
        //                                        bytes transferred into the specified buffer.          //
        //______________________________________________________________________________________________//
        // Return Value(s):     On Success - Returns buffer (containing read bytes)                     //
        //                      On Failure - The return value is 0 (zero)                               //
        //                                     -The function fails if the requested read operation      //
        //                                      crosses into an area of the process that is inaccessible//
        //==============================================================================================//

        
[DllImport("kernel32.dll")]
        static 
extern Int32 ReadProcessMemory(IntPtr OpenedHandleIntPtr lpBaseAddressbyte[] lpBuffer,
                                                    
UInt32 sizeout IntPtr lpNumberOfBytesRead);

        static public 
byte[] MemoryRead(IntPtr OpenedHandleIntPtr BaseAddressUInt32 Sizeref IntPtr Bytes)
        {
            
byte[] buffer = new byte[Size];
            
ReadProcessMemory(OpenedHandleBaseAddressbufferSizeout Bytes);
            return 
buffer;

        }

        
//==============================================================================================//
        // Function:            MemoryClose(IntPtr OpenedHandle)                                        //
        //______________________________________________________________________________________________//
        //Description:          Close an opened handle to a process, returned by MemoryOpen.            //
        //______________________________________________________________________________________________//
        // Parameter(s):        IntPtr OpenedHandle - the handle to a opened process, returned          //
        //                                            by MemoryOpen.                                    //
        //______________________________________________________________________________________________//
        // Return Value(s):     On Success - The return value is nonzero.                               //
        //                      On Failure - The return value is zero                                   //
        //==============================================================================================//
        
[DllImport("kernel32.dll")]
        static 
extern Int32 CloseHandle(IntPtr hObject);

        static 
int MemoryClose(IntPtr OpenedHandle)
        {
            
int rtn;
            
rtn CloseHandle(OpenedHandle);
            return 
rtn;
        } 
08/15/2008 20:55 tanelipe#2
Heya, this is how I have done it in my own wrapper ->

Code:
[DllImport("kernel32.dll")]
        private static unsafe extern Boolean WriteProcessMemory(IntPtr hProcess, uint lpBaseAddress,
                                                                byte[] lpBuffer, int nSize, void* lpNumberOfBytesWritten);
Ofcourse, instead the last void* you can use IntPtr if you want, so you don't have to run it as a unsafe code.

Code:
 public void Write(uint mAddress, byte[] Buffer)
        {
            if (!ProcessOpen)
                return;
            IntPtr Useless = IntPtr.Zero;
            WriteProcessMemory(ProcessID, mAddress, Buffer, Buffer.Length, Useless);
        }
The ProcessOpen just determines wether the specified memory class has opened by it.

Example of this would be
Code:
byte[] Buffer = BitConverter.GetBytes(12345);
Memory.Write(Address, Buffer);
I do not know any of the address for pinball; Can't help you with that :p
08/16/2008 00:01 Hiyoal#3
Nice example Tane.
Nothing I can add to that :p

Hiyoal
08/16/2008 09:58 tanelipe#4
Miv, did that code example help you any? I can show more of the wrapper I've made incase it didn't.
08/16/2008 14:41 Miv#5
Quote:
BitConverter.GetBytes(12345);
that line of code really helped me, thanks :)
08/16/2008 19:39 InfamousNoone#6
Quote:
Originally Posted by Miv View Post
that line of code really helped me, thanks :)
Code:
[DllImport("kernel32.dll")]
        private static unsafe extern Boolean WriteProcessMemory(IntPtr hProcess, uint lpBaseAddress,
                                                                void* lpBuffer, int nSize, void* lpNumberOfBytesWritten);
Code:
ushort value = 12345;
WriteProcessMemory(hProc, addr, &value, sizeof(ushort), null);
(Making a pointer will work faster @ runtime rather than relying on C#'s p-invoke system to change the byte[] to a void*)
08/16/2008 22:01 tanelipe#7
Making something related to pinball, I don't think the speed is the first thing they would think about.