C# - Reading Memory from a process

Ask questions about cheating in any games you would like. Does not need to pertain to MicroMacro.
Post Reply
Message
Author
zer0
Posts: 213
Joined: Sat Feb 16, 2008 11:55 pm

C# - Reading Memory from a process

#1 Post by zer0 » Sun Oct 19, 2008 9:38 am

Hey I'm using C# to try and read process memory. For some reason though, no bytes are read because in ReadProcessMemory(), ptrBytesRead is always 0. I can't figure it out, I'm hoping someone here might be able to point out the issue, since a few of you are much more familiar with hooking processes.

ProcessMemoryReader.cs

Code: Select all

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 dwDesiredAccess, Int32 bInheritHandle, UInt32 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 hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out 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 hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out 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)access, 1, (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 MemoryAddress, uint bytesToRead, out int bytesRead)
        {
            byte[] buffer = new byte[bytesToRead];

            IntPtr ptrBytesRead;
            ProcessMemoryReaderApi.ReadProcessMemory(m_hProcess, MemoryAddress, buffer, bytesToRead, out ptrBytesRead);

            bytesRead = ptrBytesRead.ToInt32();
            //Debug.Assert(bytesRead == bytesToRead);

            return buffer;
        }

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

            bytesWritten = ptrBytesWritten.ToInt32();
        }
    }
}
Program.cs

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using ProcessMemoryReaderLib;

namespace ProcessMemoryEx
{
    class Program
    {
        static void Main(string[] args)
        {
            string processName = "";
            ProcessMemoryReaderLib.ProcessMemoryReader pReader
                               = new ProcessMemoryReaderLib.ProcessMemoryReader();

            System.Diagnostics.Process[] myProcesses
                           = System.Diagnostics.Process.GetProcessesByName(processName);

            if (myProcesses.Length == 0)
            {
                Console.WriteLine("No process found!");
                return;
            }
            pReader.ReadProcess = myProcesses[0];

            // open process in read memory mode

            pReader.OpenProcess();

            int bytesReaded;
            byte[] memory;
            // Just the start memory address to test.
            memory = pReader.ReadProcessMemory((IntPtr)0x0, 4, out bytesReaded);
            int intExample = memory[0];
            Console.WriteLine("intExample: " + intExample.ToString());

            // When trying to call this it throws an exception.
            //pReader.CloseHandle();
        }
    }
}
here is the thread that I'm getting help with, someone else may understand what they r talking about. ^^
http://social.msdn.microsoft.com/Forums ... 6b85b4dfc1

User avatar
Administrator
Site Admin
Posts: 5306
Joined: Sat Jan 05, 2008 4:21 pm

Re: C# - Reading Memory from a process

#2 Post by Administrator » Mon Oct 20, 2008 3:21 am

Yeah, looks like UAC to me. You'd have to compile a manifest into your program. First step is getting a manifest file and naming it exactly like your main exe, except with a .manifest extension. Just copy micromacro.exe.manifest, and rename it to yourprogram.exe.manifest. If you place the file into the same directory as your executable, it might work just like that. Otherwise, you'll need to also compile it in as a resource file into your program.

In order to do that, you'll need to make a file, say, UacManifest.rc, and it should contain something like this:

Code: Select all

#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST "res/micromacro.exe.manifest"
Where "res/micromacro.exe.manifest" needs to be changed to your manifest file's path and name. Any other specifics are compiler and language specific, so you might have to Google search a bit to find more detailed instructions.

User avatar
3cmSailorfuku
Posts: 354
Joined: Mon Jan 21, 2008 6:25 pm

Re: C# - Reading Memory from a process

#3 Post by 3cmSailorfuku » Tue Oct 21, 2008 9:52 am

elverion wrote:Yeah, looks like UAC to me. You'd have to compile a manifest into your program. First step is getting a manifest file and naming it exactly like your main exe, except with a .manifest extension. Just copy micromacro.exe.manifest, and rename it to yourprogram.exe.manifest. If you place the file into the same directory as your executable, it might work just like that. Otherwise, you'll need to also compile it in as a resource file into your program.

In order to do that, you'll need to make a file, say, UacManifest.rc, and it should contain something like this:

Code: Select all

#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST "res/micromacro.exe.manifest"
Where "res/micromacro.exe.manifest" needs to be changed to your manifest file's path and name. Any other specifics are compiler and language specific, so you might have to Google search a bit to find more detailed instructions.
C# does create the required manifest file already by default, or does it include it into the project.
Also, it does work and I get the return value correctly with no modification,
what I noticed though is that you cannot append .exe to the process name, so *.bin might not work or any other.

User avatar
Administrator
Site Admin
Posts: 5306
Joined: Sat Jan 05, 2008 4:21 pm

Re: C# - Reading Memory from a process

#4 Post by Administrator » Tue Oct 21, 2008 12:38 pm

I'm not sure if you even can read from 0x0 (at least with certain "security" settings in Vista). Your best bet is to create a small sample application that declares an integer, and has a while loop with a rest in it, and nothing else. Search for the address to that integer with a memory editor, and try using that instead.

User avatar
3cmSailorfuku
Posts: 354
Joined: Mon Jan 21, 2008 6:25 pm

Re: C# - Reading Memory from a process

#5 Post by 3cmSailorfuku » Tue Oct 21, 2008 12:56 pm

elverion wrote:I'm not sure if you even can read from 0x0 (at least with certain "security" settings in Vista). Your best bet is to create a small sample application that declares an integer, and has a while loop with a rest in it, and nothing else. Search for the address to that integer with a memory editor, and try using that instead.
Oh he does wan't to read 0x0? Because I thought it was just some placeholder or why else would anyone want to access 0x0?. Anyway, disabling UAC fixed his problem.

User avatar
Administrator
Site Admin
Posts: 5306
Joined: Sat Jan 05, 2008 4:21 pm

Re: C# - Reading Memory from a process

#6 Post by Administrator » Tue Oct 21, 2008 4:49 pm

Yeah, it was just a placeholder. I thought as a subset of UAC, Vista would disallow reading from certain memory ranges, with 0x0 being within that range. I haven't heard any specific information about it, so it was just a guess.

You're right though, looks like he got it to work when disabling UAC. He must have edited that in after I read his post on MSDN.

zer0
Posts: 213
Joined: Sat Feb 16, 2008 11:55 pm

Re: C# - Reading Memory from a process

#7 Post by zer0 » Tue Nov 18, 2008 4:39 pm

Apologies, when using external references, it's usually good manners, to let others know that with everyone's help I managed to solve the issue. :)

Post Reply

Who is online

Users browsing this forum: No registered users and 5 guests