krassdan Опубликовано 18 апреля, 2015 Поделиться Опубликовано 18 апреля, 2015 Приветствую всех. С урока писал трейнер на игру.Все получилось. Но вот проблема:У меня имеется 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); } } } Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 18 апреля, 2015 Поделиться Опубликовано 18 апреля, 2015 Привет! У тебя для записи в память используется WinAPI-функция WriteProcessMemory, которая принимает в качестве аргументов адрес, размер и значение для записи. Соответственно, переменную adress, bytessize и массив байт bytes. Адрес при этом задан статический. Указатели по своей сути - это статический адрес + одно или несколько смещений от него, которые тоже хранят адрес, а самый последний - нужное значение. Для того, чтобы получить адрес, на который указывает некоторый указатель, нужно знать статический адрес этого указателя и смещения, а потом просто прочитать его, используя арифметику. Для чтения понадобится функция ReadProcessMemory, читать нужно будет, скорее всего, 4 байта. Тут я просто думаю, что игра 32-битная, а в 32-битном адресном пространстве адреса как раз по 4 байта каждый. Допустим, есть у тебя какой-то такой указатель: [[[0x1234567] + 0x10] + 0x20] Что тебе нужно сделать? А вот так вот: 0. Прочитать значение по адресу 0x1234567 (статический адрес).1. Прибавить к полученному 0x10 (первое смещение).2. Прочитать значение по полученному адресу.3. Прибавить к полученному 0x20 (второе смещение).4. Прочитать значение по полученному адресу. После 4-го шага в данном примере в переменной для чтения как раз и будет адрес, который дальше можно будет использовать для записи в память. PS: У меня в блоге даже нашлась [запись] на эту тему. 2 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 18 апреля, 2015 Поделиться Опубликовано 18 апреля, 2015 Привет! keng, как всегда лаконично и доходчиво. Почитал пару статей в блоге за 2015 год - в том же духе, т.е., как всегда, здорово.Ты случайно не из учительской семьи - у тебя учительский дар?(Я разделяю преподавателей и учителей: преподаватели - преподают предмет, учителя - учат ему; преподавателей я уважаю, учителей - люблю.) 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 18 апреля, 2015 Поделиться Опубликовано 18 апреля, 2015 Garik66, семья химиков и инженеров, ранее - всяких творческих личностей, музыкантов\художников. Дед преподавал в военноморском, бабушка - химию в одном из институтов. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Garik66 Опубликовано 18 апреля, 2015 Поделиться Опубликовано 18 апреля, 2015 Ну тогда получается, я прав.Чувствуется воспитание. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
krassdan Опубликовано 20 апреля, 2015 Автор Поделиться Опубликовано 20 апреля, 2015 Привет! У тебя для записи в память используется 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 и т.д , что мне делать? Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 20 апреля, 2015 Поделиться Опубликовано 20 апреля, 2015 У меня в том примере на выходе был тип float, так что я в него и конвертировал. Ты конвертируй в нужный. А по поводу типов данных для адреса и смещений - лучше там использовать uint, то есть беззнаковое целое. Мой косяк, но небольшой, так что править не буду. Ссылка на комментарий Поделиться на другие сайты Поделиться
krassdan Опубликовано 20 апреля, 2015 Автор Поделиться Опубликовано 20 апреля, 2015 У меня в том примере на выходе был тип float, так что я в него и конвертировал. Ты конвертируй в нужный. А по поводу типов данных для адреса и смещений - лучше там использовать uint, то есть беззнаковое целое. Мой косяк, но небольшой, так что править не буду.Пробовал,экспериминтировал,но все равно не получается... , Объяснишь новичку где подменить на uint , и как конвертировать в 4byte Ссылка на комментарий Поделиться на другие сайты Поделиться
keng Опубликовано 20 апреля, 2015 Поделиться Опубликовано 20 апреля, 2015 Тогда пиши сюда, например, что ты меняешь и что при этом не работает, будем вместе разбираться. Я вряд ли ошибусь точно так же и напишу то же самое, что и ты, если сяду писать сам. Если не работает какой-то код - то этот код хочется хотя бы прочитать. Ссылка на комментарий Поделиться на другие сайты Поделиться
krassdan Опубликовано 20 апреля, 2015 Автор Поделиться Опубликовано 20 апреля, 2015 Тогда пиши сюда, например, что ты меняешь и что при этом не работает, будем вместе разбираться. Я вряд ли ошибусь точно так же и напишу то же самое, что и ты, если сяду писать сам. Если не работает какой-то код - то этот код хочется хотя бы прочитать.Может скинуть исходник?Хотя не думаю что у тебя есть свободное на это время =) .Сейчас попробую еще раз.Код скину сюда. Ссылка на комментарий Поделиться на другие сайты Поделиться
krassdan Опубликовано 21 апреля, 2015 Автор Поделиться Опубликовано 21 апреля, 2015 (изменено) 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); //Закрываем хэндл//Конвертируем результат во floatreturn -1;//Возвращаем результат}return -1; //Иначе - ошибка} Ну вот, не пойму как конвертировать в 4byte, и где вставить uint ... Изменено 21 апреля, 2015 пользователем krassdan Спойлер должен быть с именем. Иначе не работает. Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения