Обращение напрямую к адресу оперативной памяти - C#

Узнай цену своей работы

Формулировка задачи:

Подскажите, как в си шарп обращаться к определённым адресам оперативной памяти и читать оттуда значения??? Нужно для оффсетов... Например, есть игра, я с помощью артмани ищу адрес определённого значения, забиваю его в программу и считываю его через каждые 10 секунд... Спасибо!!!

Решение задачи: «Обращение напрямую к адресу оперативной памяти»

textual
Листинг программы
using System;
using System.Linq;
using System.Security;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.ConstrainedExecution;
using System.Timers;
 
namespace ReadMemory
{
    class Program
    {
        [DllImport("kernel32.dll")]
        public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess,bool bInheritHandle,int processId);
 
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool ReadProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,[Out] byte[] lpBuffer,int dwSize,out IntPtr lpNumberOfBytesRead);
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
 
        static extern bool CloseHandle(IntPtr hObject);
        [Flags]
        public enum ProcessAccessFlags : uint
        {
            All = 0x001F0FFF,
            Terminate = 0x00000001,
            CreateThread = 0x00000002,
            VirtualMemoryOperation = 0x00000008,
            VirtualMemoryRead = 0x00000010,
            VirtualMemoryWrite = 0x00000020,
            DuplicateHandle = 0x00000040,
            CreateProcess = 0x000000080,
            SetQuota = 0x00000100,
            SetInformation = 0x00000200,
            QueryInformation = 0x00000400,
            QueryLimitedInformation = 0x00001000,
            Synchronize = 0x00100000
        }
        public static int pID;
        public static string pName = "ProcessName";//Имя процесса без .exe
        static void Main(string[] args)
        {
            var pList = Process.GetProcesses();
            if (pList.Count() != 0)
            {
                foreach(var _getCurrentProcess in pList)
                {
                    if(_getCurrentProcess.ProcessName == pName)
                    {
                        pID = _getCurrentProcess.Id;
                        break;
                    }
                }
            }
            var pHandle = OpenProcess(ProcessAccessFlags.All, false, pID);
            Console.WriteLine(">ProcessName:\t"+pName+"\n>ProcessID:\t"+pID+"\n>ProcessHandle:\t"+pHandle);
            Timer tmr = new Timer();
            tmr.Interval = 10000;
            tmr.Enabled = true;
            tmr.Elapsed += Tmr_Elapsed;
            CloseHandle(pHandle);
            while (true)
            {
                if(Console.ReadKey().Key == ConsoleKey.Escape)
                {
                    Environment.Exit(0);
                }
            }
        }
 
        private static void Tmr_Elapsed(object sender, ElapsedEventArgs e)
        {
            int[] offsets = { 0x50, 0x90, 0x70 };//сами смещения 
            Console.WriteLine(ReadPointerMemory(0x12345678, offsets));//Базовый адрес,тот который зеленный в cheat engine
        }
 
        public static byte[] ReadMemory(int baseAddress, int size)
        {
            IntPtr cacheRM;
            byte[] buffer = new byte[size];
            var handle = OpenProcess(ProcessAccessFlags.All, false, pID);
            ReadProcessMemory(handle, (IntPtr)baseAddress, buffer, size, out cacheRM);
            CloseHandle(handle);
            return buffer;
 
        }
        public static int ReadPointerMemory(int baseAddress, int[] offsets)
        {
            baseAddress = BitConverter.ToInt32(ReadMemory(baseAddress, 4), 0);
            for (int i = 0; i < offsets.Length; i++)
            {
                baseAddress += offsets[i];
                if (i == offsets.Length - 1)
                {
                    return baseAddress;
                }
                baseAddress = BitConverter.ToInt32(ReadMemory(baseAddress, 4), 0);
            }
            return baseAddress;
        }
    }
}

Оцени полезность:

13   голосов , оценка 4.154 из 5
Похожие ответы