-
Автор темы
- #1
Учусь писать простые читы на AssaultCube и у меня возникла проблема. Прошу вас, обьясните мне как правильно работать с указателями с помощью системных функций RPW и WPR. вот мой код
C#:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace ad
{
class Programm
{
// Функция для получения базового адреса модуля
static IntPtr GetModuleBaseAddress(Process process, string moduleName)
{
foreach (ProcessModule module in process.Modules)
{
if (module.ModuleName == moduleName)
{
return module.BaseAddress;
}
}
return IntPtr.Zero;
}
// Импорт функций из kernel32.dll
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
IntPtr lpBuffer,
int dwSize,
out IntPtr lpNumberOfBytesWritten);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
IntPtr lpBuffer,
int dwSize,
out IntPtr lpNumberOfBytesRead);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(
uint processAccess,
bool bInheritHandle,
uint processId);
const uint PROCESS_ALL_ACCESS = 0x001F0FFF;
static void Main()
{
// Находим процесс AssaultCube
Process[] processes = Process.GetProcessesByName("ac_client");
if (processes.Length == 0)
{
Console.WriteLine("Процесс ac_client.exe не найден");
return;
}
Process process = processes[0]; // Берем первый процесс из списка
uint processID = (uint)process.Id; // Получаем processID
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Введите значение");
int UserValue = Convert.ToInt32(Console.ReadLine());
byte[] buffers = BitConverter.GetBytes(UserValue);
IntPtr bytesRead;
byte[] buffer = new byte[4];
Console.WriteLine("Окно найдено!");
// Открываем процесс
IntPtr processHandle = OpenProcess(PROCESS_ALL_ACCESS, false, processID);
if (processHandle == IntPtr.Zero)
{
Console.WriteLine("Не удалось открыть процесс");
return;
}
// Получаем базовый адрес модуля ac_client.exe
IntPtr baseAddress = GetModuleBaseAddress(process, "ac_client.exe");
if (baseAddress == IntPtr.Zero)
{
Console.WriteLine("Не удалось найти базовый адрес модуля ac_client.exe");
return;
}
// Вычисляем итоговый адрес
IntPtr finalAddress = baseAddress + 0x00183828; // Базовый адрес + смещение
finalAddress = (IntPtr)(finalAddress.ToInt32() + 0x8 + 0x190 + 0x3D4); // Добавляем оффсеты
Console.WriteLine($"Final Address: 0x{finalAddress.ToInt32():X}");
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
IntPtr bytesWritten;
// Чтение из памяти по итоговому адресу
bool readSuccess = ReadProcessMemory(processHandle, finalAddress, handle.AddrOfPinnedObject(), buffer.Length, out bytesRead);
if (!readSuccess)
{
Console.WriteLine("Ошибка чтения из памяти");
return;
}
int f = BitConverter.ToInt32(buffer, 0);
Console.WriteLine($"Значение в памяти: {f}");
// Запись нового значения в память
bool writeSuccess = WriteProcessMemory(processHandle, finalAddress, Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), buffers.Length, out bytesWritten);
if (!writeSuccess)
{
Console.WriteLine("Ошибка записи в память");
return;
}
Console.WriteLine("Значение успешно записано!");
}
finally
{
if (handle.IsAllocated)
{
handle.Free();
}
}
}
}
}