Обращение напрямую к адресу оперативной памяти - 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;
}
}
}