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

keng

Ветераны
  • Постов

    1 635
  • Зарегистрирован

  • Посещение

  • Победитель дней

    55

Весь контент keng

  1. Мои запоздалые поздравления! Желаю уметь отлаживать не только игровые баги, но и собственные.
  2. Если коротко, то при перехваченном устройстве d3d поиск vm перестает быть необходимым - устройство и так знает свою текущую матрицу, причем их все.
  3. Привет! Хорошая работа. Я знал, что Pure Basic кого-нибудь зацепит!
  4. Привет! Посмотри мои видеоуроки, там показывается "общий" способ нахождения vm.
  5. Привет! Если ты еще ничего не пытался сделать сам, то хотя бы на пальцах попробуй представить и напиши, как должен аим работать. Пока этого сделать не сможешь - о написании не может быть и речи.
  6. Привет! Я где-то на форуме писал, как вручную делаются сигнатуры. Поищи. А плагин для Olly есть на моем сайте (ссылка в подписи).
  7. Привет! Что ты брутишь и как это относится ко взлому игр?
  8. Давай лучше не будем мучаться и проверим на конкретной игре.
  9. Кстати говоря, я слабо себе представляю, как оно будет работать без флага EXECUTE. Мы же исполняемый код ищем, а не данные. И да, я беру имя модуля, нужное для конкретного случая. Все модули сканировать смысла нет- слишком долго будет, а в том же CE всегда можно посмотреть, в каком модуле нужный код лежит - его и следует сканировать.
  10. Нет, погоди-ка. Что значит "в буфере нет сигнатуры"? Вот пример: 0x0000001: A+B 0x0000002: C+E 0x0000003: F+Z Представим, что буквы - это опкоды ассемблерных инструкций, а 16-ричные цифры - адреса памяти, по которым находится этот псевдокод. Пишем такую сигнатуру: "ABCEFZ" Что делает сканер? Он берет адрес исполняемого модуля, его размер в байтах, а затем бежит по этому массиву байт и ищет в нем первое вхождение сигнатуры, то есть совпадения с ней. И возвращает адрес, по которому это совпадение нашел, то есть адрес модуля + смещение. Типа вот так: 0x0000011: A+B 0x0000022: C+E 0x0000033: F+Z В первом случае сканер вернет адрес 0x0000001, а во втором - 0x0000011. Если не найдет ничего - то и вернет 0 или -1. Что дальше с этим адресом делать? Например, инъекцию кода, или просто записать на его место нужное количество команд NOP. В свете вышенаписанного, что означает "в буфере нет сигнатуры"?
  11. Как я уже писал выше, способов перевода из массива байт в текстовую строку существует довольно много. Подробнее можно почитать об этом, например, [тут]. Я все еще не совсем понимаю, как это может помочь в отладке работы сканера сигнатур, если всю необходимую информацию можно посмотреть в отладчике.
  12. Гм, шапка темы, 2-й спойлер, 16-я строка: Writer.Write(Data); То, что ты сохранишь N байт на диск вряд ли даст что-то полезное. Я еще раз повторю, что сканер сигнатур возвращает адрес памяти, по которому было найдено первое вхождение сигнатуры, или же код ошибки на выбор разработчика. Адрес можно посмотреть в твоей программе, а что по адресу находится - в отладчике. Если же что-то работает не так, что, прежде всего, надо попробовать другую сигнатуру.
  13. Если ты прекрасно понимаешь разницу, то тогда почему ты пытаешься скормить массив байт методу, который ждет string? Сканер сигнатур возвращает адрес памяти, причем первый найденный. Если он тебе возвращает что-то не то, а код ты подсмотрел у меня, то проблема не в моем коде, а в сигнатуре - попробуй сделать другую в этой же игре.
  14. Xipho, тогда я наивно полагаю, что игра написана на C++ и не имеет никакой защиты, т.к. автор не указал обратного.
  15. Привет! Нельзя просто так взять и записать массив байт туда, куда нужно записывать тип string. Нужно сначала смотреть в документацию. Можно сделать, например, вот так: using System;using System.IO; namespace fileio_bytearray_test{ class Program { static void Main(string[] args) { var data = new byte[] { 11, 22, 33 }; try { using (var bw = new BinaryWriter(File.OpenWrite(@"test.txt"))) { bw.Write(BitConverter.ToString(data)); bw.Flush(); } } catch (Exception e) { Console.Out.WriteLine(e.InnerException.ToString()); } } }}
  16. Привет! Исходный код игры находится в скомпилированном виде в бинарном файле. Чтобы игра заработала, ОС должна бинарный файл загрузить в оперативную память. Единственное исключение - это самомодифицирующийся код, но вряд ли есть игры, генерирующие исполняемый код на лету. Исходя из этого, я не совсем понимаю, что ты хочешь сделать. Адрес участка кода, для которого сделана маска (сигнатура) можно выяснить сразу же после запуска игры - то есть после того как нужный исполняемый модуль загрузится в оперативную память. Если у тебя это происходит не так, то ты явно что-то делаешь не совсем правильно. Поэтому показывай, как ты делаешь.
  17. Привет!Игры чаще всего используют DirectInput - почитай, что это такое и как с этим работать. Для перехвата нужных функций понадобится понимание того, как пишутся хуки.
  18. Так. Давай я скопирую в следующем посте твой класс и будем с ним постепенно разбираться, так как там почти тысяча строк кода. Для начала я приведу в порядок форматирование, потому что в текущем виде читать его невозможно. Исходный код класса: using System;using System.Diagnostics;using System.Runtime.CompilerServices;using System.Runtime.InteropServices;using System.Text;using System.Windows.Forms; public class VAMemory{private IntPtr baseAddress;public static bool debugMode;private Process[] mainProcess;private IntPtr processHandle;private ProcessModule processModule; public VAMemory(){} public VAMemory(string pProcessName){this.processName = pProcessName;} public bool CheckProcess(){if (this.processName != null){this.mainProcess = Process.GetProcessesByName(this.processName);if (this.mainProcess.Length == 0){this.ErrorProcessNotFound(this.processName);return false;}this.processHandle = OpenProcess(0x1f0fff, false, this.mainProcess[0].Id);if (this.processHandle == IntPtr.Zero){this.ErrorProcessNotFound(this.processName);return false;}return true;}MessageBox.Show("Programmer, define process name first!");return false;} [DllImport("kernel32.dll")]private static extern bool CloseHandle(IntPtr hObject);private void ErrorProcessNotFound(string pProcessName){MessageBox.Show(this.processName + " is not running or has not been found. Please check and try again", "Process Not Found", MessageBoxButtons.OK, MessageBoxIcon.Hand);} [DllImport("kernel32.dll")]private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, int dwProcessId);public bool ReadBoolean(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToBoolean(this.ReadByteArray(pOffset, 1), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadByte" + exception.ToString());}return false;}} public byte ReadByte(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.ReadByteArray(pOffset, 1)[0];}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadByte" + exception.ToString());}return 0;}} public byte[] ReadByteArray(IntPtr pOffset, uint pSize){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{uint num;VirtualProtectEx(this.processHandle, pOffset, (UIntPtr) pSize, 4, out num);byte[] lpBuffer = new byte[pSize];ReadProcessMemory(this.processHandle, pOffset, lpBuffer, pSize, 0);VirtualProtectEx(this.processHandle, pOffset, (UIntPtr) pSize, num, out num);return lpBuffer;}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadByteArray" + exception.ToString());}return new byte[1];}} public char ReadChar(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToChar(this.ReadByteArray(pOffset, 1), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadChar" + exception.ToString());}return ' ';}} public double ReadDouble(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToDouble(this.ReadByteArray(pOffset, 8), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadDouble" + exception.ToString());}return 0.0;}} public float ReadFloat(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToSingle(this.ReadByteArray(pOffset, 4), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadFloat" + exception.ToString());}return 0f;}} public short ReadInt16(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToInt16(this.ReadByteArray(pOffset, 2), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadInt16" + exception.ToString());}return 0;}} public int ReadInt32(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToInt32(this.ReadByteArray(pOffset, 4), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadInt32" + exception.ToString());}return 0;}} public long ReadInt64(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToInt64(this.ReadByteArray(pOffset, 8), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadInt64" + exception.ToString());}return 0L;}} public int ReadInteger(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToInt32(this.ReadByteArray(pOffset, 4), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadInteger" + exception.ToString());}return 0;}} public long ReadLong(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToInt64(this.ReadByteArray(pOffset, 8), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadLong" + exception.ToString());}return 0L;}} [DllImport("kernel32.dll", SetLastError=true)]private static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint dwSize, uint lpNumberOfBytesRead);public short ReadShort(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToInt16(this.ReadByteArray(pOffset, 2), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadInt16" + exception.ToString());}return 0;}} public string ReadStringASCII(IntPtr pOffset, uint pSize){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return Encoding.ASCII.GetString(this.ReadByteArray(pOffset, pSize), 0, (int) pSize);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadStringASCII" + exception.ToString());}return "";}} public string ReadStringUnicode(IntPtr pOffset, uint pSize){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return Encoding.Unicode.GetString(this.ReadByteArray(pOffset, pSize), 0, (int) pSize);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadStringUnicode" + exception.ToString());}return "";}} public ushort ReadUInt16(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToUInt16(this.ReadByteArray(pOffset, 2), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadUInt16" + exception.ToString());}return 0;}} public uint ReadUInt32(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToUInt32(this.ReadByteArray(pOffset, 4), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadUInt32" + exception.ToString());}return 0;}} public ulong ReadUInt64(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToUInt64(this.ReadByteArray(pOffset, 8), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadUInt64" + exception.ToString());}return 0L;}} public uint ReadUInteger(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToUInt32(this.ReadByteArray(pOffset, 4), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadUInteger" + exception.ToString());}return 0;}} public long ReadULong(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return (long) BitConverter.ToUInt64(this.ReadByteArray(pOffset, 8), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadULong" + exception.ToString());}return 0L;}} public ushort ReadUShort(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToUInt16(this.ReadByteArray(pOffset, 2), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadUShort" + exception.ToString());}return 0;}} [DllImport("kernel32.dll", SetLastError=true, ExactSpelling=true)]private static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]private static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);public bool WriteBoolean(IntPtr pOffset, bool pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteBoolean" + exception.ToString());}return false;}} public bool WriteByte(IntPtr pOffset, byte pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes((short) pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteByte" + exception.ToString());}return false;}} public bool WriteByteArray(IntPtr pOffset, byte[] pBytes){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{uint num;VirtualProtectEx(this.processHandle, pOffset, (UIntPtr) pBytes.Length, 4, out num);bool flag = WriteProcessMemory(this.processHandle, pOffset, pBytes, (uint) pBytes.Length, 0);VirtualProtectEx(this.processHandle, pOffset, (UIntPtr) pBytes.Length, num, out num);return flag;}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteByteArray" + exception.ToString());}return false;}} public bool WriteChar(IntPtr pOffset, char pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteChar" + exception.ToString());}return false;}} public bool WriteDouble(IntPtr pOffset, double pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteDouble" + exception.ToString());}return false;}} public bool WriteFloat(IntPtr pOffset, float pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteFloat" + exception.ToString());}return false;}} public bool WriteInt16(IntPtr pOffset, short pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteInt16" + exception.ToString());}return false;}} public bool WriteInt32(IntPtr pOffset, int pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteInt32" + exception.ToString());}return false;}} public bool WriteInt64(IntPtr pOffset, long pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteInt64" + exception.ToString());}return false;}} public bool WriteInteger(IntPtr pOffset, int pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteInt" + exception.ToString());}return false;}} public bool WriteLong(IntPtr pOffset, long pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteLong" + exception.ToString());}return false;}} [DllImport("kernel32.dll")]private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, uint lpNumberOfBytesWritten);public bool WriteShort(IntPtr pOffset, short pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteShort" + exception.ToString());}return false;}} public bool WriteStringASCII(IntPtr pOffset, string pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, Encoding.ASCII.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteStringASCII" + exception.ToString());}return false;}} public bool WriteStringUnicode(IntPtr pOffset, string pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, Encoding.Unicode.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteStringUnicode" + exception.ToString());}return false;}} public bool WriteUInt16(IntPtr pOffset, ushort pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteUInt16" + exception.ToString());}return false;}} public bool WriteUInt32(IntPtr pOffset, uint pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteUInt32" + exception.ToString());}return false;}} public bool WriteUInt64(IntPtr pOffset, ulong pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteUInt64" + exception.ToString());}return false;}} public bool WriteUInteger(IntPtr pOffset, uint pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteUInt" + exception.ToString());}return false;}} public bool WriteULong(IntPtr pOffset, ulong pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteULong" + exception.ToString());}return false;}} public bool WriteUShort(IntPtr pOffset, ushort pData){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.WriteByteArray(pOffset, BitConverter.GetBytes(pData));}catch (Exception exception){if (debugMode){Console.WriteLine("Error: WriteShort" + exception.ToString());}return false;}} public long getBaseAddress{get{this.baseAddress = IntPtr.Zero;this.processModule = this.mainProcess[0].MainModule;this.baseAddress = this.processModule.BaseAddress;return (long) this.baseAddress;}} public string processName { get; set; } [Flags]private enum ProcessAccessFlags : uint{All = 0x1f0fff,CreateThread = 2,DupHandle = 0x40,QueryInformation = 0x400,SetInformation = 0x200,Synchronize = 0x100000,Terminate = 1,VMOperation = 8,VMRead = 0x10,VMWrite = 0x20} private enum VirtualMemoryProtection : uint{PAGE_EXECUTE = 0x10,PAGE_EXECUTE_READ = 0x20,PAGE_EXECUTE_READWRITE = 0x40,PAGE_EXECUTE_WRITECOPY = 0x80,PAGE_GUARD = 0x100,PAGE_NOACCESS = 1,PAGE_NOCACHE = 0x200,PAGE_READONLY = 2,PAGE_READWRITE = 4,PAGE_WRITECOPY = 8,PROCESS_ALL_ACCESS = 0x1f0fff}} using System;using System.Diagnostics;using System.Runtime.CompilerServices;using System.Runtime.InteropServices;using System.Text;using System.Windows.Forms;public class VAMemory{}private IntPtr baseAddress;public static bool debugMode;private Process[] mainProcess;private IntPtr processHandle;private ProcessModule processModule;public VAMemory(){}public VAMemory(string pProcessName){this.processName = pProcessName;} public bool CheckProcess(){if (this.processName != null){this.mainProcess = Process.GetProcessesByName(this.processName);if (this.mainProcess.Length == 0){this.ErrorProcessNotFound(this.processName);return false;}this.processHandle = OpenProcess(0x1f0fff, false, this.mainProcess[0].Id);if (this.processHandle == IntPtr.Zero){this.ErrorProcessNotFound(this.processName);return false;}return true;}MessageBox.Show("Programmer, define process name first!");return false;}[DllImport("kernel32.dll")]private static extern bool CloseHandle(IntPtr hObject);private void ErrorProcessNotFound(string pProcessName){MessageBox.Show(this.processName +" is not running or has not been found. Please check and try again","Process Not Found", MessageBoxButtons.OK, MessageBoxIcon.Hand);}[DllImport("kernel32.dll")]private static extern IntPtr OpenProcess(uint dwDesiredAccess,bool bInheritHandle, int dwProcessId); public bool ReadBoolean(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return BitConverter.ToBoolean(this.ReadByteArray(pOffset, 1), 0);}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadByte" + exception.ToString());}return false;}} public byte ReadByte(IntPtr pOffset){if (this.processHandle == IntPtr.Zero){this.CheckProcess();}try{return this.ReadByteArray(pOffset, 1)[0];}catch (Exception exception){if (debugMode){Console.WriteLine("Error: ReadByte" + exception.ToString());}return 0;}}
  19. Товарищ, подожди. Я же тебе ссылку на статью дал. Тебе всего-то ее прочитать, взять из нее готовый метод и вставить в класс, исходник которого ты привел в шапке. Что в этом сложного?
  20. Привет! Так ведь game.exe - это точно такой же модуль. У него тоже есть адрес.
  21. Привет! Попробуй сначала написать сам, если не сработает - покажи, как пытался, а мы попробуем помочь. Если снабдить тебя готовым решением - ты так и не узнаешь, как оно работает.
  22. keng

    Grand Theft Auto V

    Оптимизирован движок как следует, это да. С выкрученной на максимум графикой и под DX11-API у меня выходит примерно 150-160 FPS в 1080p. Правда, периодически игра падает, но это сырость версии + криво снятая защита.
  23. Гм. У меня есть статья на тему указателей, вот [ссылка], там все довольно подробно расписано. Думаю, этого хватит для начала.
  24. Привет! Воспользуйся поиском по форуму - есть несколько, по сути, однотипных тем про работу с указателями в различных языках программирования. PS: Думаю, пора создавать ЧАВО с подобными темами.
  25. keng

    Grand Theft Auto V

    Думаю, что он скучный, если не с кем больше играть. Вот с парой друзей должно быть весело.
×
×
  • Создать...

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

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