Last year or two years ago I had looked into Process Memory Reading in order to inject values into games that where downloaded and playing to make a bot (ie; Runescape, WoW, LoL, 12Sky, etc etc) and I never fully grasped how to predict where or what the new value address would be when the program starts up as it's nearly different every time and a pain in the ass to find. However this class does all that its supposed to.

PHP Code:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace 
ProcessMemoryReaderLib
{
    
/// <summary>
    /// ProcessMemoryReader is a class that enables direct reading a process memory
    /// </summary>
    
class ProcessMemoryReaderApi
    
{
        
// constants information can be found in <winnt.h>
        
[Flags]
        public 
enum ProcessAccessType
        
{
            
PROCESS_TERMINATE            = (0x0001),
            
PROCESS_CREATE_THREAD        = (0x0002), 
            
PROCESS_SET_SESSIONID        = (0x0004), 
            
PROCESS_VM_OPERATION        = (0x0008), 
            
PROCESS_VM_READ                = (0x0010), 
            
PROCESS_VM_WRITE            = (0x0020), 
            
PROCESS_DUP_HANDLE            = (0x0040), 
            
PROCESS_CREATE_PROCESS        = (0x0080), 
            
PROCESS_SET_QUOTA            = (0x0100), 
            
PROCESS_SET_INFORMATION        = (0x0200), 
            
PROCESS_QUERY_INFORMATION    = (0x0400
        }
        
        
// function declarations are found in the MSDN and in <winbase.h> 
        
        //        HANDLE OpenProcess(
        //            DWORD dwDesiredAccess,  // access flag
        //            BOOL bInheritHandle,    // handle inheritance option
        //            DWORD dwProcessId       // process identifier
        //            );
        
[DllImport("kernel32.dll")]
        public static 
extern IntPtr OpenProcess(UInt32 dwDesiredAccessInt32 bInheritHandleUInt32 dwProcessId);

        
//        BOOL CloseHandle(
        //            HANDLE hObject   // handle to object
        //            );
        
[DllImport("kernel32.dll")]
        public static 
extern Int32 CloseHandle(IntPtr hObject);

        
//        BOOL ReadProcessMemory(
        //            HANDLE hProcess,              // handle to the process
        //            LPCVOID lpBaseAddress,        // base of memory area
        //            LPVOID lpBuffer,              // data buffer
        //            SIZE_T nSize,                 // number of bytes to read
        //            SIZE_T * lpNumberOfBytesRead  // number of bytes read
        //            );
        
[DllImport("kernel32.dll")]
        public static 
extern Int32 ReadProcessMemory(IntPtr hProcessIntPtr lpBaseAddress,[InOutbyte[] bufferUInt32 sizeout IntPtr lpNumberOfBytesRead);
    
        
//        BOOL WriteProcessMemory(
        //            HANDLE hProcess,                // handle to process
        //            LPVOID lpBaseAddress,           // base of memory area
        //            LPCVOID lpBuffer,               // data buffer
        //            SIZE_T nSize,                   // count of bytes to write
        //            SIZE_T * lpNumberOfBytesWritten // count of bytes written
        //            );
        
[DllImport("kernel32.dll")]
        public static 
extern Int32 WriteProcessMemory(IntPtr hProcessIntPtr lpBaseAddress,[InOutbyte[] bufferUInt32 sizeout IntPtr lpNumberOfBytesWritten);
    
        
    }

    public class 
ProcessMemoryReader
    
{

        public 
ProcessMemoryReader()
        {
        }

        
/// <summary>    
        /// Process from which to read        
        /// </summary>
        
public Process ReadProcess
        
{
            
get
            
{
                return 
m_ReadProcess;
            }
            
set
            
{
                
m_ReadProcess value;
            }
        }

        private 
Process m_ReadProcess null;

        private 
IntPtr m_hProcess IntPtr.Zero;

        public 
void OpenProcess()
        {
//            m_hProcess = ProcessMemoryReaderApi.OpenProcess(ProcessMemoryReaderApi.PROCESS_VM_READ, 1, (uint)m_ReadProcess.Id);
            
ProcessMemoryReaderApi.ProcessAccessType access;
            
access ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_READ 
                
ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_WRITE 
                
ProcessMemoryReaderApi.ProcessAccessType.PROCESS_VM_OPERATION;
                
m_hProcess ProcessMemoryReaderApi.OpenProcess((uint)access1, (uint)m_ReadProcess.Id);
        }

        public 
void CloseHandle()
        {
            
int iRetValue;
            
iRetValue ProcessMemoryReaderApi.CloseHandle(m_hProcess);
            if (
iRetValue == 0)
                throw new 
Exception("CloseHandle failed");
        }

        public 
byte[] ReadProcessMemory(IntPtr MemoryAddressuint bytesToReadout int bytesRead)
        {
            
byte[] buffer = new byte[bytesToRead];
            
            
IntPtr ptrBytesRead;
            
ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess,MemoryAddress,buffer ,bytesToRead,out ptrBytesRead);
            
            
bytesRead ptrBytesRead.ToInt32();

            return 
buffer;
        }

        public 
void WriteProcessMemory(IntPtr MemoryAddressbyte[] bytesToWrite ,out int bytesWritten)
        {
            
IntPtr ptrBytesWritten;
            
ProcessMemoryReaderApi.WriteProcessMemory(m_hProcess,MemoryAddress,bytesToWrite,(uint)bytesToWrite.Length,out ptrBytesWritten);
            
            
bytesWritten ptrBytesWritten.ToInt32();
        }

        


    }

Disclaimer: I had followed a tutorial in writing this class so not all or any of the code is mine.