locked
Read memory with module, base address and offsets RRS feed

  • Question

  • Hello,

    I am trying to read a memory from an application. Using some tools I managed getting a static address.
    Now my issue is reading programmatically that memory.
    This is my code:

    [DllImport("kernel32.dll")] static extern IntPtr OpenProcess(UInt32 dwDesiredAccess, Boolean bInheritHandle, UInt32 dwProcessId); [DllImport("kernel32.dll")] static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, UIntPtr nSize, uint lpNumberOfBytesWritten); static IntPtr Handle; static void Main(string[] args) { Process[] Processes = Process.GetProcessesByName("process"); Process nProcess = Processes[0]; Handle = OpenProcess(0x10, false, (uint)nProcess.Id); IntPtr pointer = IntPtr.Add(nProcess.Modules[125].BaseAddress, 0x020C5150); int curhp = ReadOffset(pointer, 0x4D8); int curhp2 = ReadOffset((IntPtr)curhp, 0x0); int curhp3 = ReadOffset((IntPtr)curhp2, 0x1c0); Console.WriteLine(curhp3.ToString()); Console.ReadKey(); } public static int ReadOffset(IntPtr pointer, uint offset) { byte[] bytes = new byte[24]; uint adress = (uint)ReadPointer(pointer) + offset; ReadProcessMemory(Handle, (IntPtr)adress, bytes, (UIntPtr)sizeof(int), 0); return BitConverter.ToInt32(bytes, 0); } public static int ReadPointer(IntPtr pointer) { byte[] bytes = new byte[24]; ReadProcessMemory(Handle, pointer, bytes, (UIntPtr)sizeof(int), 0); return BitConverter.ToInt32(bytes, 0); }

    How am I supposed to read that memory?

    The target address is: "client.dll"+0x020C5150, offset1 = 0x4D8, offset2 = 0x0, offset3 = 0x1C0

    What am I doing wrong here? How am I supposed to read that memory?

    Thank you in advance


    Thursday, February 18, 2016 10:28 PM

