Перейти к содержанию

Рекомендуемые сообщения

Приветствую всех. С урока писал трейнер на игру.Все получилось. Но вот проблема:

У меня имеется  AMMO.CS отвечающий за заморозку патрон. Вот код: 

 

- - - - - --

как вы уже поняли, при перезапуске игры это уже не сработает, приходится по новой искать Адрес ...

Как мне Записать Указатели в этот код? И прийдется ли мне полностью изменять его?

NullAlex: теги для кого сделаны? Устное предупреждение.

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Diagnostics;using System.Runtime.InteropServices; namespace Tranier2{    class ammo    {        //ReadProcessMemory        [DllImport("kernel32.dll", SetLastError = true)]        static extern bool ReadProcessMemory(          IntPtr hProcess,          IntPtr lpBaseAddress,          [Out] byte[] lpBuffer,          int dwSize,          out int lpNumberOfBytesRead         );        //OpenProcess // Flag = All = 0x001F0FFF        [DllImport("kernel32.dll")]        public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);         // CloseHandle        [DllImport("kernel32.dll", SetLastError = true)]        [return: MarshalAs(UnmanagedType.Bool)]        static extern bool CloseHandle(IntPtr hObject);        [StructLayout(LayoutKind.Sequential)]        public struct MEMORY_BASIC_INFORMATION        {            public IntPtr BaseAddress;            public IntPtr AllocationBase;            public uint AllocationProtect;            public IntPtr RegionSize;            public uint State;            public uint Protect;            public uint Type;        }        // VirtualQueryEx        [DllImport("kernel32.dll")]        static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);        //WriteProcessMemory        [DllImport("kernel32.dll", SetLastError = true)]        static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);         [DllImport("kernel32.dll", SetLastError = true)]        static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, uint nSize, UIntPtr lpNumberOfBytesWritten);        public int ProcessID;        private IntPtr handl;        public void GetProcess()    {        foreach (Process id in Process.GetProcessesByName("[b]xxx[/b]"))        {            ProcessID = id.Id;        }            WriteBytes();        }                    public void WriteBytes()            {                var adress =  0x0283A480;                               var bytessize = 4;                byte[] bytes = {0x16, 0x00, 0x00, 0x00};                var w = new UIntPtr();                var handl = OpenProcess(0x001F0FFF, false , ProcessID);                                WriteProcessMemory(handl, (IntPtr)adress, bytes, (uint)bytessize, out w);                CloseHandle(handl);            }                           }   }
Ссылка на комментарий
Поделиться на другие сайты

Привет!

 

У тебя для записи в память используется WinAPI-функция WriteProcessMemory, которая принимает в качестве аргументов адрес, размер и значение для записи. Соответственно, переменную adress, bytessize и массив байт bytes. Адрес при этом задан статический. Указатели по своей сути - это статический адрес + одно или несколько смещений от него, которые тоже хранят адрес, а самый последний - нужное значение. Для того, чтобы получить адрес, на который указывает некоторый указатель, нужно знать статический адрес этого указателя и смещения, а потом просто прочитать его, используя арифметику. Для чтения понадобится функция ReadProcessMemory, читать нужно будет, скорее всего, 4 байта. Тут я просто думаю, что игра 32-битная, а в 32-битном адресном пространстве адреса как раз по 4 байта каждый. Допустим, есть у тебя какой-то такой указатель:

 

[[[0x1234567] + 0x10] + 0x20]

 

Что тебе нужно сделать? А вот так вот:

 

0. Прочитать значение по адресу 0x1234567 (статический адрес).

1. Прибавить к полученному 0x10 (первое смещение).

2. Прочитать значение по полученному адресу.

3. Прибавить к полученному 0x20 (второе смещение).

4. Прочитать значение по полученному адресу.

 

После 4-го шага в данном примере в переменной для чтения как раз и будет адрес, который дальше можно будет использовать для записи в память.

 

PS: У меня в блоге даже нашлась [запись] на эту тему.

  • Плюс 2
Ссылка на комментарий
Поделиться на другие сайты

Привет!

offtopic.gif keng, как всегда лаконично и доходчиво. Почитал пару статей в блоге за 2015 год - в том же духе, т.е., как всегда, здорово.

Ты случайно не из учительской семьи - у тебя учительский дар?

(Я разделяю преподавателей и учителей: преподаватели - преподают предмет, учителя - учат ему; преподавателей я уважаю, учителей - люблю.)

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

offtopic.gif
Garik66, семья химиков и инженеров, ранее - всяких творческих личностей, музыкантов\художников. Дед преподавал в военноморском, бабушка - химию в одном из институтов.
  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

Привет!

 

У тебя для записи в память используется WinAPI-функция WriteProcessMemory, которая принимает в качестве аргументов адрес, размер и значение для записи. Соответственно, переменную adress, bytessize и массив байт bytes. Адрес при этом задан статический. Указатели по своей сути - это статический адрес + одно или несколько смещений от него, которые тоже хранят адрес, а самый последний - нужное значение. Для того, чтобы получить адрес, на который указывает некоторый указатель, нужно знать статический адрес этого указателя и смещения, а потом просто прочитать его, используя арифметику. Для чтения понадобится функция ReadProcessMemory, читать нужно будет, скорее всего, 4 байта. Тут я просто думаю, что игра 32-битная, а в 32-битном адресном пространстве адреса как раз по 4 байта каждый. Допустим, есть у тебя какой-то такой указатель:

 

[[[0x1234567] + 0x10] + 0x20]

 

Что тебе нужно сделать? А вот так вот:

 

0. Прочитать значение по адресу 0x1234567 (статический адрес).

1. Прибавить к полученному 0x10 (первое смещение).

2. Прочитать значение по полученному адресу.

3. Прибавить к полученному 0x20 (второе смещение).

4. Прочитать значение по полученному адресу.

 

После 4-го шага в данном примере в переменной для чтения как раз и будет адрес, который дальше можно будет использовать для записи в память.

 

PS: У меня в блоге даже нашлась [запись] на эту тему.

Спасибо за статью =) , вроде все сделал без ошибок,но в статье ты указываешь тип float, а у меня 4byte , мне убрать тут сточку где ты конвертируешь во float или записать другой код? И смещения у меня не 2 знака как например: 0x18. 0xc. 0x14( К примеру!) а: 0x358, 0x14, 0x318 и т.д , что мне делать?

Ссылка на комментарий
Поделиться на другие сайты

У меня в том примере на выходе был тип float, так что я в него и конвертировал. Ты конвертируй в нужный. А по поводу типов данных для адреса и смещений - лучше там использовать uint, то есть беззнаковое целое. Мой косяк, но небольшой, так что править не буду.
Ссылка на комментарий
Поделиться на другие сайты

У меня в том примере на выходе был тип float, так что я в него и конвертировал. Ты конвертируй в нужный. А по поводу типов данных для адреса и смещений - лучше там использовать uint, то есть беззнаковое целое. Мой косяк, но небольшой, так что править не буду.

Пробовал,экспериминтировал,но все равно не получается... :-[ , Объяснишь новичку  где подменить на uint , и как конвертировать в 4byte

 
Ссылка на комментарий
Поделиться на другие сайты

Тогда пиши сюда, например, что ты меняешь и что при этом не работает, будем вместе разбираться. Я вряд ли ошибусь точно так же и напишу то же самое, что и ты, если сяду писать сам. Если не работает какой-то код - то этот код хочется хотя бы прочитать.
Ссылка на комментарий
Поделиться на другие сайты

Тогда пиши сюда, например, что ты меняешь и что при этом не работает, будем вместе разбираться. Я вряд ли ошибусь точно так же и напишу то же самое, что и ты, если сяду писать сам. Если не работает какой-то код - то этот код хочется хотя бы прочитать.

Может скинуть исходник?Хотя не думаю что у тебя есть свободное на это время =) .Сейчас попробую еще раз.Код скину сюда.

Ссылка на комментарий
Поделиться на другие сайты

using System;


using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace AssaulCube
{
class Ammo
{
//ReadProcessMemory
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(
IntPtr hProcess,
IntPtr lpBaseAddress,
[Out] byte[] lpBuffer,
int dwSize,
out int lpNumberOfBytesRead
);
//OpenProcess // Flag = All = 0x001F0FFF
[DllImport("kernel32.dll")]
public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

// CloseHandle
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CloseHandle(IntPtr hObject);
[structLayout(LayoutKind.Sequential)]
public struct MEMORY_BASIC_INFORMATION
{
public IntPtr BaseAddress;
public IntPtr AllocationBase;
public uint AllocationProtect;
public IntPtr RegionSize;
public uint State;
public uint Protect;
public uint Type;
}
// VirtualQueryEx
[DllImport("kernel32.dll")]
static extern int VirtualQueryEx(IntPtr hProcess, IntPtr lpAddress, out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
//WriteProcessMemory
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out UIntPtr lpNumberOfBytesWritten);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, IntPtr lpBuffer, uint nSize, UIntPtr lpNumberOfBytesWritten);
public int ProcessID;
private IntPtr handl;
public void GetProcess()
{
foreach (Process id in Process.GetProcessesByName("ac_client"))
{
ProcessID = id.Id;
}
WriteBytes();
}

public void WriteBytes()
{
var address = 0x027BA448; //Базовый адрес
var offsets = new byte[] { 0x70 }; //Массив со смещениями
var myFloat = ReadBytes(address, offsets); //Читаем!
var bytessize = 4;
byte[] bytes = { 0x14, 0x00, 0x00, 0x00 };
var w = new UIntPtr();
var handl = OpenProcess(0x001F0FFF, false, ProcessID);
WriteProcessMemory(handl, (IntPtr)address, bytes, (uint)bytessize, out w);
CloseHandle(handl);
}
public int ReadBytes(int baseAddress, byte[] offsets)
{
if (pID != 0 && baseAddress != 0 && offsets.Length != 0) //Проверяем, что всё на месте
{
byte[] buffer = new byte[4]; //Буфер для чтения
int bytesread; //Заглушка
var handle = OpenProcess(0x001F0FFF, false, pID); //Получаем хэндл
ReadProcessMemory(handle, (IntPtr)baseAddress, buffer, 4, out bytesread); //Читаем базовый адрес
for (var i = 0; i < offsets.Length; i++) //Бежим в цикле, пока не кончатся смещения
{
baseAddress = BitConverter.ToInt32(buffer, 0); //Конвертируем результат в циферки
baseAddress += offsets; //Прибавляем смещение
ReadProcessMemory(handle, (IntPtr)baseAddress, buffer, 4, out bytesread); //Читаем
}
//Как только смещения в массиве закончились
CloseHandle(handle); //Закрываем хэндл
//Конвертируем результат во float
return -1;//Возвращаем результат
}
return -1; //Иначе - ошибка
}

 

Ну вот, не пойму  как конвертировать в 4byte, и где вставить uint ...

Изменено пользователем krassdan
Спойлер должен быть с именем. Иначе не работает.
Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.