All replies

  • Hi ileandros,

    Firstly, in order to read the value from memory address, we need to import 2 functions into C#: OpenProcess() and ReadProcessMemory() from kernel32.dll.

    I have tested the code that you provided, but I do not reproduce your issue because our environment is different from yours (such as the address value “0x020C5150”, the dll file “client.dll”, offset1). You may press F10 or F11 to debug your code step by step in visual studio, and then find where does it occurs errors in your code. Could you provide the code to reproduce your issue for me?

    Secondly, for your scenario, I have written and tested the following code, it worked well. You may try to use the following code about how to read the value from that memory address.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    
    namespace ConsoleApplication4
    {
        class Program
        {
            const int PROCESS_WM_READ = 0x0010;
    
            [DllImport("kernel32.dll")]
            public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
    
            [DllImport("kernel32.dll")]
            public static extern bool ReadProcessMemory(int hProcess,
              int lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead);
    
            public static void Main()
            {
                Process process = Process.GetProcessesByName("notepad")[0];
                IntPtr processHandle = OpenProcess(PROCESS_WM_READ, false, process.Id);
    
                int bytesRead = 0;
                byte[] buffer = new byte[24]; //'Hello World!' takes 12*2 bytes because of Unicode 
    
    
                // 0x0046A3B8 is the address where I found the string, replace it with what you found
                ReadProcessMemory((int)processHandle, 0x0046A3B8, buffer, buffer.Length, ref bytesRead);
    
                Console.WriteLine(Encoding.Unicode.GetString(buffer) +
                   " (" + bytesRead.ToString() + "bytes)");
                Console.ReadLine();
            }
        }
    }

    Best Regards, <o:p></o:p>

    Albert Zhang


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, February 19, 2016 9:20 AM
  • Hello,

    That's an example from notepad which I already found before posting. However it doesn't show how to find an address with offsets and modules.

    Friday, February 19, 2016 12:11 PM
  • .NET is not the right environment to do direct memory access. It avoids using pointers at all (the primary tool for it) except in unsafe mode. Moreover you run the risk of running into a Access Violation Exception. Uncontrolled memory access has been a huge cause of securty flaws. Wich is why it is no longer allowed by most OS or the .NET Runtime, even in unmanaged code.

    It is still possible to do direct memory access (more so then in Java), but the ideal langauge would be something like Native C++ (not C++. NET).

    If this is about two way interprocess communication you should propably read up on proper ways to do that, inlcuding shared memory (via memory mapped files) and named pipes:

    https://msdn.microsoft.com/en-us/library/dd997372.aspx

    https://msdn.microsoft.com/en-us/library/bb546085.aspx

    Or stuff like just bouncing network traffic off the loopback adress to anotehr port on the same computer.

    Friday, February 19, 2016 1:49 PM
  • .NET is not the right environment to do direct memory access. It avoids using pointers at all (the primary tool for it) except in unsafe mode. Moreover you run the risk of running into a Access Violation Exception. Uncontrolled memory access has been a huge cause of securty flaws. Wich is why it is no longer allowed by most OS or the .NET Runtime, even in unmanaged code.

    It is still possible to do direct memory access (more so then in Java), but the ideal langauge would be something like Native C++ (not C++. NET).

    If this is about two way interprocess communication you should propably read up on proper ways to do that, inlcuding shared memory (via memory mapped files) and named pipes:

    https://msdn.microsoft.com/en-us/library/dd997372.aspx

    https://msdn.microsoft.com/en-us/library/bb546085.aspx

    Or stuff like just bouncing network traffic off the loopback adress to anotehr port on the same computer.

    Friday, February 19, 2016 1:49 PM
  • That memory address looks a lot like a call stack.  What exactly are you intending to do once you read the memory?  If you're trying to write a debugger or equivalent then there are better tools for that.

    Michael Taylor
    http://blogs.msmvps.com/p3net

    Friday, February 19, 2016 3:14 PM
  • That memory address looks a lot like a call stack.  What exactly are you intending to do once you read the memory?  If you're trying to write a debugger or equivalent then there are better tools for that.

    Michael Taylor
    http://blogs.msmvps.com/p3net


    Just display it. I am building a graphical display of the app with some details of the actual app in it.
    So basically I am just trying to display the memory read which is equivalent to a integer. The read memory should give me 617. That's what cheat engine gives me after adding the address and offsets in it.
    Friday, February 19, 2016 6:15 PM
  • .NET is not the right environment to do direct memory access. It avoids using pointers at all (the primary tool for it) except in unsafe mode. Moreover you run the risk of running into a Access Violation Exception. Uncontrolled memory access has been a huge cause of securty flaws. Wich is why it is no longer allowed by most OS or the .NET Runtime, even in unmanaged code.

    It is still possible to do direct memory access (more so then in Java), but the ideal langauge would be something like Native C++ (not C++. NET).

    If this is about two way interprocess communication you should propably read up on proper ways to do that, inlcuding shared memory (via memory mapped files) and named pipes:

    https://msdn.microsoft.com/en-us/library/dd997372.aspx

    https://msdn.microsoft.com/en-us/library/bb546085.aspx

    Or stuff like just bouncing network traffic off the loopback adress to anotehr port on the same computer.


    I have thought about moving to C++ but it is completely different from C#. And I don't want to start over again.
    Friday, February 19, 2016 6:15 PM
  • Hi ileandros,

    >>However it doesn't show how to find an address with offsets and modules.

    For this, you could have a look at the following similar thread which provides a sample demo to implement this need by using pointer and MemorySharp.

    http://stackoverflow.com/questions/18863518/memorysharp-setting-offset-to-an-address-not-working

    Best Regards,

    Albert Zhang


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, February 23, 2016 9:57 AM
  • In addition to the others, I know only few apps that needs memory addresses. Most are blocked by firewalls or virusscaners. 

    Strange enough some of your already done question point to that. Maybe can you give us the reason you need this. 

    Windows a Multi Tasking OS based on partitions, those partitions swap through the memory. 



    Success
    Cor

    Tuesday, February 23, 2016 10:08 AM